# syntax=docker/dockerfile:1 # dockerfiles/Dockerfile.hermes-jetson-tts FROM python:3.11-slim-bookworm@sha256:d29f48a31a8b408ed19272ca1e7b10ebae13b240a27e862d3d4217c528e2e0c3 RUN python -m pip install --no-cache-dir piper-tts==1.5.0 # Pin the voice data in the image so synthesis has no runtime dependency on # Hugging Face or mutable model metadata. ADD --checksum=sha256:4cabf7c3a638017137f34a1516522032d4fe3f38228a843cc9b764ddcbcd9e09 --chmod=0444 \ https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/high/en_US-lessac-high.onnx?download=true \ /opt/models/piper/en_US-lessac-high.onnx ADD --checksum=sha256:db42b97d9859f257bc1561b8ed980e7fb2398402050a74ddd6cbec931a92412f --chmod=0444 \ https://huggingface.co/rhasspy/piper-voices/resolve/ea046e8458f6acd997706d6e6066a022b42f6fb1/en/en_US/lessac/high/en_US-lessac-high.onnx.json?download=true \ /opt/models/piper/en_US-lessac-high.onnx.json RUN chmod 0555 /opt/models /opt/models/piper COPY dockerfiles/hermes-jetson-tts-server.py /opt/atlas/hermes-jetson-tts-server.py RUN chmod 0555 /opt/atlas/hermes-jetson-tts-server.py # Load the actual pinned voice during the ARM64 build. This catches package or # model-format drift before the image can reach Flux. RUN python -c "import stat; from pathlib import Path; from piper import PiperVoice; p=Path('/opt/models/piper'); assert stat.S_IMODE(p.stat().st_mode)==0o555; assert stat.S_IMODE((p/'en_US-lessac-high.onnx').stat().st_mode)==0o444; v=PiperVoice.load(p/'en_US-lessac-high.onnx', p/'en_US-lessac-high.onnx.json', use_cuda=False, download_dir=p); assert v.config.sample_rate > 0" ENV HERMES_TTS_HOST=0.0.0.0 \ HERMES_TTS_PORT=9001 \ HERMES_TTS_VOICE=en_US-lessac-high \ HERMES_TTS_CACHE=/opt/models/piper \ OMP_NUM_THREADS=2 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 EXPOSE 9001 ENTRYPOINT ["python", "/opt/atlas/hermes-jetson-tts-server.py"]