Deploying applications
Ship a containerized web application behind Nginx and TLS with explicit release and rollback procedures.
This guide uses Docker Compose for the application stack and host-managed Nginx for the public edge. The same boundaries apply if you run the app directly with systemd.
Install Docker from its official repository
Use the current instructions for your distribution and verify the repository fingerprint before installation. Afterward:
Log out and back in for group membership to refresh. Membership in the docker group is effectively root-equivalent; grant it only to trusted operators.
Build a small, non-root image
Pin a known runtime major or immutable digest, exclude secrets with .dockerignore, and scan the final image in CI.
Define the runtime
Avoid latest. Deploy an immutable commit SHA or release version so the running artifact and rollback target are unambiguous.
Put Nginx in front
Enable TLS
Point DNS at the server first, allow ports 80 and 443, then use your organization’s certificate automation. With Certbot on Ubuntu:
Release and rollback
Record the intended version
Link the change, image digest, migration plan, owner, verification, and rollback target.
Pull before changing runtime
docker compose pull makes registry failures happen before the current containers are replaced.
Treat database migrations separately
Make database changes in stages: add the new structure, move the data, and remove the old structure only after every running application version has stopped using it. Know whether the migration can be reversed before deploying it.
Start and verify
Check container health, local health endpoint, public HTTPS, key user flow, and logs.
Roll back deliberately
Set APP_VERSION to the last known-good immutable version and run docker compose up -d. Verify with the same checklist.
A single container will briefly stop
A single container must release its port before the replacement can use it. To avoid that interruption, run at least two healthy instances behind a load balancer, add readiness checks, and keep database changes compatible with both application versions.