Back to Blog
Guide8 min read2026-05-01

Docker Production Checklist: 15 Things Before You Go Live

Run through this 15-point Docker production checklist to catch misconfigurations, security gaps, and reliability issues before they hit users.

Before You Deploy: 15 Production Checks

Moving a containerized application from development to production introduces a class of failures that don't show up locally. This checklist covers the most common issues teams discover the hard way.

1. Pin Your Base Image Version

# Never do this in production
FROM node:latest

# Do this
FROM node:20.13-alpine3.19

latest changes under you. Pin to a specific version for reproducible builds.

2. Use a Non-Root User

FROM node:20-alpine
WORKDIR /app
COPY --chown=node:node . .
RUN npm ci --only=production
USER node
CMD ["node", "server.js"]

Running as root inside a container is a security risk. Always switch to a non-root user before CMD.

3. Set Memory and CPU Limits

deploy:
  resources:
    limits:
      cpus: '1.0'
      memory: 512M

No limits = a memory leak can take down every service on the host.

4. Add a HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=5s --retries=3   CMD wget -qO- http://localhost:3000/health || exit 1

Without a healthcheck, orchestrators can't tell if your app is actually ready to serve traffic.

5. Use Multi-Stage Builds

Keep build tools and dev dependencies out of your final image:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]

6. Have a .dockerignore File

node_modules
.git
.env
*.log
coverage
.DS_Store

Without it, you're sending gigabytes to the Docker daemon and leaking .env files into your image.

7. Never Bake Secrets into Images

Every RUN command, every COPY is a layer. Secrets in layers persist even after deletion.

# BAD — DATABASE_URL is visible in docker history
RUN export DATABASE_URL="postgres://..."

# GOOD — inject at runtime
docker run -e DATABASE_URL="postgres://..." my-app:latest

On PandaStack, set secrets from [dashboard.pandastack.io](https://dashboard.pandastack.io) — they're injected at runtime, never baked in.

8. Implement Graceful Shutdown

Handle SIGTERM in your application so in-flight requests complete before the container stops:

process.on('SIGTERM', () => {
  server.close(() => {
    console.log('Graceful shutdown complete');
    process.exit(0);
  });
});

Without this, rolling deployments drop active connections.

9. Use exec Form for CMD

# Shell form — shell intercepts signals, app never gets SIGTERM
CMD "node server.js"

# Exec form — signals go directly to the app process
CMD ["node", "server.js"]

10. Set Restart Policies

services:
  api:
    image: my-app:latest
    restart: unless-stopped

Options: no, always, on-failure, unless-stopped. Use unless-stopped for services that should always be running.

11. Scan Images for CVEs

docker scout cves my-app:latest
# or
trivy image my-app:latest

Run scans in CI before pushing to production. Rebuild with updated base images regularly.

12. Configure Structured Logging

Don't write logs to files inside containers — write to stdout/stderr. The container runtime captures them:

// Use JSON structured logging
console.log(JSON.stringify({ level: 'info', msg: 'Server started', port: 3000 }));
docker logs --tail 100 -f my-container

13. Use Read-Only Filesystem Where Possible

docker run --read-only   --tmpfs /tmp:rw,noexec,nosuid   my-app:latest

A read-only filesystem prevents attackers from writing malicious files if they get code execution.

14. Tag Images with Commit SHAs

# Don't use 'latest' in production — it's not auditable
docker build -t my-app:$GIT_SHA .
docker push my-app:$GIT_SHA

Tag with the git commit SHA so you can always trace a running container back to the exact code.

15. Test Your Rollback Process

# Know how to roll back before you need to
docker service update --image my-app:previous-sha my-app-service

Deploys fail. Practice the rollback before your first production incident.

Deploying Production-Ready Containers on PandaStack

PandaStack's container deployments handle many of these concerns at the platform level — TLS termination, health checks, rolling deployments, and restart policies are managed for you.

npm install -g @pandastack/cli
panda deploy --type container --repo your-org/your-repo

Focus on writing great code; let the platform handle the infrastructure. Learn more at [docs.pandastack.io](https://docs.pandastack.io) or manage your deployments at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack — no credit card required.

Start free on PandaStack

More in Guide

Browse all Guide articles →

See also