9

I found this question, but that one uses cron - I'd like to use a systemd service instead. My docker-compose.yml is in /home/me, and I run it with sudo docker compose up (and just keep it running in the background with tmux), and stop it with sudo docker compose down.

While functional, I'd rather do this using a systemd service to start/stop my docker-compose.yml file.

How can I turn my docker-compose.yml file into a (working) systemd service?

cocomac
  • 3,394
  • 1
    I know this doesn't answer your question, but because google sends people here I thought I'd point out two things. docker-compose is now docker compose with a space. That and do you REALLY need to use sudo for your setup? If you can get away without using sudo you really should not use it. The unit file would also need to be set to use a non-root user. – Knickers Brown Oct 23 '23 at 14:54
  • Have you tried using containerd to start containers at boot time? Ubuntu has it, this is one way to show that: $ apt-cache search containerd | grep -v golang – Knickers Brown Feb 16 '24 at 22:47

4 Answers4

9

I'll assume the docker-compose file is at /home/cocomac/docker-compose.yml, but you should replace it in my example with whatever the path to your docker compose file is.

First, let's create our service file. I like the text editor micro, personally, but feel free to use a different one. I'll call my service docker-compose.service, and it will be stored in /etc/systemd/system. Feel free to use a different name if you'd like, although if you do, remember to use that name when following the rest of this answer.

First, let's create and open the file with a text editor:

$ micro /etc/systemd/system/docker-compose.service

Put the following into the file:

[Unit]
Description=Some personal Docker containers
After=docker.service
Requires=docker.service

[Service] Type=oneshot RemainAfterExit=yes ExecStart=/bin/bash -c "docker compose -f /home/cocomac/docker-compose.yml up --detach" ExecStop=/bin/bash -c "docker compose -f /home/cocomac/docker-compose.yml stop"

[Install] WantedBy=multi-user.target

This gives our service a description, start + stop commands, as well as what it requires to be running before it starts. See this Arch Wiki page for an explanation of the different service types and what RemainAfterExit does.

Save the file and exit your text editor. You should now be able to do sudo systemctl start docker-compose to start your new systemd service. It may take a moment while it creates the containers, but once it finishes starting, you can do sudo systemctl status docker-compose to check the status of your service. You can also do sudo systemctl stop docker-compose to stop it (or sudo systemctl enable docker-compose to autostart it on boot)

cocomac
  • 3,394
2

Using the following for the Service stanza also works & has the benefit that you can view logs using journalctl -u docker-compose:

[Service]
Type=simple
ExecStart=/bin/bash -c "docker-compose -f /home/cocomac/docker-compose.yml up"
ExecStop=/bin/bash -c "docker-compose -f /home/cocomac/docker-compose.yml stop"

Note that the docker-compose command does not include the --detach flag and you do not need the RemainAfterExit option. Note also that on the version of Ubuntu I tested this on (20.04), docker-compose is a separate command.

0

If you use restart: always in your docker compose file (which is fairly typical), then the docker daemon will automatically restart the container when the daemon itself starts up -- which means that you don't need to use systemd to have it automatically running all the time.

You will still need to re-run docker-compose if you make changes to the compose file or to pull updates; this will not occur automatically. But this does not require a systemd file.

Pablo Bianchi
  • 15,657
Miral
  • 101
  • 1
0

You can also start systemd unit files listed in your user folder, and have them run on a regular basis. E.g. I have a certbot container that runs daily, to keep my ftp server's certificate up-to-date.

Based on the answer here.

Set your user profile to 'linger', with launchctl enable-linger ${USER}.

Create .service and .timer unit files in ~/.config/systemd/user. e.g.

~/.config/systemd/user/certbot-ftp.service

[Unit]
Description=Certbot LetsEncrypt renewal for vsftpd Server

[Service] Type=oneshot ExecStart=docker compose -f ~/docker-projects/ftp/compose.yaml restart certbot

[Install] WantedBy=default.target

~/.config/systemd/user/certbot-ftp.timer

[Unit]
Description=Run Certbot on a daily basis

[Timer] OnCalendar=daily Persistent=true

[Install] WantedBy=timers.target

Then, to enable the service and associated timer, which will happen whether or not you're logged in (because login lingering has been enabled):

systemctl --user enable certbot-ftp --now
Alex Leach
  • 101
  • 2