Practice & Assessment
Test your understanding of Docker in Production
Multiple Choice Questions
6Why should containers run as a non-root user?
What is the risk of using `--restart always` for an application container?
What does `--memory-swap=512m` do when `--memory=512m` is also set?
Why are Docker secrets more secure than environment variables for database passwords?
What happens to logs if the default json-file driver is used without any log-opt settings?
Which restart policy is best for a web API that should survive crashes but respect manual docker stop commands?
Coding Challenges
1Harden an existing Dockerfile for production
Given a Node.js Dockerfile that runs as root with no resource constraints and a json-file logger with no size limits, make the following changes: (1) Add a non-root user 'appuser' using addgroup and adduser in Alpine, switch to that user with USER instruction. (2) Build and run the image with --memory=256m --cpus=0.5 --memory-swap=256m flags. (3) Add --log-opt max-size=5m --log-opt max-file=3 to the docker run command. (4) Add --security-opt=no-new-privileges:true and --read-only flags. Verify the container is running with docker ps, check its user with docker exec container-id whoami (should return appuser), and view its resource constraints with docker inspect container-id | grep -A5 HostConfig. Estimated time: 20 minutes.
Mini Project
Production-Ready Compose Stack with Security Hardening
Harden a three-service Compose stack (api, db, nginx) for production deployment. Requirements: (1) All services use non-root users defined in their Dockerfiles. (2) Database password delivered via Docker Compose file-based secrets mounted at /run/secrets/db_password, read using the POSTGRES_PASSWORD_FILE env var. (3) All services have restart: unless-stopped. (4) The api service has memory limit 512M and CPU limit 0.5 in the deploy.resources block. (5) All services have logging configured with json-file driver, max-size 10m, max-file 3. (6) The db service has no host port mapping — only reachable from within the Compose network. (7) The nginx service exposes port 443 to the host. (8) All three services connected on a custom named network. Run the stack, verify the db is unreachable from the host on 5432 using nc or telnet, verify the api is reachable through nginx, and verify secrets are mounted correctly with docker exec db-container cat /run/secrets/db_password.
