After switching from Firefox to LibreWolf, I became interested in the idea of self-hosting my own Firefox Sync server. Although I had seen this was possible before, I had never really looked into it—until now. I embarked on a journey to set this up, and while it wasn’t completely smooth sailing, I eventually got it working. Here’s how it went.
Finding the Right Sync Server
Initial Search: Mozilla’s Sync Server Repo
I started by searching for “firefox sync server github” and quickly found Mozilla’s syncserver repo. This is an all-in-one package designed for self-hosting a Firefox Sync server. It bundles both the tokenserver for authentication and syncstorage for storage, which sounded like exactly what I needed.
However, there were two red flags:
- The repository had “failed” tags in the build history.
- A warning was prominently displayed stating that the repository was no longer being maintained and pointing to a new project in Rust.
Switching to Rust: syncstorage-rs
With that in mind, I followed the link to syncstorage-rs, which is a modern, Rust-based version of the original project. It seemed like the more viable option, so I decided to move forward with this one. But first, I wanted to check if there was a ready-to-go Docker image to make deployment easier. Unfortunately, there wasn’t one, but the documentation did mention running it with Docker.
This is where things started to get complicated.
Diving Into Docker: Confusion and Complexity
Documentation Woes
The Docker documentation had some strange parts. For example, it mentioned:
- Ensuring that
grpcio
andprotobuf
versions matched the versions used bygoogle-cloud-rust-raw
. This sounded odd—shouldn’t Docker handle version dependencies automatically? - Another confusing part was the instruction to manually copy the contents of
mozilla-rust-sdk
into the top-level root directory. Again, why wasn’t this step automated in the Dockerfile?
At this point, I was feeling a bit uneasy but decided to push forward. I reviewed the repo, the Dockerfile, the Makefile, and the circleci workflows. Despite all that, I was still unsure how to proceed.
A Simpler Solution: syncstorage-rs-docker
I then stumbled upon dan-r’s syncstorage-rs-docker repo, which had a much simpler Docker setup. The description explained that the author had also encountered issues with the original documentation and decided to create a Docker container for their own infrastructure.
At this point, I felt reassured that I wasn’t alone in my confusion, and decided to give this setup a try.
Setting Up the Server: Docker Compose and MariaDB
Docker Compose Setup
I copied the following services into my docker-compose.yaml
:
firefox_mariadb:
container_name: firefox_mariadb
image: linuxserver/mariadb:10.6.13
volumes:
- /data/ffsync/dbdata:/config
restart: unless-stopped
environment:
MYSQL_DATABASE: syncstorage
MYSQL_USER: sync
MYSQL_PASSWORD: syncpass
MYSQL_ROOT_PASSWORD: rootpass
firefox_syncserver:
container_name: firefox_syncserver
build:
context: /root/ffsync
dockerfile: Dockerfile
args:
BUILDKIT_INLINE_CACHE: 1
restart: unless-stopped
ports:
- "8000:8000"
depends_on:
- firefox_mariadb
environment:
LOGLEVEL: info
SYNC_URL: https://mydomain/sync
SYNC_CAPACITY: 5
SYNC_MASTER_SECRET: mastersecret
METRICS_HASH_SECRET: metricssecret
SYNC_SYNCSTORAGE_DATABASE_URL: mysql://sync:usersync@firefox_mariadb:3306/syncstorage_rs
SYNC_TOKENSERVER_DATABASE_URL: mysql://sync:usersync@firefox_mariadb:3306/tokenserver_rs
A few tips:
- Be cautious with the database passwords. Avoid using special characters like
"/|%"
as they can cause issues during setup. - I added the BUILDKIT_INLINE_CACHE argument to the Docker Compose file to make better use of caching, which reduced build time while testing.
Initializing the Database
I cloned the repository and copied the Dockerfile and initdb.sh
script to my server. After making some tweaks, I ran
the following steps to get the database up and running:
- Bring up the MariaDB container:
docker-compose up -d firefox_mariadb
- Make the initialization script executable and run it:
chmod +x initdb.sh ./initdb.sh
Bringing the Stack Online
Finally, I brought up the entire stack with:
docker-compose up -d
Configuring Reverse Proxy with Caddy
Next, I needed to update my Caddy reverse proxy to point to the new Sync server. I added the following configuration:
mydomain:443 {
reverse_proxy firefox_syncserver:8000 {
}
}
After updating Caddy with the DNS entry, I restarted the proxy and the sync server was up and running.
Challenges Faced
While I eventually got everything working, there were a few notable challenges along the way:
- Database persistence: I had issues with persistent data when restarting the MariaDB container. Make sure to clear out old data if needed.
- Server storage: My server ran out of space during the build process due to the size of the Docker images and intermediate files.
- Following the right steps: It took me a while to figure out the right steps, and much of the time was spent experimenting with the Docker setup.
Final Thoughts
Setting up a self-hosted Firefox Sync server is not the easiest task, especially if you’re not very familiar with Docker
or database management. The official documentation is confusing, but thanks to community efforts like
the syncstorage-rs-docker
repo, it’s doable.
In the end, it took me about two hours to get everything running, but it was worth it. If you’re looking to control your own Firefox Sync server, this guide should help you avoid some of the pitfalls I encountered.
Happy syncing!