R
G

Back to list2024-270

Syncthing Discovery Service on Alpine Linux

Seldom have I come across a tool as useful, reliable and long lasting as Syncthing. If you never heard of it or tried it yourself take a look.

It's a great way to keep files of all shapes and sized synced across your mutliple devices without the need for any central point. The data never leaves the devices you trust and they are reliably transmitted across the available networks.

It works very easily out of the box and doesn't require much configuration at all.

However it's a complete open source based stack. Part of Syncthing's protocol is a discovery mechanism implemented by stdiscsrv. Having your own such service isn't strictly required but can be quite useful for using syncthing in more restrictive environments (e.g. no internet connection) or just to improve overall security and privacy by not using the global discovery services.

About the setup

I'm using a minimal LXC container managed by Proxmox to set this up. Relying on Alpine Linux provides the benefit of having an extremely small footprint. My discovery service containers crack just above 50 MB of disk space used and I've completely overdone RAM by assigning it 256MB.

That's why I chose Alpine in the first place.

Docker containers exist but Docker isn't my preferred weapon of chocie and I apreciate the atomic nature of the proxmox LXC setup as well as the ease of moving these services around the cluster.

Deploy stdiscosrv on Alpine Linux

The hands on part is extremely simple. After initializing your container run:

# Install syncthing-utils (syncthing is not required)
apk add syncthing-utils

# Setting user and group for the service
USER=syncthing-disco
GROUP=syncthing-disco

# Adding service user and group
addgroup -S $GROUP
adduser -h /var/lib/syncthing-disco/ -H -D -S -s /sbin/nologin -G $GROUP $USER -g "Syncthing Discovery Service"

# Initialize service directories for runtime data and logging
mkdir -p /var/lib/syncthing-disco/ /var/log/syncthing-disco
mkdir -p /var/lib/syncthing-disco/certs
chown syncthing-disco:syncthing-disco /var/lib/syncthing-disco/ /var/log/syncthing-disco
chmod 750 -R /var/lib/syncthing-disco/ /var/log/syncthing-disco

# Prepare the init script and it's config
touch /etc/init.d/stdiscosrv /etc/conf.d/stdiscosrv 
chmod 755 /etc/init.d/stdiscosrv
chmod 644 /etc/conf.d/stdiscosrv 

#################################################
# FIXME: Find a way to place your own certificats:
cp <YOUR_SSL_CERT.pem> /var/lib/syncthing-disco/certs/
cp <YOUR_SSL_KEY.pem>  /var/lib/syncthing-disco/certs/
#################################################

# Set permissions for the service
chown -R $USER:$GROUP /var/lib/syncthing-disco/ /var/log/syncthing-disco

# Define the service config
echo "# Configuration for /etc/init.d/stdiscosrv

# Service user/group
user=syncthing-disco
group=syncthing-disco

# Root path to stdiscosrv data (e.g. discovery.db)
data_root_dir=/var/lib/syncthing-disco
log_root_dir=/var/log/syncthing-disco

# HTTPS config
cert_path=/var/lib/syncthing-disco/certs/cert.pem
key_path=/var/lib/syncthing-disco/certs/privkey.pem
listen=:8443" > /etc/conf.d/stdiscosrv

# Define the init script needed to start / stop the service and make it
# part of the boot process
echo '#!/sbin/openrc-run

# Description of the service
name=$RC_SVCNAME
description="Syncthing Discovery Server $cert_path"
description_checkconfig="Verify configuration file"
description_reload="Reload configuration"

# Define the command that starts the discovery server
command="/usr/bin/stdiscosrv"

# Optional: specify additional arguments for the command
command_args="--cert=$cert_path --key=$key_path --db-dir=$data_root_dir/discovery.db"

output_log="$log_root_dir/service.log"
error_log="$log_root_dir/error.log"

# Optional: specify the user to run the service
command_user="$user:$group"

# PID file location
pidfile="/var/run/$RC_SVCNAME.pid"

command_background=yes

depend() {
    # Specify service dependencies here
    need net
    after firewall
}

start_pre() {
    # Ensure necessary directories exist
    checkpath --directory --owner $user:$group $data_root_dir $log_root_dir
}' > /etc/init.d/stdiscosrv

# Add the process ot the default target
rc-update add stdiscosrv default

# Start the service
rc-service stdiscosrv start

The SSL part may be a bit tricky. I have my ways to push the certs needed into place but that's not a copy/paste solution for you.

Note that the config is flexible about the location of those certificates. So no need to copy them if you have another way to handle certificates.

Have fun :)