Host Your Own EteSync Server
last updated 2020-11-28 08:52:28 by Simon Vandevelde
This guide is outdated, and only here for legacy reasons. If you want the up to date version, you can find it on the EteSync wiki
Hi! Welcome to my guide on self hosting an EteSync server on the Raspberry Pi Zero.
In this guide, we will be using the `Raspbian `_ operating system.
Raspbian is based on Debian, which is an OS known for its stability.
This means that we can setup up the server and have minimal maintenance afterwards.
Next up, we need to install three packages at the start.
All we need to do is copy the file to
A Web Server Gateway Interface - WSGI - does this job. WSGI is a Python standard.
uWSGI is a WSGI implementation. In this tutorial we will set up uWSGI so that it creates a Unix socket, and serves responses to the web server via the uwsgi protocol. At the end, our complete stack of components will look like this:
The file should now look like this.
If we now want to run uWSGI, we do so by using the following command.
We can do the exact same thing for uWSGI, after creating a systemd unit file. Create a new file and paste in the following (don't forget to change):
This unit executes exactlythe same command as we had to do earlier.
By saving this file as
To start and enable the uWSGI unit, do the following.
First, we need to download certbot. To setup SSL for HTTPS, we need to first make sure our server is reachable on HTTP from the outside. To do this, you should port-forward your router to point port 80 and 443 to your pi's local IP address. Next, have your domain name resolve to your external IP address (if you don't know this, check here). Now you should be able to reach your EteSync server using your domain name, followed by
To setup HTTPS, we're going to need a certificate. Thanks to certbot, this is a breeze. All we need to do is install it, and have it run. It should even automatically change our
Hi! Welcome to my guide on self hosting an EteSync server on the Raspberry Pi Zero.
Requirements:
- Computer running a Linux flavour;
- A Raspberry Pi Zero;
- A micro SD card;
- A working internet connection;
- A domain name, unless you want to read it locally;
- The ability to port-forward your router;
- The ability to read.
Setup the Pi.
In the first step, we'll be setting up the Raspberry Pi zero. If your Pi already runs an operating system, you can skip to the next step.In this guide, we will be using the `Raspbian
Download the image
Go to the download url and download the Lite version of Raspbian. The lite version ships without desktop, and is thus only usable through the terminal. If you would like a desktop, download the Raspbian version with desktop.Flash the image
Once the image is downloaded, we can flash it to our SD card. Open up a terminal, and executelsblk
.
Find the name of your micro SD.
If you're not sure which device name belongs to the SD card, unplug it, run lsblk
, plug it in and rerun lsblk
.
The new device that shows up is your SD card.
It is extremely important that you choose the right name.
You could seriously mess up your filesystem!
Next we're going to write the image to the SD.
To do this, navigate to where the Raspbian image is located and execute the following command.
Fill in the name of the image and the name of the /dev/
device.
$ dd bs=4M if=20xxI-xx-xx-raspbian-xx.img of=/dev/sdX conv=fsync progress=status
Setup SSH and WiFi
Now that the image is written, we can almost start the Raspberry Pi. However, it is important that we are able to connect to the Pi afterwards. See this tutorial page to do a headless setup of the WiFi and to enable SSH.Prepare the Pi
Now that we have the image ready, go ahead and stick it in the Pi. It should connect to your network and allow SSH connections. Next we need the Pi's IP address to connect to it. To find out the IP address of your Pi, there are multiple ways. An easy one is to check your router's connected devices. Another one is using the commandarp -a
to list connected devices.
After finding out the IP, SSH to it by using the following command:
$ ssh pi@192.168.x.xThe first thing we need to do is change the password (and preferably the user too!). To change the password, type
passwd
.
To change the user, create a new user like so:
$ sudo useradd -mNow close the ssh connection, and reconnect to the Pi using the new user. After having created a new user, you might want to consider deleting the default Pi user:$ sudo groupadd sudo # Add user to sudo group $ sudo passwd
sudo userdel pi
.
Download install dependencies
Now that we have our own user, we need to update and upgrade the Pi. Do this using the following command.$ sudo apt get update && sudo apt get upgradeNote: this might take a very long time.
Next up, we need to install three packages at the start.
$ sudo apt get install python3-pip git $ pip3 install virtualenv
Setting up the basic server
Clone the server code
First, we need to clone the server code from the GitHub repository. To download the server in your home directory, execute the following commands:$ cd ~ $ git clone blablabla.git $ cd server-skeleton
Create a virtual environment
Before installing our dependencies, we should set up a Python virtual environment. This virtual environment keeps the Python packages we install for the server seperated from our users' packages. More info on this can be sound here. This is technically optional, but I highly recommend it. Setting up a virtual environment is simple. In~/server-skeleton
, simply do the following.
$ virtualenv -p python3 venv $ source venv/bin/activateBy sourcing
venv/bin/activate
, we 'activate' the virtual environment.
Any dependencies now installed, will be installed to the virtual environment instead of our user's environment.
Install dependencies
The server GitHub repo comes with a file calledrequirements.txt
file.
This file contains all the necessary Python requirements for the servercode to run.
Installing them is very simple.
.. code-block:: console
$ pip3 install -r requirements.txt
Create an ini file
The server requires a basic .ini file to run. This file contains some settings for the server. Luckily for us, the the GitHub repo already contains a basic ini calledetesync-server.ini.example
!
All we need to do is copy the file to
etesync-server.ini
and adjust one line.
To do this, run the cp
command.
$ cp etesync-server.ini.example etesync-server.iniAfterwards, open the new ini file in your favorite terminal text editor (for beginners I recommend Nano) and set allowed hosts to "*".
Test the basic server!
Now we need to initialise the server and then we can run it.$ ./manage.py migrate $ ./manage.py runserver 0.0.0.0:8000Now try surfing to the Pi's IP address followed by the portnumber (
192.168.x.x:8000
) in a web browser and check the page.
You should see a webpage saying "It works!".
If not, try to retrace your steps to find out where it went wrong.
3. uWSGI
Context
We can't just run our basic server and expose it to the outside world. Intead, we build a server stack: different layers on top of each other, with each layer talking to a top one and a bottom one. The uWSGI docs say the following: A web server faces the outside world. It can serve files (HTML, images, CSS, etc) directly from the file system. However, it can’t talk directly to Django applications; it needs something that will run the application, feed it requests from web clients (such as browsers) and return responses.A Web Server Gateway Interface - WSGI - does this job. WSGI is a Python standard.
uWSGI is a WSGI implementation. In this tutorial we will set up uWSGI so that it creates a Unix socket, and serves responses to the web server via the uwsgi protocol. At the end, our complete stack of components will look like this:
the web client <-> the web server <-> the socket <-> uwsgi <-> DjangoIn this tutorial, we use uWSGI as WSGI, and Nginx as web server.
Installing uWSGI
Installation of uWSGI is done via Pip. We invoke the installation command as sudo, because the root user needs access to uWSGI later.$ sudo pip3 install uwsgi
Testing uWSGI
We can already test whether or not our uWSGI installation works, by using the following command.$ uwsgi --http :8000 --module etesync_server.wsgi --virtualenv venvThis command will have uWSGI start an EteSync server instance and expose it on port 8000. Check in your webbrowser if you can see the "It works!" again. If not, you should see an error pop up in the terminal to help debugging.
4. Nginx
The final layer of our server stack is Nginx. Nginx will form our proper web server.Installing Nginx
Nginx is installable via the apt.$ sudo apt-get install nginx
Setup Nginx
Next, we have some setup to do. First of all, we're going to create Django's static files, so that Nginx can access these.$ ./manage.py collectstaticAfter creating the static files, we need to create a configuration file for Nginx. Create a new file called
etesync_nginx.conf
and paste in the following configuration.
Don't forget to change the server_name
and fill in the correct path to your static
folder!
Next, we need to move this configuration file to /etc/nginx/sites-available/
and then symlink it to /etc/nginx/sites-enabled
to enable it.
Nginx will start to use the config file after a restart.
If we then run the uWSGI server like before but on port 8001 instead of 8000, you should be able to surf to the same url as before and see "It Works!".
$ sudo cp etesync_nginx.conf /etc/nginx/sites-available/ $ sudo ln -s /etc/nginx/sites-available/etesync_nginx.conf /etc/nginx/sites-enables/etesync_nginx.conf $ systemctl restart nginx $ uwsgi --socket :8001 --module etesync_server.wsgiIf you encounter any errors, check the Nginx log which is located in
/var/log/nginx/error.log
.
Finalize Nginx setup
Now that we now Nginx works, we want to make a last small adjustment. Currently, our uWSGI setup exposes the Django server on port 8001. However, a more elegant solution would be to expose the Django server using a file socket. Change the/etc/nginx/sites-available/etesync_nginx.conf
file to accept sockets by commenting in # server unix:///tmp/etesync_server.sock;
and commenting out server 127.0.0.1:8001;
.
The file should now look like this.
Finalize uWSGI setup
Of course, we still need to setup our uWSGI to also use a websocket. For this, copy the following code into a file calleduwsgi.ini
.
This .ini file specifies some parameters to our uWSGI, like for example to location of where it should expose the socket and which users should be able to use it.
Since Nginx runs under the user www-data
, we use the .ini to make sure Nginx is able to open socket.
If we now want to run uWSGI, we do so by using the following command.
$ uwsgi --ini uwsgi.ini
5. Run server at boot
Now that we have a fully functional webserver, we want to make sure that it is able to launch at startup so that we don't have to start it manually very time. Luckily, Nginx does this already. (Recall how we used asystemd
command earlier to restart it).
We can do the exact same thing for uWSGI, after creating a systemd unit file. Create a new file and paste in the following (don't forget to change
/etc/systemd/system/etesync_server.service
, we can use it via systemd.
To start and enable the uWSGI unit, do the following.
$ systemd start etesync_server $ sytemd enable etesync_server #this makes it launch at startup
6. Open up the server to the world!
It would surely stink if the EteSync server could only be used on a local network. Luckily for us, it is very easy to expose it to the outside world. Unluckily for us, this is also very dangerous. We could run the EteSync server over HTTP, but obviously HTTPS is more safe.First, we need to download certbot. To setup SSL for HTTPS, we need to first make sure our server is reachable on HTTP from the outside. To do this, you should port-forward your router to point port 80 and 443 to your pi's local IP address. Next, have your domain name resolve to your external IP address (if you don't know this, check here). Now you should be able to reach your EteSync server using your domain name, followed by
:8000
.
To setup HTTPS, we're going to need a certificate. Thanks to certbot, this is a breeze. All we need to do is install it, and have it run. It should even automatically change our
etesync_nginx.conf
file to support HTTPS.
$ sudo apt-get install certbot python-certbot-nginx $ sudo certbot --nginxAnd that's it! Our server is fully set up. All there's left to do, is create an admin super user, login to our EteSync server, create a non-super user and you're good to go.
$ ./manage.py createsuperuser