Repository navigation
chore(infra): Docker, CI/CD, and server-start optimization (Phase 9.7) - #18
Merged
Merged
Conversation
Slim backend image by 46% (2.13GB -> 1.14GB), run it as a non-root user, and make its worker count configurable via WEB_CONCURRENCY. Add GHA-backed Docker layer caching, concurrency groups, and path-filter gating to CI workflows that lacked them, and fix compose.deploy.yml's missing restart:always on redis. Every researched area (Docker build, Compose, CI caching, server startup, test execution) gets a documented verdict in docs/development/ci-cd-and-docker.md, including the ones left unchanged because they already matched current best practice. Claude-Session: https://claude.ai/code/session_01WACAxnAd7w5uk12Y58EHqz
- Stop chowning the whole /app tree at the end of the Dockerfile: it
forced overlay2 to copy up every earlier layer, giving back ~430MB of
the slim-base size win (1.14GB -> 707MB once removed). Chown each
layer's own output at creation time instead (COPY --chown, chown
inside the same RUN as uv sync).
- Quote the ${WEB_CONCURRENCY:-4} expansion in the Dockerfile CMD.
- Add docker/setup-buildx-action (driver: docker-container) before the
docker compose build steps that rely on cache_from/cache_to: type=gha
-- the default docker driver silently ignores that cache backend.
- Add pyproject.toml/uv.lock/bun.lock to the changes-job path filters in
test-backend.yml, test-docker-compose.yml, and playwright.yml, so a
dependency-only bump can no longer skip its own test job.
Claude-Session: https://claude.ai/code/session_01WACAxnAd7w5uk12Y58EHqz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Infrastructure-only pass per the Phase 9.7 spec: Docker image build, Docker Compose, CI/CD workflows, server startup, and test execution. No application logic, API/websocket behavior, or test content changed.
python:3.14->python:3.14-slim(measured 2.13GB -> 1.14GB, -46%), non-rootappuser, configurableWEB_CONCURRENCYworker count (shell-expansion default, not a persistentENV, so it can't leak into the devfastapi devcommand). Fixed the healthcheck regression the slim base caused (nocurl->python3/urllib.request). Hardened.dockerignore(root,backend/).compose.deploy.yml'sredisservice was missingrestart: always-- added. Named volumes,condition: service_healthyhealthchecks, and Compose Watch were already current best practice, confirmed and left alone.concurrencygroups to 4 workflows that lacked them,dorny/paths-filtergating totest-backend.yml/test-docker-compose.yml(mirroringplaywright.yml's existing pattern), and GHA-backed Docker layer caching (cache_from/cache_to: type=gha+COMPOSE_BAKE=1) targeting Playwright's 4x-redundant per-shard Docker build. Bumped stalebun-versionpins to match local dev. Confirmed via real CI-log inspection that uv's dependency cache was already working correctly -- left alone.pytest-xdist(real cross-worker collision risk given the session-scoped shared-DB fixture, not applied) andprestart.sh's wait-for-DB logic (already covered by Compose/CI's own health-gated orchestration, not applied).Full reasoning, including every area that was already fine and deliberately left alone, is in
docs/development/ci-cd-and-docker.md.Test plan
ruff check/ruff format --check/mypy app/ty check appcleanprek run --all-filesclean (incl.zizmoron every workflow edit)docker compose up -d --wait backend adminerreports healthyCOMPOSE_BAKE=1 docker compose build backend/playwrightsucceed locally with the newcache_from/cache_tofieldscompose.yml+compose.deploy.ymlconfig showsredis: restart: alwayshttps://claude.ai/code/session_01WACAxnAd7w5uk12Y58EHqz