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.

Application Services

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.

Try It — Systemd Unit File Generator

Open full tool