From 21f372b5be0fea4292223e68592b30f04efa1ba3 Mon Sep 17 00:00:00 2001 From: Simon Vandevelde Date: Sun, 27 Sep 2020 14:48:27 +0200 Subject: [PATCH] Update to etebase using Daphne --- Production-setup-using-Daphne-and-Nginx.md | 134 ++++++++++----------- 1 file changed, 63 insertions(+), 71 deletions(-) diff --git a/Production-setup-using-Daphne-and-Nginx.md b/Production-setup-using-Daphne-and-Nginx.md index 468b035..eda937a 100644 --- a/Production-setup-using-Daphne-and-Nginx.md +++ b/Production-setup-using-Daphne-and-Nginx.md @@ -1,70 +1,70 @@ -## uWSGI +This page details how to create a production setup for the Etebase server. +There exist many ways of doing this, but this guide uses `Daphne` as ASGI and `Nginx` as web server. -It's not a good idea to just run the basic debug server and expose it to the outside world. +We do because its not a good idea to just run the basic debug server and expose it to the outside world. Instead, a component stack should be built. -The [uWSGI docs](https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html) state the following: +In this guide, we will create the following stack: ->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 <-> Nginx <-> the socket <-> Daphne <-> Django` -> `the web client <-> the web server <-> the socket <-> uwsgi <-> Django` -Note that different WSGI's exist and can be used, like for example Gunicorn. -However, in this tutorial uWSGI is used. +## Daphne -### Installing uWSGI +### Installing Daphne -Installation of uWSGI is easily done via pip. -Root needs access to uWSGI later, so install it as superuser. +Installation of Daphne is easily done via pip. +Make sure to install it inside of your virtual environment if you are using one. ``` -sudo pip3 install uwsgi +$ cd path/to/etebase +$ source venv/bin/activate # In case you haven't activated the venv yet. +$ pip3 install daphne ``` -### Testing uWSGI +### Testing Daphne -We can already test whether our uWSGI installation works. +We can already test whether our daphne installation works. ``` -cd path/to/server-skeleton -source venv/bin/activate # In case you haven't activated the venv yet. -uwsgi --http :8000 --module etesync_server.wsgi --virtualenv venv +$ cd path/to/etebase +$ source venv/bin/activate # In case you haven't activated the venv yet. +$ daphne -b 0.0.0.0 -p 8000 etebase_server.asgi:application ``` -This command runs the EteSync module, exposes it on port 8000 and uses the `venv` virtual environment. -You can now surf to the IP address followed by port 8000 in the browser to check if it works (you should see "It works!") +This command runs the Etebase application and exposes it on port 8000. +On the machine itself, you can now surf to `localhost:8000` to check if it works. +If you're on a different machine than the one running the server, surf to its local IP address followed by the port number, e.g. `192.168.x.x:8000`. ## Nginx -Nginx will form our proper web server. +Nginx will be used as our proper web server. ### Installing Nginx -Installation if done via apt. +Installation can be done via apt. ``` -sudo apt-get install nginx +$ sudo apt-get install nginx ``` ### Setup Nginx -First of all, create Django's static files so that Nginx can access them. +First of all, we create Django's static files so that Nginx can access them. ``` -./manage.py collectstatic +$ ./manage.py collectstatic ``` Now we need to configure Nginx, using a configuration file. -Create a new file called `etesync_nginx.conf` and paste the following into it. +Create a new file called `etebase_nginx.conf` and paste the following into it. Don't forget to change `server_name` and the path to `/static`. ``` -# mysite_nginx.conf +# etebase_nginx.conf # the upstream component nginx needs to connect to -upstream django { - # server unix:///tmp/etesync_server.sock; # for a file socket +upstream etebase { + # server unix:///tmp/etebase_server.sock; # for a file socket server 127.0.0.1:8001; # for a web port socket (we'll use this first) } @@ -80,77 +80,69 @@ server { client_max_body_size 75M; # adjust to taste location /static/ { - alias /path/to/server_skeleton/static; # Project's static files + alias /path/to/etebase; # Project's static files } - # Finally, send all non-media requests to the Django server. location / { - uwsgi_pass django; - include /etc/nginx/uwsgi_params; # the uwsgi_params file, this path by default + proxy_pass http://etebase; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; } } ``` -Move this file to `/etc/nginx/sites-available` and symlink it to `/etc/nginx/sites-enabled`. -After restarting Nginx and launching uWSGI (on port 8001), you should be able to surf to the same url as before and see "It works!". +Now we move this file to `/etc/nginx/sites-available` and symlink it to `/etc/nginx/sites-enabled`. +After restarting Nginx and launching Daphne (on port 8001), 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-enabled/etesync_nginx.conf -systemctl restart nginx -uwsgi --socket :8001 --module etesync_server.wsgi --virtualenv venv +$ sudo cp etebase_nginx.conf /etc/nginx/sites-available/ +$ sudo ln -s /etc/nginx/sites-available/etebase_nginx.conf /etc/nginx/sites-enabled/etebase_nginx.conf +$ systemctl restart nginx +$ daphne -b 0.0.0.0 -p 8000 etebase_server.asgi:application ``` If you encounter any errors, the Nginx log is located in `/var/log/nginx/error.log`. -### Finalize Nginx & uWSGI setup +### Finalize Nginx & Daphne setup -For testing purposes, uWSGI exposes the Django application on port 8001. -A more elegant solution would be to expose the application using a file socket. +For testing purposes, Daphne exposes the Django application on port 8001. +A more elegant solution would be to expose the application using a Unix file socket. -Change `/etc/nginx/sites-available/etesync_nginx.conf` to accept file sockets by commenting in `server unix:///tmp/etesync_server.sock;` and commenting out `server 127.0.0.1:8001;`. +Change `/etc/nginx/sites-available/etebase_nginx.conf` to accept file sockets by commenting in `server unix:///tmp/etebase_server.sock;` and commenting out `server 127.0.0.1:8001;`. The first part should now look like this: ``` # the upstream component nginx needs to connect to -upstream django { - server unix:///tmp/etesync_server.sock; # for a file socket +upstream etebase { + server unix:///tmp/etebase_server.sock; # for a file socket # server 127.0.0.1:8001; # for a web port socket (we'll use this first) } ``` -This will create a file socket at `/tmp/etesync_server.sock`. -Now, configure uWSGI to also work using a file socket. -Because a lot of parameters are needed, create a `uwsgi.ini` and copy the following in it. -Don't forget to replace `` by the name of the user for the server. +This will create a file socket at `/tmp/etebase_server.sock`. +Now, we change the way we run Daphne to use the same file socket. + ``` -[uwsgi] -chdir = /path/to/server-skeleton/ -socket = /tmp/etesync_server.sock -chown-socket = :www-data -chmod-socket = 660 -module = etesync_server.wsgi -master = true -uid = -virtualenv = venv -``` - -Now to run uWSGI, all you need to do is tell it to use the `.ini` server. -Restart Nginx and check if everything still works. - -``` -systemctl restart nginx -sudo uwsgi --ini uwsgi.ini # has to be executed as root +$ systemctl restart nginx +$ daphne -u /tmp/etebase_server.sock etebase_server.asgi:application ``` ### That's it! -You now have a working EteSync server over HTTP. -Don't forget to change `allowed_hosts` to your domain name in `etesync-server.ini` and to set `server_name` to your domain name in `/etc/nginx/sites-available/etesync_nginx.conf`. +You now have a working Etebase server over HTTP. +Don't forget to change `allowed_hosts` to your domain name in `etebase-server.ini` and to set `server_name` to your domain name in `/etc/nginx/sites-available/etebase_nginx.conf`. -An optional next step is to have your uWSGI run automatically at boot. More explanation can be found here: [Run uWSGI at boot](https://github.com/etesync/server/wiki/Run-uWSGI-at-boot) +An optional next step is to have your Daphne run automatically at boot. More explanation can be found here: [Run Daphne at boot](https://github.com/etesync/server/wiki/Run-Daphne-at-boot) -It is also *highly* recommended **to enable SSL for your EteSync server!** -A page detailing SSL setup can be found here: [Setup HTTPS for EteSync](https://github.com/etesync/server/wiki/Setup-HTTPS-for-EteSync) \ No newline at end of file +It is also *highly* recommended **to enable SSL for your Etebase server!** +A page detailing SSL setup can be found here: [Setup HTTPS for Etebase](https://github.com/etesync/server/wiki/Setup-HTTPS-for-Etebase) \ No newline at end of file