5 min read

Running Docker Compose as a systemd Service: A Comprehensive Guide

Learn how to run Docker Compose as a systemd service to ensure automatic startup and seamless container management.
Running Docker Compose as a systemd Service: A Comprehensive Guide
Using Sytemd for Docker Compose Deployments For Easy Management

Docker Compose is like a handy tool for putting together simple apps. It lets you start a bunch of connected parts (we call them containers) all at once, creating a single app. It's pretty easy to use and set up.

Managing Docker containers efficiently is crucial for seamless application deployment. Integrating Docker Compose with systemd allows for automatic startup and robust process management of your containerized applications. In this guide, we'll walk you through setting up Docker Compose as a systemd service, ensuring your applications are resilient and easy to manage.


Table fo contents

Why Use systemd with Docker Compose?

Systemd is the init system for many Linux distributions, responsible for managing system services during boot and runtime. By creating a systemd service for your Docker Compose applications, you can:

  • Ensure Automatic Startup: Your Docker containers will start automatically on system boot.
  • Simplify Management: Utilize systemd commands to control your Docker services.
  • Enhance Reliability: Systemd monitors services and can restart them upon failure.

Prerequisites

Before proceeding, ensure you have:

  • A Linux system with systemd (e.g., Ubuntu 20.04).
  • Docker and Docker Compose installed.
  • A Docker Compose YAML file (docker-compose.yml) defining your services.

What is systemd service?

A systemd service is a script or executable that is managed by the systemd process, which controls the behavior and status of these underlying services.

  • Automatic Startup: Ensure that your Docker containers start automatically when the system boots.
  • Unified Management: Use familiar systemctl commands to manage your Docker Compose applications.
  • Enhanced Reliability: Leverage systemd's process management capabilities to monitor and restart services as needed.
  • Handy & Simple to operate: Handling services is simple and easy as they can be used as system component instead of decoupled program.

Steps to Create systemd Service

To create systemd service we need to write a service file which will execute command or script in case of start, stop and restart actions.

So in case of docker-compose application we need to have docker-compose.yml file which has definition of all the services and then using docker-compose up -d command we can give start action for the service, similarly for stop we can use docker-compose stop command.

Let's see step by step:

  • Write docker-compose.yml file with all services/components, below is the django app example taken from docker documentation.
version: "3.9"
   
services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

Example from docs.docker.com

  • For testing purpose you can bring the application up by using docker-compose up command, additionally we can have -d flag for running application as daemon
# will bring up all services in docker-compose.yml
docker-compose up -d

# pass yml file with -f flag
docker-compose up -f application.yml
  • Once, application is working correctly we can have service for this application by writing service file and placing it in /etc/systemd/system directory
  • Create file /etc/systemd/system/myapp.service with below content - note ExecStart and ExecStop directives - each will be used as starting and stopping command for the service respectively
[Unit]
Description=Service for myapp
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
WorkingDirectory=/root/bootvar
Environment=COMPOSE_HTTP_TIMEOUT=600
ExecStart=/usr/bin/env /usr/bin/docker-compose -f /root/bootvar/docker-compose.yml up -d
ExecStop=/usr/bin/env /usr/bin/docker-compose -f /root/bootvar/docker-compose.yml stop
StandardOutput=syslog
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

/etc/systemd/system/myapp.service

  • You can set environment variables using Environment directive or pass variables from a file
  • Once file is created you need to reload all system services using systemctl daemon-reload command
  • Now you have created myapp service, start the service using systemctl start myapp which will execute command/script defined in ExecStart
  • If you want to start your service whenever your server reboots then you need to enable it using systemctl enable myapp command which will ensure whenever your server boots up myapp service will be started
  • Adjust the WorkingDirectory to the location of your docker-compose.yml.
  • Ensure the ExecStart and ExecStop paths point to your Docker Compose binary.
# will enable service to start at server bootup
systemctl enable myapp

# start service ( Executes ExecStart command )
systemctl start myapp

This way you can make sure your docker-compose service stays up and running after every server restart.

Best Practices

  • Environment Variables: If your application requires environment variables, define them within the docker-compose.yml or specify them in the systemd service file using the Environment directive.
  • User Permissions: If running Docker as a non-root user, specify the User directive in the [Service] section of the systemd service file.
  • Timeouts: Adjust TimeoutStartSec and other timeout settings as needed to ensure that services have adequate time to start and stop.
  • Logging: Redirect logs to syslog or a specific file by configuring the StandardOutput and StandardError directives.

Troubleshooting

  • Permission Issues: Ensure the user running the systemd service has the necessary permissions to manage Docker.
  • Path Errors: Verify that the paths to docker-compose and your working directory are correct.
  • Service Not Starting on Boot: Confirm that the service is enabled and that there are no errors in the service file syntax.

Conclusion

To turn a correctly working application into a service, you can write a service file and place it in the /etc/systemd/system directory. The service file, named myapp.service, should contain the starting and stopping commands for the service, specified in the ExecStart and ExecStop directives, respectively.

With a custom systemd service, the application can be automatically started when the server is restarted, overcoming the limitation of Docker Compose's lack of automatic start on reboot.

Frequently Asked Questions (FAQs)

1. Why should I use systemd instead of docker-compose up -d?

Using systemd ensures that your Docker Compose services automatically restart on reboot, can be monitored, and follow a structured logging mechanism.

2. How do I check if my systemd service for Docker Compose is running correctly?

You can use the following command to check the status:

sudo systemctl status my-docker-compose

If there's an issue, logs can be checked using:

journalctl -u my-docker-compose --no-pager --lines=50

3. What happens if a container crashes?

If you've set the restart policy in your docker-compose.yml to always or unless-stopped, systemd will restart the container automatically when it crashes.

4. Can I run multiple Docker Compose projects with systemd?

Yes, but each project should have a separate systemd service file. Ensure each service file points to the correct docker-compose.yml location.

5. How can I update my Docker Compose service without stopping the entire systemd service?

You can update containers and reload systemd as follows:

cd /path/to/your/docker-compose
docker-compose pull  
docker-compose up -d  
sudo systemctl daemon-reload  
sudo systemctl restart myapp

6. How can I ensure my Docker Compose service starts on boot?

Enable the service to start at boot using:

sudo systemctl enable myapp

7. Does systemd support logging for Docker Compose services?

Yes, systemd captures logs for your services. View logs using:

journalctl -u my-docker-compose -f