10

I have a docker-compose project that I would like to control through systemd. In upstart, I would use a script that looks like this:

description "Start/Stop server"
author "Jim Cortez"

start on filesystem and started docker
stop on runlevel [!2345]

respawn limit 3 240

pre-start script
    # wait (if necessary) for our docker context to be accessible
    while [ ! -f /projects/my_server/docker-compose.yml ]
    do
      sleep 1
    done
    /usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml up -d
end script

script
    sleepWhileAppIsUp(){
        while docker ps | grep "$1" >/dev/null; do
            sleep 2
        done
    }

    sleepWhileAppIsUp "my_server"
end script

# stop docker container after the stop event has completed
post-stop script
    if docker ps | grep my_server;
    then
        /usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml stop
    fi
end script

(above adapted from here)

However, I am now running on a docker host that runs Ubuntu 15.04, which has switched to systemd. How can I do the above as a systemd service script? Simply launching the docker-compose daemon will not allow systemd to track and restart in case of failure.

Here is what I have so far:

[Unit]
Description=My Server container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml up -d
ExecStop=/usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml stop

[Install]
WantedBy=local.target
Jim Cortez
  • 201
  • 1
  • 2
  • 6

3 Answers3

11

I suggest removing the -d option. You do not need to run the containers in the background in this case.

Kevin Rood
  • 273
  • 3
  • 6
  • When removing `-d` and executing a start of the unit, it will block the prompt until the container is finished, which, depending on the workload, may be never. – OneK Jan 16 '21 at 15:31
6

I found that: The author uses a similar approach as you http://trackless.ca/2015/12/21/docker-compose-meets-systemd/. But additionally he creates one systemd service for each docker-compose service.

You might consider to convert your docker-compose file to multiple systemd service files to get rid of the docker-compose dependency: http://container-transform.readthedocs.org/ I used that approach, it works fine for simple setups.

André B.
  • 163
  • 2
0

Try this, I found in my test, it require more time than normal service to start or stop.

[Unit]
Description=My Server container
Requires=docker.service
After=network.target docker.service

[Service]
#Restart=always
Type=simple
WorkingDirectory=/projects/my_server
ExecStart=/usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /projects/my_server/docker-compose.yml down

[Install]
WantedBy=multi-user.target
Daniel YC Lin
  • 153
  • 1
  • 2
  • 7
  • 1
    i think you should use WorkingDirectory. docker-compose use current working directory to load .env files WorkingDirectory=/projects/my_server also ExecStart=/usr/local/bin/docker-compose up – Mohammadalijf May 01 '19 at 10:49