After several years with Google Chrome and the Vivaldi browser, I am currently testing whether I can get along with Firefox. Firefox offers significantly better ways to protect your own data. It also seems to be a little better integrated under Linux than Vivaldi. But I do not want to go into more detail about that in this blog post. Instead, this is about how to synchronize settings across multiple browsers while keeping the actual data on your own servers.
Firefox lets you use an account to store all your browser settings in Mozilla's cloud. This is not a new feature. Almost every current browser now has the option to store bookmarks, settings, extensions, and so on on a central server. This is handy if you use several devices—a workstation, laptop, and mobile device. Anyone who takes a more critical view of their data and thinks about where they store it and whom they trust may want to keep control of it themselves. Personally, I have no problem storing my bookmarks in some cloud. However, I would like to spread my data out a little more so that no single provider holds all of it. If it works, though, I am happy to store the data in my own network at home.
Mozilla offers two important components as open source:
- Firefox Account Server, the account server for Mozilla's single sign-on service.
- Sync server for the actual data
In practice, this means that you log in through the account server and synchronize your data through the sync server. As a first step, I set up a sync server. We will see... perhaps I will also set up an account server so that I have control over the login itself as well.
Docker Image
Since my infrastructure is built with Docker, I first looked for an official Docker image. And sure enough, there is one on Docker Hub.
https://hub.docker.com/r/mozilla/syncserver
Unfortunately, the official image uses Sqlite as its database backend. Since Sqlite is not designed for multi-user operation, I decided to switch the database backend to Postgres. This works by installing the Python library psycopg2. The base image is Alpine Linux with an old Python 2.7. For psycopg2 to compile correctly when building the image, the postgresql-dev package also needs to be installed. If you want to use sqlite, you can simply use the official mozilla/syncserver Docker image. It is also possible to use MySQL as the database backend. However, I have a central Postgres server running and wanted to use it for this.
The Dockerfile then looks like this:
FROM mozilla/syncserver
USER root
RUN apk add --no-cache postgresql-dev && \
pip install psycopg2
USER 1000
Network / Traefik Configuration
Of course, the whole thing also needs to be reachable from outside somehow. I use a Traefik server in my network.
My project's docker-compose.yml looks like this:
version: '3.7' services: mozilla-sync: container_name: mozilla-sync build: . env_file: - syncserver.env restart: always labels: - "com.centurylinklabs.watchtower.enable=false" - "traefik.enable=true" - "traefik.http.routers.mozilla-sync.rule=Host(`<your-public-domain>`)" - "traefik.http.routers.mozilla-sync.tls=true" - "traefik.http.routers.mozilla-sync.tls.certresolver=letsencrypt" - "traefik.http.routers.mozilla-sync.entrypoints=https" - "traefik.http.services.mozilla-sync.loadbalancer.server.port=4500"
I moved the environment variables into the syncserver.env file:
SYNCSERVER_PUBLIC_URL=https://<your-public-server-url> SYNCSERVER_SECRET=<your-secret-for-encryption> SYNCSERVER_SQLURI=postgresql://<db-user>:<db-pass>@<db-host>/<db> SYNCSERVER_BATCH_UPLOAD_ENABLED=true SYNCSERVER_FORCE_WSGI_ENVIRON=true # nach erstem Sync die Variable wieder auf "false" setzen und Container mit "docker-compose up -d" neu erstellen SYNCSERVER_ALLOW_NEW_USER=true PORT=4500
After the first sync, set the variable back to "false" and recreate the container with "docker-compose up -d", as noted in the comment.
Simply replace the placeholders for the database details with your own and, of course, enter the domain exposed by the Traefik server as the public URL.
If everything is running, you should see these tables in your database:
If the database connection fails, you will see that in the container's log.
Browser Settings
Desktop
To make your Firefox browser use the new sync server, you need to configure it through about:config.
Search for identity.sync.tokenserver.uri, then enter your sync server's public URL and the path to the token endpoint.
Android
On Android, it is similar but a little more complicated. To enter the sync server, you must not be logged into Mozilla. So log out first.
Then go to "About Firefox" in the settings and tap the Firefox logo 5 times in a row.
After that, an option for entering the sync server appears in the settings. Enter the same URL there.
Firefox for Android - Sync server settings
Now log in, and synchronization should work.
Troubleshooting
If synchronization does not work, you can open the URL about:sync-log in desktop Firefox and look at the log files there. I initially got 404 messages myself because my URL was missing "/token".
Deleting Existing Data at Mozilla
If you have already used Mozilla's official sync server, you may want to delete your existing data after setting up your own server.
The sync server includes a small script you can run for this.
I ran the script as follows:
docker-compose exec mozilla-sync python bin/delete_user_data.py <firefox account email>
After running it, you will be asked for your login password. Enter it and confirm. After that, the data on the Mozilla server should be deleted, and you will have control over your own data.

