Package and serve the website and API from one image #26

Open
opened 2026-11-01 20:11:43 +00:00 by viacheslavshuka · 0 comments

One deployable image keeps the frontend and API release coordinated. Static delivery needs correct caching, Brotli negotiation, and explicit handling of retained assets.

Scope

Build the Vite assets into the FastAPI application image. Serve through Granian with --loop uvloop behind Dokploy's proxy under one website origin. The background worker uses a separate entrypoint from the same application image and version.

Acceptance criteria

  • A reproducible build uses pinned container inputs and locked dependencies. Runtime serving does not use Vite preview, Node, or Bun as a production server.
  • API routes take priority over frontend fallback. Direct browser navigation reaches the intended application route. Missing asset requests cannot return HTML as JavaScript.
  • Public static requests avoid unnecessary authentication and database work. Authenticated API responses remain private.
  • HTML revalidates. Content-hashed assets receive immutable caching. Brotli negotiation works through the installed proxy/application combination without double compression.
  • Encoding variants have correct headers and validators. Clients without Brotli support receive a usable response.
  • Document the retention bounds for earlier content-hashed assets. Current and retained chunks return the expected JavaScript content. Missing obsolete chunks return an explicit not-found response.
  • Image checks use the production entrypoint and disposable dependencies. They verify readiness, a representative database-backed request, and orderly shutdown.
  • The web service and worker can run separately from the same image and version once the worker exists. Their commands have explicit resource ownership.

Validation

Test the built image through direct routes, missing assets, compression variants, database failure, and process termination. Replace the image and check current, retained, and expired asset responses.

Dependencies

One deployable image keeps the frontend and API release coordinated. Static delivery needs correct caching, Brotli negotiation, and explicit handling of retained assets. ## Scope Build the Vite assets into the FastAPI application image. Serve through Granian with `--loop uvloop` behind Dokploy's proxy under one website origin. The background worker uses a separate entrypoint from the same application image and version. ## Acceptance criteria - A reproducible build uses pinned container inputs and locked dependencies. Runtime serving does not use Vite preview, Node, or Bun as a production server. - API routes take priority over frontend fallback. Direct browser navigation reaches the intended application route. Missing asset requests cannot return HTML as JavaScript. - Public static requests avoid unnecessary authentication and database work. Authenticated API responses remain private. - HTML revalidates. Content-hashed assets receive immutable caching. Brotli negotiation works through the installed proxy/application combination without double compression. - Encoding variants have correct headers and validators. Clients without Brotli support receive a usable response. - Document the retention bounds for earlier content-hashed assets. Current and retained chunks return the expected JavaScript content. Missing obsolete chunks return an explicit not-found response. - Image checks use the production entrypoint and disposable dependencies. They verify readiness, a representative database-backed request, and orderly shutdown. - The web service and worker can run separately from the same image and version once the worker exists. Their commands have explicit resource ownership. ## Validation Test the built image through direct routes, missing assets, compression variants, database failure, and process termination. Replace the image and check current, retained, and expired asset responses. ## Dependencies - [#6: Start the FastAPI runtime with owned database resources](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/6). The image needs the production API entrypoint. - [#7: Create the React application with locked frontend tooling](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/7). The image includes built website assets. - [#16: Run durable PostgreSQL jobs with atomic effects](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/16). The same image must supply the separate worker entrypoint. ## Related work - [#32: Use one application version across builds and release artifacts](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/32) - [#34: Deploy validated main images to development](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/34)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
viacheslavshuka/quorum#26
No description provided.