From 18726ef7c55e4d3209aa922191c1e8eea35b0231 Mon Sep 17 00:00:00 2001 From: Roni bhakta <77425964+ronibhakta1@users.noreply.github.com> Date: Thu, 8 Oct 2026 19:40:00 +0530 Subject: [PATCH 1/3] ci: build docker image on PRs after tests pass --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b77615..01dbc3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,3 +30,25 @@ 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 From 1fe619eabbc3430b6b46fca423a8099225d159c9 Mon Sep 17 00:00:00 2001 From: Roni bhakta <77425964+ronibhakta1@users.noreply.github.com> Date: Thu, 8 Oct 2026 19:49:33 +0530 Subject: [PATCH 2/3] ci: validate nginx config with nginx -t --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01dbc3c..95c3207 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,3 +52,19 @@ jobs: 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 From aa997cd5e3acc6a748ff061f7fad3cabb905cd89 Mon Sep 17 00:00:00 2001 From: Roni bhakta <77425964+ronibhakta1@users.noreply.github.com> Date: Thu, 8 Oct 2026 19:46:53 +0530 Subject: [PATCH 3/3] fix: remove duplicate proxy_read_timeout that crashes nginx on start --- nginx/snippets/proxy-pass.conf | 7 ++----- nginx/templates/20-speech-server.conf.template | 9 ++++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/nginx/snippets/proxy-pass.conf b/nginx/snippets/proxy-pass.conf index 06ffe1a..b84b86a 100644 --- a/nginx/snippets/proxy-pass.conf +++ b/nginx/snippets/proxy-pass.conf @@ -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; diff --git a/nginx/templates/20-speech-server.conf.template b/nginx/templates/20-speech-server.conf.template index 7577de2..d8aa73f 100644 --- a/nginx/templates/20-speech-server.conf.template +++ b/nginx/templates/20-speech-server.conf.template @@ -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; } @@ -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; } }