Skip to content

Instantly share code, notes, and snippets.

@mosquito
Last active May 22, 2024 17:17
Show Gist options
  • Save mosquito/b23e1c1e5723a7fd9e6568e5cf91180f to your computer and use it in GitHub Desktop.
Save mosquito/b23e1c1e5723a7fd9e6568e5cf91180f to your computer and use it in GitHub Desktop.
Add doker-compose as a systemd unit

Docker compose as a systemd unit

Create file /etc/systemd/system/docker-compose@.service. SystemD calling binaries using an absolute path. In my case is prefixed by /usr/local/bin, you should use paths specific for your environment.

[Unit]
Description=%i service with docker compose
PartOf=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=true
WorkingDirectory=/etc/docker/compose/%i
ExecStart=/usr/local/bin/docker-compose up -d --remove-orphans
ExecStop=/usr/local/bin/docker-compose down

[Install]
WantedBy=multi-user.target

Place your docker-compose.yml into /etc/docker/compose/myservice and call

systemctl start docker-compose@myservice

Docker cleanup timer with system

Create /etc/systemd/system/docker-cleanup.timer with this content:

[Unit]
Description=Docker cleanup timer

[Timer]
OnUnitInactiveSec=12h

[Install]
WantedBy=timers.target

And service file /etc/systemd/system/docker-cleanup.service:

[Unit]
Description=Docker cleanup
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
WorkingDirectory=/tmp
User=root
Group=root
ExecStart=/usr/bin/docker system prune -af

[Install]
WantedBy=multi-user.target

run systemctl enable docker-cleanup.timer for enabling the timer

JournalD support

Just add the following line to the /etc/docker/daemon.json:

{
    ...
    "log-driver": "journald",
    ...
}

And restart your docker service.

@gnat
Copy link

gnat commented May 17, 2021

Also this was required for me to get systemctl --user enable docker-compose@blah to work on Ubuntu 20.04 server (load on reboot).

[Install]
WantedBy=default.target

default.target should be an alias for multi-user.target, but apparently not in my situation.

@parisni
Copy link

parisni commented May 18, 2021

and all the above restrictions will not be applied.

well my experimentations have shown that some of them have impact: for example, if I turn off Notify then the docker-compose does not start up

@whistler
Copy link

Would it be better to remove -d after docker-compose up so logs get saved by systemctl?

@mosquito
Copy link
Author

Would it be better to remove -d after docker-compose up so logs get saved by systemctl?

The better way is the docker starts writing all logs to the journald

@chkpnt
Copy link

chkpnt commented Oct 4, 2021

I'm using WantedBy=docker.service so that the service is started when docker itself is (re)started.

@bigntallmike
Copy link

This is great but as said in the docker forums, "docker system prune is not safe to be used in production."

@so-jelly
Copy link

so-jelly commented May 1, 2022

@chkpnt I recommend using

PartOf=docker.service

PartOf=

Configures dependencies similar to Requires=, but limited to stopping and restarting of units. When systemd stops or restarts the units listed here, the action is propagated to this unit. Note that this is a one-way dependency — changes to this unit do not affect the listed units.

@dcd-arnold
Copy link

The better way is the docker starts writing all logs to the journald

@mosquito can you explain why?

@mosquito
Copy link
Author

@dcd-arnold It's simple, at the time of writing this note, the docker daemon storage all container logs in plain JSON files in the /var/lib/docker, which quite often grew to a rather indecent size if you do not does something for control them separately. Now the question is, why do you have to monitor this separately if there is already a daemon in the operating system that can effectively read/write/compress/sign structured log records? Thus, transferring responsibility for all logs to the JournalD level allows them to be efficiently stored, rotated, and read using journalctl filters (e.g. CONTAINER_ID or CONTAINER_NAME).

@mosquito
Copy link
Author

@so-jelly fixed thank you.

@dcd-arnold
Copy link

It's simple, at the time of writing this note, the docker daemon storage all container logs in plain JSON files in the /var/lib/docker, which quite often grew to a rather indecent size if you do not does something for control them separately. Now the question is, why do you have to monitor this separately if there is already a daemon in the operating system that can effectively read/write/compress/sign structured log records? Thus, transferring responsibility for all logs to the JournalD level allows them to be efficiently stored, rotated, and read using journalctl filters (e.g. CONTAINER_ID or CONTAINER_NAME).

@mosquito But docker-compose would not run in background, hence pushing its stdout to systemd, which is build to take such data in and store it. What am i missing here?

@mosquito
Copy link
Author

@dcd-arnold but /usr/local/bin/docker-compose up -d ... in the ExecStart=

@dcd-arnold
Copy link

@mosquito That was the original question:

Would it be better to remove -d after docker-compose up so logs get saved by systemctl?

If you omit -d, docker-compose pushes its stdout to systemd to do with it as it sees fit.

@mosquito
Copy link
Author

@dcd-arnold if you omit something from this recipe, you have to resolve following troubles :-).

@dcd-arnold
Copy link

@mosquito @dcd-arnold if you omit something from this recipe, you have to resolve following troubles :-).

sure thing.

@jest
Copy link

jest commented Jun 7, 2022

@dcd-arnold moreover, having docker-compose printing logs on stdout doesn't stop Docker daemon from saving logs. So you would end up using twice as much space -- once in Docker daemon and once in systemd -- as required for your logs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment