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
- 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 - noteExecStart
andExecStop
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
- 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 usingsystemctl start myapp
which will execute command/script defined inExecStart
- 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 upmyapp
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.