Self-hosting Firefox sync 1.5

Posted on January 11, 2015 in Selfhosting • 4 min read

I used to self-host Firefox Sync but since the new Firefox Accounts + Firefox Sync (appeared in Firefox 29), it has became more difficult to self-host it, and I didn’t take time to handle it. However, lately, the doc has greatly improved and it’s rather straightforward. Although, most of the doc available (for Firefox Accounts mostly) is mainly oriented toward dev and testing rather than setting a production ready instance. So, I will try to describe as best as I can the different steps I took to get a working setup.

Please refer at any time to the README file in the cloned repo, which contains very useful information that may be missing in this article. Please report me also any such information, so that I can keep an up-to-date comprehensive guide on this installation.

As said before, there are now two components that are needed for the sync server. The first one is the sync server itself, written in Python, as it already used to be in the past. The new one is the Firefox Account instance, written in Node, which is used as a common authentication mechanism for all the Mozilla services like Sync, Firefox Marketplace, Firefox’s find-my-device, etc.

It is optional to self-host the Firefox accounts part, and you can rely on the Mozilla servers if you want. They will only do the authentication part, and their server will never handle your plaintext password, so that they cannot in any case decrypt your data, as explained here. This is a good compromise if you want a quick and easy running solution.

At the beginning, I was planning on selfhosting everything for myself. But the Firefox Accounts part is really tricky to set, and you should know that no official Mozilla server will be able to handle authentification against a non-Mozilla Firefox Accounts server. This means that if you use your own Firefox Accounts server, it can be used for Sync (and for FindMyDevice if you have a FirefoxOS phone and tweak a bit), but not for the Marketplace or so. So I decided it was not worth the energy and time passed to update it and keep track of security updates and selfhost only the Firefox Sync part.

Firefox sync server

Actually, the doc is really good for this part and you should just read the official instructions. A french doc is available on dattaz’s blog.

For further configuration, the syncserver.ini file is well commented and the comments should be self-explanatory.

Firefox Accounts server

To self-host this component, you will need node and npm. Firefox Account itself is split in multiple components: an auth server, a database backend and a content server to serve the interface. We will install all the firefox accounts part in /home/fxa. The official doc is available here.

Firefox Accounts authentication server

Let us first focus on the authentication server and its database backend. First step is to install the necessary stuff: node, npm, pgrep, libgmp-dev and mysql (or mariadb). The train-NN branches are kind of tagged versions, and you should git checkout the latest, which is 27 as of writing this article.

cd /home/fxa
git clone git clone git://
git checkout train-27
cd fxa-auth-server
npm install

This will clone and install the auth-server. Then, let’s clone the database backend as well:

cd /home/fxa
git clone
cd fxa-auth-db-server
npm install

In fxa-auth-db-server/, you will have to edit your database credentials. Edit (or create) the file .fxa_dbrc and put the following content inside:

    "master": {
        "user": "fxa",
        "password": "mysecret",
        "database": "fxa"
    "slave": {
        "user": "fxa",
        "password": "mysecret",
        "database": "fxa"

Where fxa is a previously created user in MySQL, with restricted rights and full rights over a database fxa, and mysecret is its password.

Then, we will create a new user to handle firefox account stuff, fxa and give him rights on the previously created repos:

useradd --home /home/fxa fxa
chown -R fxa:fxa /home/fxa
su fxa

Let us initialize the database with

NODE_ENV=prod node bin/db_patcher.js

and the server keys with

cd ../fxa-auth-server
NODE_ENV=prod node ./scripts/gen_keys.js

Let us customize the configuration:

cd config
cp dev.json prod.json
vim prod.json

(there is basically not much to do, except tweaking the smtp settings)

Firefox Accounts content server

First, let us clone the repo:

cd /home/fxa
git clone
chown -R fxa:fxa fxa-content-server
cd fxa-content-server

Then, checkout the last version, using git tags. As of writing this article, it is git checkout v0.27.0. The tagged versions of the content server should be in sync with the train-NN branches in the auth-server, and you should clone the same version number for the two of them (at least as of writing this article). Install the dependencies with npm install.

Customize the config. In server/config/production.json, add (change what has to be changed):

    "EXISTING_KEY": "…",
    "client_sessions": {
        "cookie_name": "session",
        "secret": "YOU MUST CHANGE ME",
        "duration": 86400000

Note: The README file says that this should go in .fxa_dbrc file. But it is not yet supported and the doc is not right on this point, cf this issue. This might however change in the near future. Have a look.

Finally, run grunt server:dist to build production resources (will take some time) and run a local server on port 3030 with production resources.

Launch all the stuff

Ideally, this should be run in a screen (or as daemons) with less privileged user (such as the previous fxa user).

screen -S fxa
cd ~fxa/fxa-auth-db-server
NODE_ENV=prod; npm start
# (new window)
cd ~fxa/fxa-auth-server
NODE_ENV=prod; node ./test/mail_helper.js
# (new window)
export NODE_ENV=prod; node ./bin/key_server.js | node ./bin/notifier.js >/dev/null
# (new window)
cd ~fxa/fxa-content-server
grunt server:dist

You can head to your_ip:3030 to create a Firefox Account. You may want to setup an Apache proxy to serve it, but this is not covered in this guide. For the last settings in Firefox, I let you have a look at the official doc.

Of course, you can run it behind an Apache proxy, or do more advanced configuration. However, as I am not using it and considered useless to spend much time configuring it, I did not look at these parts.