ci / test (push) Successful in 29s
- deploy/compose/nex-speech: whisper-server v1.9.4 (sm_52/sm_61, Port 8178, -l de -bs 5 --convert, tmpfs, Aufwärmen mit 1 s Stille) und OpenAI-kompatibler Piper-Wrapper (Port 8179, mp3/opus/aac/flac/pcm gestreamt, wav, PCM 24 kHz mit Rate-Header) - Host-Netz, damit ufw greift; keine Texte in Logs, kein Access-Log - Rolle nex-speech + Playbook (nur gpu-pve52): ufw, Modelle mit sha256, Compose bauen/starten - compose-check um nex-speech erweitert, community.docker in requirements.yml Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
103 lines
2.9 KiB
YAML
103 lines
2.9 KiB
YAML
# --- Firewall in der VM: SSH aus dem LAN, Sprachdienste nur von appsrv08, sonst nichts ---
|
||
# Reihenfolge wichtig: SSH-Regel vor dem Einschalten, sonst sperrt sich Ansible aus.
|
||
- name: ufw installieren
|
||
ansible.builtin.apt:
|
||
name: ufw
|
||
state: present
|
||
|
||
- name: ufw – SSH aus dem LAN erlauben
|
||
community.general.ufw:
|
||
rule: allow
|
||
from_ip: "{{ nex_speech_ssh_from }}"
|
||
port: "22"
|
||
proto: tcp
|
||
comment: ssh-lan
|
||
|
||
- name: ufw – Sprachdienste nur von appsrv08
|
||
community.general.ufw:
|
||
rule: allow
|
||
from_ip: "{{ nex_speech_allow_from }}"
|
||
port: "{{ item.port | string }}"
|
||
proto: tcp
|
||
comment: "{{ item.name }}"
|
||
loop:
|
||
- {name: nex-stt, port: "{{ nex_speech_stt_port }}"}
|
||
- {name: nex-tts, port: "{{ nex_speech_tts_port }}"}
|
||
|
||
- name: ufw – eingehend sonst ablehnen, ausgehend erlauben
|
||
community.general.ufw:
|
||
direction: "{{ item.direction }}"
|
||
default: "{{ item.policy }}"
|
||
loop:
|
||
- {direction: incoming, policy: deny}
|
||
- {direction: outgoing, policy: allow}
|
||
|
||
- name: ufw einschalten
|
||
community.general.ufw:
|
||
state: enabled
|
||
|
||
# Compose baut nur mit buildx (BuildKit); der Altbau-Builder ist in Docker 29 veraltet
|
||
- name: docker-buildx installieren
|
||
ansible.builtin.apt:
|
||
name: docker-buildx
|
||
state: present
|
||
|
||
# --- Modelle ---
|
||
- name: Modellverzeichnisse
|
||
ansible.builtin.file:
|
||
path: "{{ nex_speech_models_dir }}/{{ item }}"
|
||
state: directory
|
||
mode: "0755"
|
||
loop: [whisper, piper]
|
||
|
||
- name: Modelle laden (Prüfsumme gegen Hugging Face)
|
||
ansible.builtin.get_url:
|
||
url: "{{ item.url }}"
|
||
dest: "{{ nex_speech_models_dir }}/{{ item.dest }}"
|
||
checksum: "{{ item.checksum }}"
|
||
mode: "0644"
|
||
timeout: 120
|
||
loop: "{{ nex_speech_models }}"
|
||
loop_control:
|
||
label: "{{ item.dest }}"
|
||
|
||
# --- Compose-Projekt ---
|
||
- name: Compose-Dateien kopieren
|
||
ansible.builtin.copy:
|
||
src: "{{ playbook_dir }}/../../../../deploy/compose/nex-speech/"
|
||
dest: "{{ nex_speech_dir }}/"
|
||
mode: preserve
|
||
directory_mode: "0755"
|
||
register: nex_speech_files
|
||
|
||
- name: .env schreiben (keine Geheimnisse)
|
||
ansible.builtin.copy:
|
||
dest: "{{ nex_speech_dir }}/.env"
|
||
mode: "0644"
|
||
content: |
|
||
# Verwaltet von Ansible (Rolle nex-speech)
|
||
{% for k, v in nex_speech_env.items() %}
|
||
{{ k }}={{ v }}
|
||
{% endfor %}
|
||
register: nex_speech_envfile
|
||
|
||
# Bauen dauert beim ersten Mal lange (whisper.cpp mit CUDA auf 4 Kernen, ca. 20–40 min)
|
||
- name: Images bauen und Dienste starten
|
||
community.docker.docker_compose_v2:
|
||
project_src: "{{ nex_speech_dir }}"
|
||
build: "{{ 'always' if (nex_speech_files.changed or nex_speech_envfile.changed) else 'policy' }}"
|
||
state: present
|
||
wait: false
|
||
async: 3600
|
||
poll: 30
|
||
|
||
- name: Warten, bis beide Dienste gesund sind
|
||
ansible.builtin.uri:
|
||
url: "http://127.0.0.1:{{ item }}/health"
|
||
status_code: 200
|
||
register: nex_speech_health
|
||
until: nex_speech_health.status == 200
|
||
retries: 60
|
||
delay: 10
|
||
loop: ["{{ nex_speech_stt_port }}", "{{ nex_speech_tts_port }}"]
|