How to Install Firefox Sync Server on Debian 11 – Set Up Your Own Sync Hub
If you’ve ever wanted a private place to keep your bookmarks, passwords, and open tabs in sync across devices without letting Mozilla hold the keys, this is how to spin up the official sync server on Debian 11. I’ll walk you through the bits you actually need to know and warn you where the road trips usually take a detour.
1. Get Your System Ready
Debian’s stock repositories don’t ship the freshest copy of Firefox Sync, so we’ll pull from Mozilla’s own build. First, make sure your OS is up‑to‑date:
sudo apt update && sudo apt upgrade -y
the sync server relies on a handful of newer libraries (especially libssl3 and libpq5). If you skip the upgrade, you’ll hit “cannot find dependency” later.
Create a dedicated user for the service. Running it as root is a no‑no:
sudo adduser --disabled-login syncsrv
Give that user a home directory; the config files will live there. I’ve run into permission headaches before when the service tried to write to /var/lib without rights.
2. Install Dependencies
The sync server is written in Rust and requires a couple of runtime libraries:
sudo apt install -y \
libssl3 \
libpq5 \
postgresql-client \
python3-certbot-nginx
If you’re planning to use PostgreSQL locally (highly recommended), the client package will be handy for creating the initial database. The certbot‑nginx pair is what we’ll use later for SSL, so install it now even if you only plan to test on HTTP.
3. Pull the Source or Binary
The easiest way to get a working binary is to grab the pre‑built release from GitHub:
cd ~syncsrv curl -L https://github.com/mozilla-services/sync-server/releases/download/v1.4.0/sync-server-v1.4.0-linux-amd64.tar.gz | tar xzf -
Replace v1.4.0 with the latest tag if that’s what you want. Unpacking into the user’s home keeps everything tidy.
Alternatively, if you’re comfortable compiling:
sudo apt install -y cargo build-essential cargo build --release
But for most users a pre‑built binary is faster and less likely to trip over compiler versions on Debian 11.
4. Set Up the PostgreSQL Database
Create a database user and schema that sync will use:
sudo -u postgres psql <<EOF CREATE USER syncdb WITH PASSWORD 'changeme'; CREATE DATABASE syncdb OWNER syncdb; \q EOF
Now run the migration script included with the server to set up tables:
./sync-server-migrate --db-url "postgresql://syncdb:changeme@localhost/syncdb"
If you see an error about “database does not exist,” double‑check that you’re pointing at the right host and port. I once forgot to expose PostgreSQL on localhost, which caused a cryptic connection timeout.
5. Configure the Service
Create /etc/systemd/system/syncsrv.service with:
[Unit] Description=Firefox Sync Server After=network.target [Service] User=syncsrv WorkingDirectory=/home/syncsrv/ ExecStart=/home/syncsrv/sync-server-v1.4.0-linux-amd64/sync-server --config /home/syncsrv/config.toml Restart=on-failure [Install] WantedBy=multi-user.target
The --config flag points to a TOML file we’ll generate next.
6. Write the Config File
In /home/syncsrv/config.toml, paste:
# Basic network settings
listen = "0.0.0.0:443"
# Database connection string
database-url = "postgresql://syncdb:changeme@localhost/syncdb"
# Optional TLS (will be overridden by Nginx)
tls-cert-file = "/etc/ssl/certs/fullchain.pem"
tls-key-file = "/etc/ssl/private/privkey.pem"
[services]
accounts = { enabled = true }
search = { enabled = false } # optional, not needed for basic sync
Explaination: listen binds to all interfaces on port 443 so we can front‑gate with Nginx later. The TLS paths are placeholders; you’ll generate them with Certbot.
7. Install and Configure Nginx + Certbot
sudo apt install -y nginx
Create an Nginx virtual host:
server {
listen 80;
server_name sync.example.com;
location /.well-known/acme-challenge/ { root /var/www/certbot; }
}
server {
listen 443 ssl;
server_name sync.example.com;
ssl_certificate /etc/letsencrypt/live/sync.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sync.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:443;
proxy_set_header Host $host;
proxy_ssl_verify off; # because sync runs TLS internally
}
}
Run Certbot to fetch a cert:
sudo certbot --nginx -d sync.example.com
If the domain is local or you’re just testing, skip this step and use a self‑signed cert.
8. Start Everything
sudo systemctl daemon-reload sudo systemctl enable syncsrv sudo systemctl start syncsrv systemctl status syncsrv
You should see “Active: active (running)”. If it’s stuck in a failure loop, check /var/log/syslog for the error; often it’s a mis‑typed database URL.
9. Test It
Open Firefox on any machine and go to about:preferences#sync. In the Add account dialog, choose “Use a private server” and point it at https://sync.example.com. If everything is wired correctly, you’ll be prompted for the sync password you set up when creating an account (the sync‑server CLI has a helper to generate that). Once logged in, try opening a bookmark on one device and watch it appear on another.
If you hit “connection refused” or “certificate not trusted,” double‑check the Nginx config and TLS paths. The most common hiccup I see is forgetting to reload Nginx after certbot updates:
sudo systemctl reload nginx
10. Keep It Running
Set up automatic certificate renewal with Certbot’s timer (it usually installs one by default). For the sync service, systemd already restarts on failure, but you can add a watchdog or monitor log tailing if you’re running it in production.
That’s it—your own Firefox Sync server is now humming quietly behind your firewall. The next step? Harden the PostgreSQL user permissions and maybe sprinkle some reverse‑proxy auth (like HTTP basic) to keep the sync endpoint out of sight from casual browsers.
Happy syncing, and remember: keeping your data under your control is a bit like having an extra set of keys—use it wisely!