Setup a Firefox Sync Server with nginx and systemd

2 minute read

I needed a way to synchronize my bookmarks in Firefox across three computers, and doing it manually wasn’t an option anymore, so I turned to sync-like extensions. I needed something which would give me full control on the data storage part (I don’t want to use their servers). The first one I tried was Xmarks, which just can’t handle the 4MB bookmarks I have, so that was a dead end. Then I realized you can host your own Firefox Sync Server and that’s how I did it.

Update: I adopted and fixed the PKGBUILD in the AUR, so you can now skip most of the content in this post and just install the package available there.

Old post (partially outdated)

This setup is inspired from the PKGBUILD for mozilla-firefox-sync-server-hg in AUR. First I created a user and its group in order to confine the server, its files and database:

$ sudo useradd -Ums /bin/false ffsync
$ sudo usermod -aG ffsync tim

Then I installed some dependencies:

$ sudo pacman -S python2-virtualenv sqlite3

And I built the server in the ffsync home directory:

$ sudo -u ffsync bash
$ cd && hg clone https://hg.mozilla.org/services/server-full
$ cp -r server-full server-full-build && cd server-full-build
$ make build VIRTUALENV=virtualenv2

As I use nginx, I installed the recommended gunicorn python server and did the cleanup:

$ bin/easy_install gunicorn
$ find . -name '*.pyc' -delete
$ rm -rf .hg

You need to change the development.ini file like this to enable gunicorn:

1
2
3
4
5
[server:main]
use = egg:gunicorn#main
host = unix:/var/run/ffsync/syncserver.sock
use_threadpool = True
threadpool_workers = 60

Also, don’t forget to tweak the etc/sync.conf config file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[storage]
backend = syncstorage.storage.sql.SQLStorage
sqluri = sqlite:////home/ffsync/sync_storage.db
[...]
quota_size = 102400
[...]

[auth]
backend = services.user.sql.SQLUser
sqluri = sqlite:////home/ffsync/sync_storage.db
[...]

[nodes]
# You must set this to your client-visible server URL.
fallback_node = https://example.com/ffsync/

Here is an extract from my nginx.conf:

        # Firefox sync config
        location /ffsync/ {
            rewrite  ^/ffsync(.+)$ $1 break;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://unix:/var/run/ffsync/syncserver.sock;
        }

And here is the systemd service unit file to run the Sync Server with a confined user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=A gunicorn server running Mozilla's Firefox sync server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
User=ffsync
Group=http
Umask=007
Restart=on-abort
ExecStart=/home/ffsync/server-full-build/bin/gunicorn_paster /home/ffsync/server-full-build/development.ini

[Install]
WantedBy=multi-user.target

And the /etc/tmpfiles.d/ffsync.conf file to make sure the /var/run/ffsync/ folder gets created on boot-up:

D /var/run/ffsync 0750 ffsync http

References:

Updated:

Comments


Comments are disabled on this blog but feel free to start a discussion with me on Mastodon.
You can also contact me directly if you have feedback.