2

I installed docker with snap. Every time snap updates docker, snap.docker.dockerd (default) service gets stopped and started after some time. I have a docker-compose app running so every update my app just goes down.

Docker compose's option restart doesn't work for me because of bug (https://github.com/docker/for-win/issues/584)

So the only option I see is to use systemd service. Here it is (/etc/systemd/system/docker-compose-chebur.service):

[Unit]
Description=Docker Compose Chebur
Requires=snap.docker.dockerd.service
PartOf=snap.docker.dockerd.service
After=snap.docker.dockerd.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/maybephilipp/projects/chebur-docker
User=maybephilipp
Group=docker
ExecStartPre=/usr/bin/sleep 3
ExecStart=/snap/bin/docker compose -f chebur.docker-compose.yml up -d
ExecStop=/snap/bin/docker compose -f chebur.docker-compose.yml down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

OS: Ubuntu 20.04.4

I tried BindsTo=, PartOf=, Requires= but as I see on the Internet and in practice they don't help in starting my service when snap.docker.dockerd gets started from stopped state.

So my question is: how can I make my service to start when snap kills and then starts docker service?

My second thought is to create cron tab that just does docker compose up -d every 5 mins or less. But it seems very dirty hack:(

1 Answers1

1

You want to change your [Install] section to:

[Install]
WantedBy=multi-user.target
WantedBy=snap.docker.dockerd.service

Then rerun systemctl enable docker-compose-chebur.service.


You were playing with Requires=, BindsTo= you almost had the right idea, but the wrong direction. You kept saying "When docker-compose-chebur.service starts, I also need to start snap.docker.dockerd.service". But you needed the opposite: When snap.docker.dockerd.service starts, start docker-compose-chebur.service". Therefore you really need to add Wants=, Requires=, BindsTo= to snap.docker.dockerd.service instead. If you can only modify this service, the opposite of Wants=, Requires= is WantedBy=, RequiredBy=. Those can only be set in the [Install] section. BoundBy= cannot be set in the [Unit] or [Install] sections as it's usually a mistake to do, but if necessary you can do it via drop-in.


Here's an explanation of all of the relationships you've defined. Maybe you don't need them all.

  • Requires=A.service: When this is started, A.service will start too. If After= is set (which it is) and A.service fails to start, this will not be started.
  • PartOf=A.service: When A.service is stopped/restarted, this will also be stopped/restarted.
  • After=A.service: See Requires=
  • WantedBy=A.service: When A.service is started, start this too. Unlike RequiredBy= which is the opposite of Requires=, this skips the success check.

In your case, I would check if snap.docker.dockerd.service is already WantedBy=multi-user.target. If so, I would drop that line in [Install] and simply have WantedBy=snap.docker.dockerd.service.

Reference: https://www.freedesktop.org/software/systemd/man/systemd.unit.html

Stewart
  • 12,628
  • 1
  • 37
  • 80