3

I want to systemd-ize our docker/docker-compose/podman setups, but it seems that systemd is incapable of properly dealing with service units that end without leaving a process behind. That is problematic, because the tools in question work by calling an API, scheduling processes to start but not spawning or forking them themselves, so by the time a call to, say, docker-compose returns, no processes are visible for systemd, so any variation of Type/RemainAfterExit still leads to the service marked as stop/dead/stopping/etc., because no surviving PID is detected.

I am not sure if this is relevant, but I run in userspace with --user. Lingering is enabled for the user.

This is one of my many attempts at getting systemd to work, but like any other combination of settings, it gets stopped after 5 seconds:

[Unit]
Description=%u service with docker compose
BindsTo=podman.service
After=podman.service

[Service]
Environment=DOCKER_HOST=unix:///run/user/%U/podman/podman.sock
Environment=XDG_RUNTIME_DIR=/run/user/%U
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/podman/%u
ExecStart=/usr/local/bin/docker-compose up -d --remove-orphans
ExecStop=/usr/local/bin/docker-compose down -v

[Install]
WantedBy=default.target

I start above file with systemctl --user start myservice.service. It produces an output like this:

May 04 14:10:27 myhost systemd[841]: Starting myservice service with docker compose...
May 04 14:10:27 myhost docker-compose[106023]:  Container nginx  Creating
May 04 14:10:27 myhost docker-compose[106023]:  Container nginx  Created
May 04 14:10:27 myhost docker-compose[106023]:  Container nginx  Starting
May 04 14:10:27 myhost docker-compose[106023]:  Container nginx  Started
May 04 14:10:27 myhost systemd[841]: Finished myservice service with docker compose.
May 04 14:10:32 myhost systemd[841]: Stopping myservice service with docker compose...
May 04 14:12:03 myhost systemd[841]: myservice.service: Stopping timed out. Terminating.
May 04 14:12:03 myhost systemd[841]: myservice.service: Failed with result 'timeout'.
May 04 14:12:03 myhost systemd[841]: myservice.service: Unit process 106072 (docker-compose) remains running after unit stopped.
May 04 14:12:03 myhost systemd[841]: Stopped myservice service with docker compose.
May 04 14:12:03 myhost docker-compose[106072]:  Container nginx  Stopping
May 04 14:12:03 myhost docker-compose[106072]:  Container nginx  Stopped
May 04 14:12:03 myhost docker-compose[106072]:  Container nginx  Removing
May 04 14:12:03 myhost docker-compose[106072]:  Container nginx  Removed
Torque
  • 131
  • 2
  • 1
    I must admit, I generate my pod startup scripts by creating a pod (which is what your docker-compose probably does when you "up"), and then use `podman generate systemd` to give me a set of service files that depend on each other in the right order. – Marcus Müller May 04 '23 at 12:18
  • Unfortunately, docker-compose doesn't create pods, and we have too many existing compose configurations to just start from scratch and write a gazillion pod definitions :( – Torque May 04 '23 at 12:42
  • `podman-compose` does @Torque – Nicolas Formichella May 04 '23 at 14:11

1 Answers1

1

When executing docker-compose from systemd you do not want to daemonize (remove the -d option from your ExecStart) so systemd can properly track it.

You probably also do not need to declare the Type= or RemainAfterExit= options as the defaults should be fine for docker-compose services.

If you want to make services for individual containers, I would advise you look at the output of podman generate systemd for one of your containers and adjust your Docker service files to be similar.

Another note: the podman.service is not supposed to be constantly running as it is invoked from podman.socket. Setting After= to reference podman.socket may be closer to the behavior you are expecting. I am not sure the BindsTo= option is what you are looking for. While the podman.socket would be required for running docker-compose commands, it is not required for running the containers and I am not sure you would want all of your containers to restart when the Podman API is restarted.

With all that, your posted service file would look like this:

[Unit]
Description=%u service with docker compose
After=podman.socket

[Service]
Environment=DOCKER_HOST=unix:///run/user/%U/podman/podman.sock
Environment=XDG_RUNTIME_DIR=/run/user/%U
WorkingDirectory=/srv/podman/%u
ExecStart=/usr/local/bin/docker-compose up --remove-orphans
ExecStop=/usr/local/bin/docker-compose down -v

[Install]
WantedBy=default.target

These have been my experiences with running podman and docker-compose through systemd. Hopefully some of that helps you craft working services for your containers.

GracefulRestart
  • 4,421
  • 1
  • 9
  • 10
  • Your point about the correct service name being `podman.socket` instead of `podman.service` was actually the reason for my problem. I would accept your answer, but I have been warned against leaving non-detached docker-compose instances open for weeks at a time like this so I am not sure I should. Are you certain that that is a good idea ? – Torque May 04 '23 at 18:34
  • If you have documentation about leaving non-detached `docker-compose` containers running, I would to see it. I cannot think of any problems off the top of my head, and all of my `docker-compose` `systemd` services work this way. `systemd` wants all services to run in the foreground to track them properly. If there is an issue with `docker-compose` running that way, it is news to me. – GracefulRestart May 04 '23 at 19:53