CIFS Dependency Chains with Tailscale⚓︎
System Overview⚓︎
This configuration enables reliable mounting of CIFS network shares over Tailscale VPN before dependent services start. The setup uses systemd services with proper dependency chains to ensure correct startup sequence.
Prerequisites⚓︎
- Ubuntu Linux server
- Tailscale installed and configured
- Docker (if using containers)
- Samba credentials file
Component Details⚓︎
Credentials File⚓︎
Location: /etc/samba/credentials
Permissions: 600 (readable only by root)
Format:
Mount Script⚓︎
Location: /usr/local/bin/mount-shares.sh
Permissions: 755 (executable)
Purpose: Mounts all CIFS shares after Tailscale is ready
#!/bin/bash
# Wait for Tailscale
sleep 30
# Mount shares
/bin/mount -t cifs //100.122.167.110/Files /mnt/Backup -o credentials=/etc/samba/credentials,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,iocharset=utf8
/bin/mount -t cifs //100.122.167.110/Plex /mnt/Plex -o credentials=/etc/samba/credentials,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,iocharset=utf8
/bin/mount -t cifs //100.122.167.110/Files/minio /mnt/Minio -o credentials=/etc/samba/credentials,uid=1001,gid=1001,file_mode=0775,dir_mode=0775,iocharset=utf8
CIFS Mounts Service⚓︎
Location: /etc/systemd/system/cifs-mounts.service
Purpose: Systemd service that runs the mount script
Dependencies: network-online.target, tailscaled.service
[Unit]
Description=Mount CIFS shares
After=network-online.target tailscaled.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mount-shares.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Charm Mount Service⚓︎
Location: /etc/systemd/system/mount-charm.service
Purpose: Mounts a squashfs file from a CIFS share
Dependencies: cifs-mounts.service
[Unit]
Description=Mount charm.li squashfs file
After=network.target remote-fs.target cifs-mounts.service
Requires=cifs-mounts.service
RequiresMountsFor=/mnt/Backup
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/sleep 5
ExecStart=/bin/bash -c 'if ! mountpoint -q /mnt/Backup/operation-charm/lmdb-pages; then mount -o loop -t squashfs /mnt/Backup/operation-charm/lmdb-pages.sqsh /mnt/Backup/operation-charm/lmdb-pages; fi'
ExecStop=/bin/bash -c 'if mountpoint -q /mnt/Backup/operation-charm/lmdb-pages; then umount /mnt/Backup/operation-charm/lmdb-pages; fi'
[Install]
WantedBy=multi-user.target
Docker Service Dependency⚓︎
Location: /etc/systemd/system/docker.service.d/wait-for-mounts.conf
Purpose: Makes Docker wait for all mounts to complete
[Unit]
After=cifs-mounts.service mount-charm.service
Requires=cifs-mounts.service mount-charm.service
Service Dependency Chain⚓︎
- System boot begins
- Network services initialize
- Tailscale establishes connection
- cifs-mounts.service mounts network shares
- mount-charm.service mounts squashfs file
- Docker starts
- Docker containers launch with access to mounted filesystems
Initial Setup Instructions⚓︎
Create Required Directories⚓︎
Create Credentials File⚓︎
Add your credentials in this format:
Then set proper permissions:
Create Mount Script⚓︎
Add this content to the script:
#!/bin/bash
# Wait for Tailscale
sleep 30
# Mount shares
/bin/mount -t cifs //100.122.167.110/Files /mnt/Backup -o credentials=/etc/samba/credentials,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,iocharset=utf8
/bin/mount -t cifs //100.122.167.110/Plex /mnt/Plex -o credentials=/etc/samba/credentials,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,iocharset=utf8
/bin/mount -t cifs //100.122.167.110/Files/minio /mnt/Minio -o credentials=/etc/samba/credentials,uid=1001,gid=1001,file_mode=0775,dir_mode=0775,iocharset=utf8
Make the script executable:
Create Systemd Services⚓︎
Add this content:
[Unit]
Description=Mount CIFS shares
After=network-online.target tailscaled.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/mount-shares.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Create the charm mount service:
Add this content:
[Unit]
Description=Mount charm.li squashfs file
After=network.target remote-fs.target cifs-mounts.service
Requires=cifs-mounts.service
RequiresMountsFor=/mnt/Backup
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/bin/sleep 5
ExecStart=/bin/bash -c 'if ! mountpoint -q /mnt/Backup/operation-charm/lmdb-pages; then mount -o loop -t squashfs /mnt/Backup/operation-charm/lmdb-pages.sqsh /mnt/Backup/operation-charm/lmdb-pages; fi'
ExecStop=/bin/bash -c 'if mountpoint -q /mnt/Backup/operation-charm/lmdb-pages; then umount /mnt/Backup/operation-charm/lmdb-pages; fi'
[Install]
WantedBy=multi-user.target
Create Docker override directory and file:
sudo mkdir -p /etc/systemd/system/docker.service.d/
sudo nano /etc/systemd/system/docker.service.d/wait-for-mounts.conf
Add this content:
[Unit]
After=cifs-mounts.service mount-charm.service
Requires=cifs-mounts.service mount-charm.service
Enable and Start Services⚓︎
sudo systemctl daemon-reload
sudo systemctl enable cifs-mounts.service
sudo systemctl enable mount-charm.service
sudo systemctl restart docker
Maintenance Tasks⚓︎
Adding a New Share⚓︎
- Create the mount point:
sudo mkdir -p /mnt/NewShare -
Add the mount command to the script:
-
Test mount:
sudo systemctl restart cifs-mounts.service
Updating Credentials⚓︎
- Edit credentials file:
sudo nano /etc/samba/credentials - Remount shares:
sudo systemctl restart cifs-mounts.service
Adding Service Dependencies⚓︎
If you have a service that needs to wait for mounts:
sudo mkdir -p /etc/systemd/system/myservice.service.d/
sudo nano /etc/systemd/system/myservice.service.d/wait-for-mounts.conf
Add:
Troubleshooting⚓︎
Checking Mount Status⚓︎
# List all mounts
mount | grep cifs
# Check if specific mount point is mounted
mountpoint -q /mnt/Backup && echo "Mounted" || echo "Not mounted"
# List all block devices
lsblk
Service Logs and Status⚓︎
# View CIFS mounts service logs
journalctl -u cifs-mounts.service
# View service status
systemctl status cifs-mounts.service
systemctl status mount-charm.service
# View service dependencies
systemctl list-dependencies cifs-mounts.service
Common Issues and Solutions⚓︎
Mounts Not Working After Boot⚓︎
- Check if Tailscale is running:
systemctl status tailscaled - Verify network connectivity:
ping 100.122.167.110 - Check service logs:
journalctl -u cifs-mounts.service
Permission Issues⚓︎
- Verify UID/GID in mount options match your user:
id - Check credentials file permissions:
ls -la /etc/samba/credentials - Test manual mount with verbose output:
mount -v -t cifs //100.122.167.110/Files /mnt/Backup -o credentials=/etc/samba/credentials
Docker Containers Can't Access Mounts⚓︎
- Verify Docker started after mounts:
systemctl show -p After docker.service - Check mount ownership:
ls -la /mnt/ - Check if container user has correct permissions
Security Considerations⚓︎
- Credentials file is protected with 600 permissions (root only)
- Mount options specify explicit file/directory permissions
- Tailscale provides encrypted tunnel for CIFS traffic
- Different UID/GID can be set per mount point for isolation
Backup and Recovery⚓︎
- Keep a backup of all configuration files:
- /usr/local/bin/mount-shares.sh
- /etc/systemd/system/cifs-mounts.service
- /etc/systemd/system/mount-charm.service
- /etc/systemd/system/docker.service.d/wait-for-mounts.conf