Docker: Setup, Security Best Practices, & Automation
Docker has transformed home lab infrastructure and enterprise deployment by enabling lightweight, isolated containerization. However, convenience must not come at the expense of host security. This guide covers secure setup, runtime protection, a quick-reference command cheat sheet, and automation strategies for backups and updates.
1. Core Container Security Principles
By default, container processes run as root inside the container namespace, and giving a process access to the Docker socket (/var/run/docker.sock) is equivalent to giving root access to the entire host OS.
- Never Expose the Docker Socket: Do not mount
/var/run/docker.sockinto unprivileged containers. - Specify Non-Root Users: Always add a
USERdirective in your Dockerfile or configureuser: "1000:1000"in Docker Compose to prevent applications from running as root. - Drop Unnecessary Capabilities: Remove Linux capabilities your application doesn’t need using
--cap-drop=ALLand selectively adding back only required permissions (e.g.,NET_BIND_SERVICE). - Forbid New Privileges: Always pass
--security-opt=no-new-privilegesto prevent processes from gaining new privileges via setuid/setgid binaries.
2. Docker Command Cheat Sheet
Container Lifecycle
docker ps— List running containers.docker ps -a— List all containers (running and stopped).docker start <container>/docker stop <container>— Start or stop a container.docker restart <container>— Restart a container.docker rm <container>— Remove a stopped container.docker rm -f <container>— Force remove a running container.
Monitoring & Inspection
docker logs -f <container>— Stream live container logs.docker stats— Display live resource utilization (CPU, memory, network I/O) for all containers.docker inspect <container>— View detailed low-level configuration JSON for a container.docker exec -it <container> /bin/bash— Open an interactive shell inside a running container.
Images & Cleanup
docker images— List downloaded local images.docker rmi <image>— Remove a local image.docker system prune -a --volumes— Remove all stopped containers, unused networks, dangling images, and unreferenced volumes to free disk space.
Docker Compose
docker compose up -d— Build (if needed) and start services in detached mode.docker compose down— Stop and remove containers and networks.docker compose logs -f— View logs across all services in the compose stack.docker compose pull— Download newer versions of base images defined in the compose file.
3. Automating Updates and Backups
A. Automated Container Updates with Watchtower
You can automate container image updates safely by deploying Watchtower as a companion container, configured to monitor and update your stack automatically:
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=86400 # Check daily (in seconds)
- WATCHTOWER_INCLUDE_STOPPED=false
B. Automated Volume & Configuration Backups
Container data stored in named volumes or bind mounts must be backed up regularly. Here is a robust shell script snippet that archives Docker volume directories into a timestamped tarball and prunes old backups:
#!/bin/bash
BACKUP_DIR="/mnt/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
VOLUMES_PATH="/var/lib/docker/volumes"
mkdir -p "$BACKUP_DIR"
echo "Starting Docker volume backup at $DATE..."
# Archive volumes
tar -czf "$BACKUP_DIR/docker_volumes_$DATE.tar.gz" -C "$VOLUMES_PATH" .
# Retain only the last 7 daily backups
find "$BACKUP_DIR" -name "docker_volumes_*.tar.gz" -mtime +7 -delete
echo "Backup completed successfully and stored in $BACKUP_DIR."
You can automate this script by placing it in /etc/cron.daily/docker-backup and ensuring it has executable permissions chmod +x /etc/cron.daily/docker-backup .