for Production Shops and APIs
A container that runs fine on your laptop is not yet a production-ready container. Health checks, restart policies, secrets management, resource limits and clean logging are the factors that decide between a stable production system and outages in the middle of the night.
Table of Contents
- 1. Why a Docker container checklist is essential
- 2. Health checks: monitoring container health continuously
- 3. Restart policies: configuring automatic recovery
- 4. Logging: structured and rotated in production
- 5. Secrets management: no passwords in images or compose files
- 6. Resource limits: CPU and memory for stable co-existence
- 7. Controlling network segmentation and port exposure
- 8. Automating image updates and vulnerability scanning
- 9. Docker container checklist in direct comparison
- 10. Summary
- 11. FAQ
1. Why a Docker container checklist is essential
Most container problems in production are not caused by faulty application logic, but by missing or misconfigured container infrastructure. A Docker container checklist is the structured way to make sure no critical aspect gets forgotten during deployment. Without one, containers regularly end up in production that will not restart automatically after a crash, whose logs fill up the disk, or that run with plaintext passwords in environment variables.
Especially in e-commerce projects, Magento shops, Shopware instances, WooCommerce systems, and in APIs with high traffic volumes, the consequences of a container that is not production-ready are directly measurable: downtime, data loss, security incidents. A complete Docker container checklist covers the ten areas that separate a working development container from a production-grade one. The following sections walk through every point of this Docker container checklist and show exactly what needs to be configured and why.
A common misconception: Docker Compose in development often works without any safeguards, because the developer sees problems directly and steps in. In production, containers run unattended, often at night and on weekends. The Docker container checklist closes the gap between "runs on my machine" and "runs reliably in production".
2. Health checks: monitoring container health continuously
A Docker health check is the first point of any serious Docker container checklist. Without a health check, Docker marks a container as "running" as soon as the main process has started, regardless of whether the application can actually handle requests. A started PHP-FPM process does not mean the database connection is up and the shop can process orders. The health check defines what "healthy" means for this specific container.
The parameters interval, timeout, retries and start_period in the Docker container checklist must be tuned to the application's startup time. A Magento container needs considerably longer on its first start than on a warm restart, and start_period: 120s prevents the container from being marked unhealthy during initialization. The interval value determines how often the health check runs. For critical production systems, 30 seconds is a good compromise between reaction speed and the load the check itself causes.
# docker-compose.yml: Production health check configuration
version: "3.9"
services:
php:
image: mironsoft/magento-php:8.4-fpm
healthcheck:
# Check that PHP-FPM is accepting connections on the socket
test: ["CMD", "php-fpm-healthcheck"]
interval: 30s
timeout: 10s
retries: 3
start_period: 120s
nginx:
image: nginx:1.27-alpine
healthcheck:
# HTTP health endpoint returning 200 when Nginx serves requests
test: ["CMD", "curl", "-f", "-s", "--max-time", "5", "http://localhost/health"]
interval: 15s
timeout: 5s
retries: 3
start_period: 10s
redis:
image: redis:7.4-alpine
healthcheck:
# Redis PING command confirms the server is ready
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
Important at this point in the Docker container checklist: the health check command must be available inside the container image. Minimal images such as Alpine-based containers often lack curl. Either add curl in the Dockerfile, or fall back to wget or a dedicated health check endpoint in the application. An HTTP endpoint such as /health that explicitly checks the database connection, the cache connection and filesystem writability is the most reliable option for complex applications like e-commerce shops.
3. Restart policies: configuring automatic recovery
Restart policies are the second essential item on the Docker container checklist. Without an explicit restart policy, a container will not come back up after a crash: it stays stopped until an operator intervenes manually. For production systems that need to be available around the clock, that is unacceptable. The unless-stopped policy restarts the container automatically after every crash and after a server reboot, but does not restart it if it was stopped manually.
The on-failure policy with a maximum number of restarts is suited to worker containers that should not end up in a restart loop after a persistent error. For web servers and database containers, unless-stopped is the right choice in this part of the Docker container checklist. In Docker Swarm or Kubernetes, restart policies are replaced by service reconciliation, but for simple Compose deployments on a single server, this setting remains an essential checklist item.
4. Logging: structured and rotated in production
Docker's default logging writes all container output into JSON files under /var/lib/docker/containers/. Without rotation, these files fill up the disk, especially with verbose PHP applications or Nginx access logs under heavy traffic. Item four of the Docker container checklist is therefore configuring the log driver with explicit limits. The json-file driver with max-size: "50m" and max-file: "5" caps logs at a maximum of 250 MB per container.
For centralized logging in larger environments, multiple servers, multiple containers, the Docker container checklist points to the fluentd or loki driver. These forward logs directly to a central log aggregator without accumulating logs on the host's disk. Structured logging from within the application, JSON format instead of free text, makes it possible to filter and search logs efficiently. A Magento shop that logs its errors as structured JSON can be analyzed in minutes during an incident instead of hours.
# Logging configuration in docker-compose.yml
# Prevents disk exhaustion from unrotated container logs
version: "3.9"
services:
php:
image: mironsoft/magento-php:8.4-fpm
logging:
driver: "json-file"
options:
# Rotate after 50 MB, keep 5 files = max 250 MB per container
max-size: "50m"
max-file: "5"
# Add container labels to log entries for filtering
labels: "com.mironsoft.service"
tag: "{{.Name}}/{{.ID}}"
nginx:
image: nginx:1.27-alpine
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
# Global logging default in /etc/docker/daemon.json
# {
# "log-driver": "json-file",
# "log-opts": { "max-size": "50m", "max-file": "3" }
# }
5. Secrets management: no passwords in images or compose files
Storing passwords and API keys as environment variables directly in docker-compose.yml is one of the most common security mistakes a Docker container checklist is meant to prevent. These values end up in version control, in docker inspect output, and in the layer caches of images. Instead, item five of the checklist points to Docker Secrets for Swarm deployments, or to dedicated .env files that are excluded from the repository and mounted into containers via the secrets directive.
For single servers without Swarm, the Docker container checklist recommends the pattern of placing secrets as files in a directory outside the repository and mounting them as read-only volumes into the container. The application reads the secret from the file instead of from an environment variable. This pattern is compatible with HashiCorp Vault, AWS Secrets Manager and other secret stores that expose secrets as files. Critically, the base image must not contain any secrets: docker history and docker inspect reveal every layer and environment variable set during the build.
6. Resource limits: CPU and memory for stable co-existence
Without resource limits, a single container can, in a failure scenario, block all CPU cores or consume all available memory, destabilizing other services on the same host. Item six of the Docker container checklist is configuring mem_limit, mem_reservation and cpus for every container. The distinction between mem_limit (a hard limit, the container gets killed once exceeded) and mem_reservation (a soft limit, honored only under resource pressure) matters here.
For a Magento PHP-FPM container on a server with 8 GB of RAM, typical values are: mem_limit: 2g, mem_reservation: 512m, cpus: "2.0". These values belong in the project's Docker container checklist, adjusted to the actual resource usage measured through monitoring. The docker stats tool provides live data on CPU and memory usage of all running containers and is the starting point for sizing these limits.
# Resource limits in docker-compose.yml
# Prevents a single container from starving other services
version: "3.9"
services:
php:
image: mironsoft/magento-php:8.4-fpm
deploy:
resources:
limits:
# Hard limit: container is OOM-killed if exceeded
memory: 2G
cpus: "2.0"
reservations:
# Soft limit: respected during resource contention
memory: 512M
cpus: "0.5"
mysql:
image: mysql:8.4
deploy:
resources:
limits:
memory: 4G
cpus: "4.0"
reservations:
memory: 1G
cpus: "1.0"
redis:
image: redis:7.4-alpine
deploy:
resources:
limits:
memory: 512M
cpus: "0.5"
# Monitor actual usage:
# docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
7. Controlling network segmentation and port exposure
By default, Docker Compose connects all containers of a project on a single shared network. That means every container can reach every other container. For a production environment, that is too permissive. Item seven of the Docker container checklist recommends defining explicit networks and assigning containers only to the networks they actually need to communicate on. The database should only be reachable from the application container, not from the SMTP container or external services.
Port exposure is just as critical. Binding a port to 0.0.0.0 in the ports directive makes the service reachable on every network interface of the host, including the public one. The Docker container checklist requires binding database ports only to 127.0.0.1: "127.0.0.1:3306:3306". That way MySQL cannot be reached from outside the server, even if the host firewall has a gap. Only the reverse proxy port (80/443) should ever be exposed externally.
8. Automating image updates and vulnerability scanning
A container image with known CVEs running in production is a security risk that a Docker container checklist can address systematically. Images do not update themselves; they stay at the state of the last build until someone explicitly runs docker pull and docker compose up -d --pull always. Item eight of the checklist recommends scheduling weekly automated vulnerability scans with Trivy or Grype and defining critical CVEs as deployment blockers.
Concretely, for the Docker container checklist this means: pinning to minor versions instead of latest (e.g. mysql:8.4 instead of mysql:latest), automated Dependabot or Renovate pull requests for image updates, and a CI pipeline that runs a Trivy scan on the built image at every merge. The base image should be refreshed regularly against a clean minimal image such as alpine or debian-slim to keep the attack surface small.
9. Docker container checklist in direct comparison
The table below shows, for every point of the Docker container checklist, what a typical development container includes and what a production-ready container must have configured. The gap between these two columns is the risk introduced into production by a container that is not fully configured.
| Checklist item | Development (typical) | Production (checklist) | Risk without configuration |
|---|---|---|---|
| Health check | Not configured | HTTP or CMD check with start_period | Container shows "running" even though the app is down |
| Restart policy | no (default) | unless-stopped | Container is not recovered after a crash |
| Log rotation | Unlimited (JSON file) | max-size: 50m, max-file: 5 | Disk fills up, host becomes unstable |
| Secrets | Plaintext in .env | Docker Secrets or read-only mount | Credentials exposed in logs and inspect output |
| Resource limits | No limits | mem_limit + cpus per service | One container destabilizes the entire host |
Implementing this Docker container checklist can be centralized in a single compose file covering all production services. A docker-compose.prod.yml that extends the development compose file with overrides keeps the difference between development and production configuration explicit and visible. Every new service added to the project must go through this checklist before it is deployed to production.
Mironsoft
Docker consulting, container security and production deployments
Ready to put this Docker container checklist into practice?
We review your existing compose files against the full Docker container checklist, identify gaps in health checks, secrets and resource limits, and deliver production-ready configurations for shops and APIs.
Compose audit
Complete review of all compose files against the Docker container checklist
Secrets hardening
Migration from plaintext credentials to Docker Secrets or Vault integration
Monitoring setup
Health check alerting and container metrics with Grafana and Prometheus
10. Summary
The Docker container checklist for production shops and APIs covers ten points that together ensure a container does not just run on your laptop, but is stable, secure and observable in production. Health checks define what health means for this container. Restart policies provide automatic recovery without manual intervention. Log rotation prevents disk exhaustion. Secrets management eliminates plaintext credentials from compose files and images.
Resource limits protect other services on the same host. Network segmentation reduces the blast radius of a compromised container. Regular image updates and vulnerability scans keep the security posture current. This Docker container checklist is not a one-time document; it belongs integrated into the deployment process and revisited for every new service. A container that satisfies every point on this checklist is ready for production.
Docker Container Checklist: The Essentials at a Glance
Health & Restart
Health check with a tuned start_period and restart policy unless-stopped, the foundation for self-healing production systems.
Logging & Secrets
Log rotation with max-size and max-file. No credentials in compose files, use Docker Secrets or read-only volume mounts instead.
Resource limits
Configure mem_limit and cpus for every service. Use measurements from docker stats as the basis for sizing.
Network & Updates
Bind database ports only to 127.0.0.1. Run weekly Trivy scans and pin images to minor versions instead of latest.