EteSync Server

EteSync is a secure, end-to-end encrypted, and privacy respecting sync for your contacts, calendars and tasks. You can set up your own EteSync Server to sync all your devices. It is written in Python and based on the popular Django-Framework.


For this guide you should be familiar with the basic concepts of


All relevant legal information can be found here:


Your URL needs to be set up:

[isabell@stardust ~]$ uberspace web domain list
[isabell@stardust ~]$

Install uWSGI

Install the required uwsgi package with pip.

[isabell@stardust ~]$ pip3.6 install uwsgi --user
[isabell@stardust ~]$

After that, continue with setting it up as a service.

Create ~/etc/services.d/uwsgi.ini with the following content:

command=uwsgi --master --emperor %(ENV_HOME)s/uwsgi/apps-enabled
stderr_logfile = ~/uwsgi/err.log
stdout_logfile = ~/uwsgi/out.log

Create needed folders and files for uwsgi:

[isabell@stardust ~]$ mkdir -p ~/uwsgi/apps-enabled
[isabell@stardust ~]$ touch ~/uwsgi/err.log
[isabell@stardust ~]$ touch ~/uwsgi/out.log
[isabell@stardust ~]$

Tell supervisord to refresh its configuration and start the service:

[isabell@stardust ~]$ supervisorctl reread
uwsgi: available
[isabell@stardust ~]$ supervisorctl update
uwsgi: added process group
[isabell@stardust ~]$ supervisorctl status
uwsgi                            RUNNING   pid 26020, uptime 0:03:14
[isabell@stardust ~]$

If it’s not in state RUNNING, check your configuration.


Step 1

Clone the source code from Github to ~/etesync_server. Make sure to replace the release number v0.3.0 in the command with the latest release which can be found at the release page on GitHub:

[isabell@stardust ~]$ git clone --branch v0.3.0 ~/etesync_server
[isabell@stardust ~]$

Step 2

Install the requirements for EteSync Server:

[isabell@stardust ~]$ cd ~/etesync_server
[isabell@stardust etesync_server]$ pip3.6 install -r requirements.txt --user
[isabell@stardust etesync_server]$ pip3.6 install mysqlclient --user
[isabell@stardust etesync_server]$

Step 3

Install the static files:

[isabell@stardust etesync_server]$ mkdir /var/www/virtual/$USER/html/static/
[isabell@stardust etesync_server]$ ln -s /var/www/virtual/$USER/html/static/
[isabell@stardust etesync_server]$ python3.6 collectstatic

152 static files copied to '/home/isabell/etesync_server/static'.
[isabell@stardust etesync_server]$

Step 4: Basic configuration

Create the file ~/etesync_server/ and add the following line (replace isabell with your own username and MySuperSecretPassword with your actual MySQL password):


  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'isabell_etesync_server',
    'USER': 'isabell',
    'PASSWORD': 'MySuperSecretPassword',
    'HOST': '',
    'PORT': '3306',

Step 5: Database setup

Create a database:

[isabell@stardust etesync_server]$ mysql -e "CREATE DATABASE ${USER}_etesync_server DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;"
[isabell@stardust etesync_server]$

Apply database migrations:

[isabell@stardust etesync_server]$ python3.6 migrate
[isabell@stardust etesync_server]$

Step 6: Security configuration

Perform a Django deployment check, which will give some configuration recommendations:

[isabell@stardust etesync_server]$ python3.6 check --deploy
System check identified some issues:

[isabell@stardust etesync_server]$

Open ~/etesync_server/ again and add the recommended configuration at the end:

# Django deployment check recommendations

Perform the check again to make sure all warnings have been resolved:

[isabell@stardust etesync_server]$ python3.6 check --deploy
System check identified no issues (0 silenced).
[isabell@stardust etesync_server]$

Step 7: Web backend configuration


EteSync server is running on port 8000 in the default configuration.

To make the application accessible from the outside, configure a web backend:

[isabell@stardust ~]$ uberspace web backend set / --http --port <port>
Set backend for / to port <port>; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[isabell@stardust ~]$

And for the static files:

[isabell@stardust ~]$ uberspace web backend set --apache /static
Set backend for /static to apache.
[isabell@stardust ~]$

Step 8: Daemon setup

To deploy your application with uwsgi, create a file at ~/uwsgi/apps-enabled/etesync_server.ini with the following content:

chdir = $(HOME)/etesync_server
base = %(chdir)/etesync_server

http = :8000
master = true
wsgi-file = %(base)/
touch-reload = %(wsgi-file)
static-map = /static=%(base)/static

app = wsgi

plugin = python

Restart uwsgi:

[isabell@stardust ~]$ supervisorctl restart uwsgi
uwsgi: stopped
uwsgi: started
[isabell@stardust ~]$

Step 9: Test your installation

Perform a CURL request to your URL (e.g. to see if your installation succeeded:

[isabell@stardust ~]$ curl -I
HTTP/2 200
[isabell@stardust ~]$

If you don’t see HTTP/2 200 check your installation.


First, you have to create an admin user:


Set your own username, email and password (twice). Select a secure password which differs from the password used for your Uberspace account.

[isabell@stardust ~]$ cd ~/etesync_server
[isabell@stardust etesync_server]$ python3.6 createsuperuser
Username (leave blank to use 'isabell'):
Email address:
Password (again):
Superuser created successfully.
[isabell@stardust etesync_server]$


It is not recommended to use the admin user in daily life (i.e. for syncing data between your devices). So, go to, log in with your admin user credentials and create a separate non-privileged user.

Now you can install the EteSync app on your device(s) and connect to your EteSync server using your URL (e.g. and the non-privileged user’s credentials.


Relevant data to be backed up is the SQL database and the file ~/etesync_server/secret.txt. They both are included in the backups of your whole Uberspace. But since your contacts and calendar data may be too important to loose, consider setting up a separate backup strategy.

To create backups automatically, create a file ~/bin/backup-etesync-server with the following content (replace isabell_etesync_server with your own database name):

#!/usr/bin/env bash

# specify the database name

# create the backup target
BACKUP_DIR="${HOME}/backup/etesync_server/$(date '+%Y-%m-%d')"
mkdir -p "$BACKUP_DIR"

# backup relevant data
cp ${HOME}/etesync_server/secret.txt "$BACKUP_DIR"

Make the file executable:

[isabell@stardust ~]$ chmod +x ~/bin/backup-etesync-server

Set up a cron job by using the crontab -e command and adding the line:

@daily  $HOME/bin/backup-etesync-server


Your backups should be stored at another location outside your Uberspace!


Keep in mind that the data stored by EteSync server is end-to-end encrypted. Therefore, the data from your server backups can not be restored without the encryption password which is not included in the backups, because it only exists on your synchronized devices. Make sure you keep your encryption password in a safe place, too!



Check the release page on GitHub regularly or follow the feed to stay informed about the newest version.

If there is a new version available, update your EteSync server installation to the latest release with git (make sure to replace v0.3.x with the latest version number):

   [isabell@stardust ~]$ cd ~/etesync_server
   [isabell@stardust etesync_server]$ git pull origin v0.3.x
   [isabell@stardust etesync_server]$ pip3.6 install -U -r requirements.txt
   [isabell@stardust etesync_server]$ python3.6 migrate
   [isabell@stardust etesync_server]$ python3.6 collectstatic
   [isabell@stardust etesync_server]$

Tested with EteSync server 0.3.0 and Uberspace

Written by: nepoh <>