Using Firefox Sync Server with Nginx


Recently, I tried to install the Sync Server on a NgInx server but the big Internet could not help me much, so I decided to write this blog entry in an attempt to complete the official documentation.

For those who don’t know, the Sync Server provides passwords, bookmarks and sessions synchronisation features between multiple running Firefox’s instances. In the past, I used other alternatives, such as SyncPlaces, but the lack of integration within Firefox finally pushed me away from this solution.

Setting up Firefox to use Mozilla Foundation’s Sync Server (i.e. as a client) is pretty straightforward and if you don’t mind being dependent of the Mozilla foundation, you might choose to upload your data to their server. Privacy should not be to much of a concern as they (supposedely) encode your personnal information before transfering it to the server. Still, if, like me, you decide to have your own Sync Server (say, for the sake of being independent) you can do so as it is open source. A first version of the Sync Server was in PHP, but thanks to Tarek Ziade a Python server now also exists. Today, only the Python version of the server will be of interest to us.

As I said in the intro, I found out that setting up the Sync Server using NgInx (and Gunicorn) can be tricky, especially when you are new to the tools (as I am).

In a way, you can see this page as a complement to the excellent Sync Server documentation.

So, let’s get started!

First, you need to download the Sync Server:

hg clone sync-server
cd sync-server
make build

In order to complete our installation with some important tools, you may want to type in the following command:

./bin/pip install -U -i gunicorn
./bin/pip install -U -i pysqlite
./bin/pip install -U -i pastedeploy

These three commands will respectively install gunicorn (the Web Server Gateway Interface HTTP server we want to combine with Nginx), pysqlite (lightweight SQL database) and pastedeploy.

Now, let’s take a look at the configuration files. In the developpement.ini file, modify the server:main block so it looks like this:

use = egg:gunicorn#main
host = unix:syncserver.sock
use_threadpool = True
threadpool_workers = 60

This configuration will enable gunicorn to listen on the syncserver.sock socket file. You may want you syncserver.sock to be only read/write accessible to your NgInx server, either by relaxing the permission on the file, or by starting the gunicorn_paster with the same group as your Nginx server.

That’s it, this part is done. You can check that everything is in order by starting the Sync server. In the Sync server source directory, type the following:

./bin/gunicorn_paster development.ini

It should output something similar to this:

2012-02-27 23:19:11 [16626] [INFO] Starting gunicorn 0.13.4
2012-02-27 23:19:11,623 INFO  [gunicorn.error] Starting gunicorn 0.13.4
2012-02-27 23:19:11 [16626] [INFO] Listening at: unix:syncserver.sock (16626)
2012-02-27 23:19:11,626 INFO  [gunicorn.error] Listening at: unix:syncserver.sock (16626)
2012-02-27 23:19:11 [16626] [INFO] Using worker: sync
2012-02-27 23:19:11,626 INFO  [gunicorn.error] Using worker: sync
2012-02-27 23:19:11 [16640] [INFO] Booting worker with pid: 16640
2012-02-27 23:19:11,629 INFO  [gunicorn.error] Booting worker with pid: 16640

On the NgInx side:

# ... omitted for the sake of brievty ...

http {

	# ... omitted for the sake of brievty ...

	location /sync/ {
			rewrite  ^/sync(.+)$ $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:/fullpathtoyour/syncserver.sock;

	# ... omitted for the sake of brievty ...

Here you can witness some “rewrite” wizardery. I use it because we do not want your sync server to sit on the root of my website. If you want to use the sync server directly at the root of your website, you can remove it.

If you want to automate when the server starts, you could easily make a script out of it. I choose not too, so I won’t document that aspect. However, if you write one, I’ll be interested in knowing which solution you choose.

That’s it for today.