Docker Container Service
Manage a Docker container as a systemd service. Learn about Docker service dependencies, container lifecycle management, pre-start cleanup, and reliable restart behavior.
Detailed Explanation
Managing Docker Containers with systemd
While Docker has its own restart policies, managing containers through systemd provides integration with the host's service management, boot ordering, and dependency handling. This approach is useful when you need fine-grained control over container lifecycle.
[Unit]
Description=My Application Docker Container
After=docker.service
Requires=docker.service
[Service]
Type=simple
ExecStartPre=-/usr/bin/docker stop myapp
ExecStartPre=-/usr/bin/docker rm myapp
ExecStart=/usr/bin/docker run \
--name myapp \
--rm \
-p 8080:8080 \
-v /opt/myapp/data:/data \
-e NODE_ENV=production \
--log-driver=journald \
myapp:latest
ExecStop=/usr/bin/docker stop -t 10 myapp
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Docker Service Dependency
The Requires=docker.service and After=docker.service directives ensure:
- The Docker daemon is running before the container starts
- If the Docker daemon stops, the container service also stops
Pre-Start Cleanup
The ExecStartPre= lines handle cleanup of stale containers:
ExecStartPre=-/usr/bin/docker stop myapp
ExecStartPre=-/usr/bin/docker rm myapp
The - prefix means systemd ignores failures. If the container doesn't exist, the stop and rm commands fail, but the service still starts. This pattern prevents "container name already in use" errors.
Why docker run Instead of docker start -a
Using docker run with --rm creates a fresh container each time:
- Clean state: No leftover files from previous runs
- Image updates: Always uses the latest image tag
- No orphans: Container is removed when it stops
Alternatively, docker start -a reuses an existing container:
ExecStart=/usr/bin/docker start -a myapp
This is faster but doesn't pick up image updates automatically.
Journald Log Integration
The --log-driver=journald flag routes container logs to the systemd journal:
journalctl -u myapp.service -f
journalctl CONTAINER_NAME=myapp --since "1 hour ago"
Container Health Monitoring
Docker health checks integrate with systemd monitoring:
docker run --health-cmd="curl -f http://localhost:8080/health" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
myapp:latest
Use Case
Running a Docker container as a managed system service on a VM or bare-metal server where Docker Compose or Kubernetes is not available, but you need boot-time start, dependency ordering with other services, and automatic restart.