Why a Checklist Matters
Deploying Docker containers to production can feel like assembling a jigsaw puzzle blindfolded. One missing piece—an unpinned base image, an exposed port, or a container that never shuts down—can turn a smooth rollout into a firefighting session. A concise checklist forces you to verify the most common failure points before you press Deploy.
Pre‑flight: Prepare Your Image
Base Image Selection
- Choose an official, minimal image (e.g.,
node:18-alpine
orpython:3.11-slim
). - Avoid
latest
tags; they introduce nondeterministic builds.
Pinning Versions
# Dockerfile example for a Node.js API
FROM node:18.17-alpine AS builder
WORKDIR /app
# Pin npm version
RUN npm install -g npm@9.8.1
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:18.17-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]
- Why? The exact version numbers lock down the attack surface and guarantee reproducible builds across CI runners.
Secure the Runtime
Run as a Non‑Root User
# Add a low‑privilege user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
- Never run your app as
root
. This limits the impact of a container breakout.
Read‑Only Filesystem
Add the --read-only
flag when you start the container, and mount only the directories that truly need write access.
docker run -d \
--read-only \
-v /app/tmp:/tmp:rw \
mycompany/api:1.2.3
- Protects against accidental overwrites and makes your container behave more like a stateless micro‑service.
Networking & Service Discovery
-
Expose only needed ports – use
EXPOSE
in the Dockerfile and-p
/--publish
at runtime for the exact mapping. - Healthchecks – let orchestrators know when a container is ready.
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
- Document the expected inbound/outbound traffic in a short table:
Port | Protocol | Purpose |
---|---|---|
3000 | TCP | HTTP API |
5432 | TCP | Database (only internal) |
Observability
-
Structured Logging – output JSON to
stdout
/stderr
. Most log aggregators (e.g., Loki, Papertrail) parse it automatically. - Metrics – expose Prometheus metrics on a dedicated endpoint.
- Tracing – inject a trace ID at the entry point and propagate it downstream.
# Example: expose Prometheus metrics at /metrics
ENV METRICS_PORT=9100
EXPOSE 9100
Graceful Shutdown with systemd
When Docker runs under a systemd service, you can control stop timeouts and ensure dependent services are notified.
# /etc/systemd/system/myapp.service
[Unit]
Description=My Dockerized API
After=network-online.target
Wants=network-online.target
[Service]
Restart=always
# Pull the latest image before each start (optional)
ExecStartPre=/usr/bin/docker pull mycompany/api:1.2.3
ExecStart=/usr/bin/docker run \
--rm \
--name myapp \
--read-only \
-v /app/tmp:/tmp:rw \
-p 3000:3000 \
mycompany/api:1.2.3
ExecStop=/usr/bin/docker stop -t 30 myapp
TimeoutStopSec=40
[Install]
WantedBy=multi-user.target
-
TimeoutStopSec
gives the container a 30‑second grace period to finish in‑flight requests beforedocker kill
is forced.
CI/CD Integration
A minimal GitHub Actions workflow that builds, scans, and pushes the image:
name: CI
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: mycompany/api:${{ github.sha }}
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: mycompany/api:${{ github.sha }}
severity: HIGH,CRITICAL
- The scan step catches known CVEs before they reach production.
Final Thoughts
Running Docker in production isn’t just about writing a Dockerfile
. It’s a disciplined process that spans image hygiene, runtime hardening, networking, observability, and automation. By ticking off each item on this checklist you’ll reduce the odds of a surprise outage and keep your services performant and secure. If you’re looking for a partner that can help you audit your container pipeline or provide managed Kubernetes hosting, consider checking out https://lacidaweb.com for a no‑pressure conversation.
Top comments (0)