Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,41 @@ jobs:

- name: Test
run: uv run pytest -m 'not integration and not slow' -v

# Same Dockerfile deploy.yml pushes, built but not pushed — a PR that would
# break the prod image (Dockerfile, uv.lock, missing files) fails here instead.
build:
needs: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- name: Validate compose file
run: touch .env && docker compose config -q # .env is gitignored

- name: Build image
uses: docker/build-push-action@v6
with:
context: .
push: false
cache-from: type=gha
cache-to: type=gha,mode=max

# Renders the template with envsubst (the nginx image does it on start) and
# runs nginx -t, so a bad directive fails here, not as a crash-looping nginx
# on deploy. Throwaway cert + `app` host stand in for the real ones.
- name: Validate nginx config
run: |
d=$(mktemp -d); mkdir -p $d/live/ci.test
openssl req -x509 -newkey rsa:2048 -nodes -days 1 -subj /CN=ci.test \
-keyout $d/live/ci.test/privkey.pem -out $d/live/ci.test/fullchain.pem
docker run --rm --add-host app:127.0.0.1 -e DOMAIN=ci.test \
-v $PWD/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $PWD/nginx/snippets:/etc/nginx/snippets:ro \
-v $PWD/nginx/templates:/etc/nginx/templates:ro \
-v /dev/null:/etc/nginx/conf.d/default.conf:ro \
-v $d:/etc/letsencrypt:ro \
nginx:alpine nginx -t
7 changes: 2 additions & 5 deletions nginx/snippets/proxy-pass.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
set $upstream_app app:8000;
proxy_pass http://$upstream_app;

# No backend synthesis timeout exists today (ffmpeg.py only bounds the
# encode step at 30s; TTS inference itself is unbounded) — pick a ceiling
# safely above realistic worst-case rather than nginx's low defaults cutting
# off legitimate slow requests.
proxy_read_timeout 120s;
# proxy_read_timeout is set per location (nginx rejects a directive repeated in
# one block, so it can't live here and be overridden after the include).
proxy_send_timeout 120s;
proxy_connect_timeout 5s;

Expand Down
9 changes: 6 additions & 3 deletions nginx/templates/20-speech-server.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ server {
include /etc/nginx/snippets/proxy-pass.conf;

# TTS inference is CPU-bound and can be slow (24-layer models, long text,
# emulated arch) — give synthesis more than the shared 120s read timeout so
# a legitimately long generation isn't cut off with a 504. This override must
# come AFTER the include, whose 120s would otherwise win.
# emulated arch) — give synthesis more than the 120s default on other
# routes so a legitimately long generation isn't cut off with a 504.
proxy_read_timeout 300s;
}

Expand All @@ -91,5 +90,9 @@ server {
limit_conn perip 20;

include /etc/nginx/snippets/proxy-pass.conf;

# No backend timeout exists today (TTS inference is unbounded) — pick a
# ceiling safely above realistic worst-case rather than nginx's low default.
proxy_read_timeout 120s;
}
}
Loading