… has too many hobbies.

Using systemd to run a Docker container only when an SMB mount is mounted

I have a Linux machine that mounts several shares from my NAS via Samba. I'd like it to run fscrawler in a Docker container for each of those shares, but only when the shares are working properly — if the share goes away while fscrawler is running, fscrawler will eventually delete all the documents for that share from Elasticsearch. (Ask me how I know!)

This post walks through how to achieve that.

/etc/fstab

For the record, /etc/fstab entries for these shares look like this; it's very standard:

//jetstream.dzhome/general /mnt/jetstream/general cifs ro,credentials=/home/cdzombak/.smb-creds-jetstream,uid=1000,gid=1000 0 0

The docker-compose stack

Since lifetimes for these Docker containers will now be managed by systemd, I've removed the restart line from docker-compose.yml. Otherwise, the docker-compose stack looks exactly like the sample in my samba-docker repo. Here's a representative entry:

---
services:

  fscrawler-general:
    image: dadoonet/fscrawler:2.10-SNAPSHOT
    container_name: fscrawler-general
    volumes:
      - /mnt/jetstream/general:/mnt/storage/general:ro
      - ./fscrawler-config/general:/root/.fscrawler/general
      - /opt/docker/data/storageidx/logs:/usr/share/fscrawler/logs
    command: general --restart

Making the Docker container start & stop with the mount

For each mount, create a new file in /etc/systemd/system. On my machine, here's fscrawler-general.service:

[Unit]
Description=fscrawler - general SMB mount
After=mnt-jetstream-general.mount
Requires=mnt-jetstream-general.mount
BindsTo=mnt-jetstream-general.mount

[Install]
WantedBy=mnt-jetstream-general.mount

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/docker/compose/fscrawler
ExecStart=/usr/bin/docker compose up -d fscrawler-general
ExecStop=/usr/bin/docker compose stop fscrawler-general
TimeoutStartSec=0

Note that this uses the mounts that systemd automatically generated based on /etc/fstab. Neat!

This ensures that the fscrawler Docker container starts when the share is mounted and stops if it's unmounted for any reason.