Systemd Service for docker-compose

Docker-compose can be used to deploy simple applications, it gives ability to start set of dependent containers or services as a whole application. It is simple to use and configure.

For small and simple applications, Docker Compose is the preferred choice. However, for more complex and enterprise-level applications, alternatives such as Docker Swarm or Kubernetes may be more suitable.


Docker compose provides simplicity for deploying simple applications. When server is restarted docker containers will not start automatically. This can be solved by creating custom systemd service. Let's first see from basics.

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.

  • systemd services can be started automatically at boot time
  • These services can be restarted in case of failures
  • We can enable/disable these services to handle with systemd process or not.
  • By using systemd services, system administrators can manage and organize system services in a consistent and centralized manner.

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
# 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.

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.

Suhas Adhav
In love with web3, DApps and Blockchain Technology | DevOps Expert | Kubernetes | Docker | Jenkins | Cloud | Hadoop
The Internet