How to Self-Host Firefox Sync Using syncstorage-rs
This article provides a step-by-step guide for privacy-conscious
users on how to self-host Mozilla's syncstorage-rs server
and configure the Firefox Web Browser to use this private
infrastructure. By deploying your own sync server using Docker and
MariaDB, and updating a single configuration setting within Firefox, you
can maintain complete control over your browsing history, bookmarks,
passwords, and open tabs without storing your encrypted data on
Mozilla's cloud servers.
Prerequisites
Before deploying the server, ensure you have the following ready:
- A Linux server with Docker and Docker Compose installed.
- A registered domain name (or subdomain) pointing to your server.
- A reverse proxy (such as Nginx, Caddy, or Traefik) configured to handle HTTPS/TLS termination for your domain.
- A Mozilla Account (formerly Firefox Account). Note that this setup self-hosts the data storage, while still using Mozilla's public authentication servers to verify your identity.
Step 1: Prepare the Database
The syncstorage-rs server requires a MySQL or MariaDB
instance with two separate databases: one for storing the actual sync
data (syncstorage) and one for managing authentication
tokens (tokenserver).
Create a project directory on your server:
mkdir firefox-sync && cd firefox-syncCreate an initialization SQL script named init.sql to
automatically build the required databases and permissions when the
database container starts:
CREATE DATABASE IF NOT EXISTS syncstorage_rs;
CREATE DATABASE IF NOT EXISTS tokenserver_rs;
GRANT ALL PRIVILEGES ON syncstorage_rs.* TO 'syncuser'@'%';
GRANT ALL PRIVILEGES ON tokenserver_rs.* TO 'syncuser'@'%';
FLUSH PRIVILEGES;Step 2: Configure Docker Compose
Next, generate two random secrets that the server will use for security. Run the following command twice and save the outputs:
head -c 32 /dev/urandom | base64Create a docker-compose.yml file in your
firefox-sync directory. Replace
your_db_password, your_root_password,
secret_1, secret_2, and
https://sync.yourdomain.com with your actual values.
version: '3.8'
services:
mariadb:
image: mariadb:10.11
container_name: sync-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: your_root_password
MYSQL_USER: syncuser
MYSQL_PASSWORD: your_db_password
volumes:
- ./db_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 3
syncstorage:
image: mozilla/syncstorage-rs:latest
container_name: sync-server
restart: unless-stopped
depends_on:
mariadb:
condition: service_healthy
ports:
- "127.0.0.1:8000:8000"
environment:
SYNC_HOST: 0.0.0.0
SYNC_PORT: 8000
SYNC_HUMAN_LOGS: 1
SYNC_MASTER_SECRET: "secret_1"
SYNC_HASH_SECRET: "secret_2"
SYNC_SYNCSTORAGE__DATABASE_URL: "mysql://syncuser:your_db_password@mariadb:3306/syncstorage_rs"
SYNC_TOKENSERVER__DATABASE_URL: "mysql://syncuser:your_db_password@mariadb:3306/tokenserver_rs"
SYNC_TOKENSERVER__ENABLED: "true"
SYNC_TOKENSERVER__RUN_MIGRATIONS: "true"
SYNC_TOKENSERVER__FXA_EMAIL_DOMAIN: "api.accounts.firefox.com"
SYNC_TOKENSERVER__FXA_OAUTH_SERVER_URL: "https://oauth.accounts.firefox.com"
SYNC_TOKENSERVER__FXA_METRICS_HASH_SECRET: "secret_2"
SYNC_TOKENSERVER__ADDITIONAL_BLOCKING_THREADS_FOR_FXA_REQUESTS: 2Start the containers to initialize the databases and run the migrations:
docker compose up -dStep 3: Register the Node in the Token Server
Even though the server is running, it will reject sync attempts until
you register your domain as an available storage node inside the
tokenserver_rs database.
Run the following command to access the MariaDB container (enter your
MYSQL_ROOT_PASSWORD when prompted):
docker exec -it sync-db mariadb -u root -p tokenserver_rsOnce inside the MariaDB shell, run these two SQL queries. Replace
https://sync.yourdomain.com with your actual HTTPS domain
URL, and set capacity to the maximum number of users you
want this server to support:
INSERT INTO services (id, service, pattern) VALUES (1, 'sync-1.5', '{node}/1.5/{uid}');
INSERT INTO nodes (id, service, node, available, current_load, capacity, downed, backoff)
VALUES (1, 1, 'https://sync.yourdomain.com', 1, 0, 10, 0, 0);
EXIT;Step 4: Configure the Reverse Proxy
The syncstorage-rs container is now listening on
127.0.0.1:8000. Configure your chosen reverse proxy to
route traffic from https://sync.yourdomain.com to
http://127.0.0.1:8000.
Ensure your reverse proxy passes the standard
X-Forwarded-For and X-Forwarded-Proto headers,
and that a valid SSL/TLS certificate (such as one from Let's Encrypt) is
active. Firefox will refuse to sync over an unencrypted HTTP
connection.
You can verify the server is reachable by navigating to
https://sync.yourdomain.com/__heartbeat__ in your browser.
It should return a JSON response indicating the database and server are
healthy.
Step 5: Point Firefox to Your Private Server
With the server operational, you must instruct Firefox to use your private infrastructure instead of Mozilla's default storage servers.
- Open the Firefox Web Browser.
- If you are currently logged into a Mozilla Account in Firefox, sign out first.
- In the address bar, type
about:configand press Enter. - Click Accept the Risk and Continue.
- In the search bar, type
identity.sync.tokenserver.uri. - Click the Edit (pencil) icon next to the preference.
- Replace the default URL with your custom domain, appending
/1.0/sync/1.5to the end. It must look like this:https://sync.yourdomain.com/1.0/sync/1.5 - Click the Save (checkmark) icon.
- Log back into your Mozilla Account in Firefox.
Verification
To confirm that Firefox is utilizing your self-hosted server, type
about:sync-log into the Firefox address bar. If a sync has
occurred, you will see log files listed. Open the most recent log file
and verify that the requests are being sent to
https://sync.yourdomain.com. You can also check the
syncstorage_rs database on your server; the
bso (Basic Storage Object) table will now be populated with
your encrypted browser data. You can repeat Step 5 on any other desktop
or mobile Firefox browser to sync data across all your devices using
your private server.