Implementing Docker Compose as a Service via Systemd

Implementing Docker Compose as a Service via Systemd
Photo by Phil Huang @ Vancouver, BC

I have personally been using docker-compose for over 10 years. When most services are containerd, I usually write the YAML file for the docker-compose.yaml at the same time, rather than using docker commands directly.

https://brand.systemd.io

Although Kuberentes can handle many complex scenarios, sometimes when the scenriao is simpler, you might want to expose services in an easier way, and docker-compose + systemd is a great choice for that.

Run Docker-compose as a Systemd service

The core technology is using systemd to manage the start and stop of docker-compose. The following script is the method I am currently using in the production envirnomnet.

[Unit]
Description=Blacair API Service
Requires=docker.service
After=docker.service

[Service]
Type=simple
WorkingDirectory=/root/blackair-api/ # Need to point the folder where your docker-compose is located
Environment=ENVIRONMENT=production # Put any environments you want to pass into docker
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down
Restart=always
RestartSec=10s
User=root
Group=root

[Install]
WantedBy=multi-user.target

blackair-api.service

#!/bin/bash
# This script installs systemd and its dependencies on a Linux system.

SERVICE_NAME="blackair-api.service"

# Check if the script is run as root
if [ "$(id -u)" -ne 0 ]; then
    echo "This script must be run as root."
    exit 1
fi

# Check if the /etc/systemd/system/$SERVICE_NAME exists
if [ ! -f /etc/systemd/system/$SERVICE_NAME ]; then
    cp $SERVICE_NAME /etc/systemd/system/$SERVICE_NAME
fi

systemctl daemon-reload
systemctl enable $SERVICE_NAME
systemctl start $SERVICE_NAME
systemctl status $SERVICE_NAME

install-systemd-serivce.sh

Forward syslog to Journald

Due to systemd's buit-in capability to provide real-time logging and storage of application logs, service started with systemd will, by default, forward logs to journald without requiring the alternative installation of a rsyslogd service for log collection.

journalctl -u blackair-api.service -f
journalctl

However, the logs received every day are very numerous, and to preveent the logs from completely consuming the hard disk space, we need to make adjustments to /etc/systemd/journald.conf

[Journal]
# Ensure that logs are saved into disk
Storage=persistent
# Compress logs to save disk space
Compress=yes
# Set the max disk space available for logs
SystemMaxUse=1G
# Set the maximum days of log files to retain
MaxRetentionSec=90day

/etc/systemd/journald.conf

systemctl restart systemd-journald
journalctl --rotate

Through the above setting, we can ensure that logs can be retained for 90 days and the log limit is 1GB only.

Container with Systemd

Overall, I feel very comfortable with this way of usage. Of course, if you need to use a large number of containers at the same time, Kubernetes is still an excellent choice. However, if you are interested in podman + systemd, you can refer to the document "Red Hat Enterprise Linux - Chapter 11. Porting containers to systemd using Podman," which provides very detailed explanations.

Read more