Docker Compose can describe a small agent application’s services, networks, and storage in one reviewable place. It cannot decide which data should persist, which actions a worker may perform, or whether an application is ready for production. Those decisions belong in your deployment plan.
This is an unexecuted reference workflow. We have not built a sample agent image or tested a working stack for this article. The names below describe responsibilities, not downloadable products. Use the actual image, commands, health checks, and storage paths documented by your chosen application. Never substitute an invented image name into a production deployment.
Draw the smallest useful architecture
Begin with four responsibilities, combining them only when the application genuinely supports that arrangement:
- Public entry point: handles HTTPS and forwards requests to the application
- Application service: authenticates users, authorizes actions, and creates task records
- Worker: consumes queued work and calls the model API or approved tools
- State services: store task progress, application data, and durable files
An external managed database may replace a database container. A small synchronous application may not need a separate queue. Avoid adding services merely to make the diagram look complete. Every component creates configuration, backup, upgrade, and monitoring work.
Decide which process owns each external action. If both the web service and worker can execute the same job after a timeout, you need a shared ownership mechanism and duplicate detection. Packaging them in separate containers does not coordinate them automatically.
Review the production configuration
Create a clear distinction between development conveniences and production settings. Remove debugging access, interactive development servers, and unnecessary source-code mounts. Record the resolved image version, expected configuration, and resource limits in a release record. Review the combined configuration if you use multiple Compose files; a production override can leave an unexpected development setting in place.
Docker’s production guidance describes production-specific configuration and service recreation during updates. Treat a configuration change as a release requiring review, especially when it affects mounts, network exposure, or secrets.
Make state survive the right failures
List every directory the application writes. Classify it as disposable cache, durable user data, database state, or operational evidence. Map only the durable categories to intentional persistent storage. A local model download, if you later add one, needs a separate capacity decision from application data.
Docker volumes persist independently of an individual container’s writable layer. That makes them useful for state, but does not make them backups. Give each volume an owner, purpose, restore method, and retention rule. Confirm that the application actually writes to the mounted path.
Test recreation with harmless sample data before trusting persistence. Then test recovery into a different volume. The first test proves a routine container replacement can preserve state; the second tests whether you can recover from losing that state.
Publish only the intended entry point
If the reverse proxy is another container, let it reach the application over a shared private network. If the proxy runs on the host, use an appropriately restricted host binding. Do not publish database or queue ports merely because a local development example does so.
Docker’s port-publishing documentation warns that a published port is externally available by default, and documents loopback bindings and networking caveats. Verify reachability over both enabled address families from outside the server. A list of intended ports is not evidence of actual exposure.
Deliver secrets deliberately
Give each service only the credentials it needs. The proxy should not need the model API key; a read-only reporting process should not receive database administration credentials. Review error logging so failed startup does not print a complete configuration containing secrets.
Compose can make secrets available as per-service files, but the application must support reading them. An environment variable ending in “_FILE” is an application convention, not universal behavior. Consult Docker’s secrets guide and the application’s own documentation. Protect the source files and test rotation with the old key revoked.
Update with a way back
Before an update, capture the running release identity, verify a current backup, and read migration notes. Test the new release against an isolated copy with outbound actions disabled. Check login, a harmless task, persistence, and failure behavior.
During rollout, stop accepting new work if the update requires it, let active jobs finish or checkpoint, and replace the necessary services. Observe errors and queue progress before reopening full traffic. Define a concrete rollback trigger, such as failed authentication or repeated task failures, rather than “if things look bad.”
A previous image alone is not a complete rollback plan. Confirm whether it can read the current database schema and whether external actions already performed need reconciliation. Record what passed, what failed, and what remains untested. A running container is the start of verification, not its conclusion.