mirror of
https://github.com/etesync/server
synced 2024-11-26 10:48:21 +00:00
Created a page detailing a possible uWSGI & Nginx setup.
parent
98abd224ef
commit
a43003bdc9
155
Production-setup-using-uWSGI-and-Nginx.md
Normal file
155
Production-setup-using-uWSGI-and-Nginx.md
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
## uWSGI
|
||||||
|
|
||||||
|
It's 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:
|
||||||
|
|
||||||
|
>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 <-> Django`
|
||||||
|
|
||||||
|
Note that different WSGI's exist and can be used, like for example Gunicorn.
|
||||||
|
However, in this tutorial uWSGI is used.
|
||||||
|
|
||||||
|
### Installing uWSGI
|
||||||
|
|
||||||
|
Installation of uWSGI is easily done via pip.
|
||||||
|
Root needs access to uWSGI later, so install it as superuser.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo pip3 install wsgi
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing uWSGI
|
||||||
|
|
||||||
|
We can already test whether our uWSGI 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
|
||||||
|
```
|
||||||
|
|
||||||
|
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!")
|
||||||
|
|
||||||
|
## Nginx
|
||||||
|
|
||||||
|
Nginx will form our proper web server.
|
||||||
|
|
||||||
|
### Installing Nginx
|
||||||
|
|
||||||
|
Installation if done via apt.
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup Nginx
|
||||||
|
|
||||||
|
First of all, create Django's static files so that Nginx can access them.
|
||||||
|
|
||||||
|
```
|
||||||
|
./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.
|
||||||
|
Don't forget to change `server_name` and the path to `/static`.
|
||||||
|
|
||||||
|
```
|
||||||
|
# mysite_nginx.conf
|
||||||
|
|
||||||
|
# the upstream component nginx needs to connect to
|
||||||
|
upstream django {
|
||||||
|
# server unix:///tmp/etesync_server.sock; # for a file socket
|
||||||
|
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
|
||||||
|
}
|
||||||
|
|
||||||
|
# configuration of the server
|
||||||
|
server {
|
||||||
|
# the port your site will be served on
|
||||||
|
listen 8000;
|
||||||
|
# the domain name it will serve for
|
||||||
|
server_name example.com; # substitute your machine's IP address or domain name
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
# max upload size
|
||||||
|
client_max_body_size 75M; # adjust to taste
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
alias /path/to/server_skeleton/static # 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
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!".
|
||||||
|
|
||||||
|
```
|
||||||
|
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.wsgi
|
||||||
|
```
|
||||||
|
|
||||||
|
If you encounter any errors, the Nginx log is located in `/var/log/nginx/error.log`.
|
||||||
|
|
||||||
|
### Finalize Nginx & uWSGI 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.
|
||||||
|
|
||||||
|
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;`.
|
||||||
|
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
|
||||||
|
# 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 `<user>` by the name of the user for the server.
|
||||||
|
|
||||||
|
```
|
||||||
|
[uwsgi]
|
||||||
|
chdir = /path/to/server-skeleton/
|
||||||
|
socket = /tmp/etesync_server.sock
|
||||||
|
chown-socket = <user>:www-data
|
||||||
|
chmod-socket = 660
|
||||||
|
module = etesync_server.wsgi
|
||||||
|
master = true
|
||||||
|
uid = <user>
|
||||||
|
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
|
||||||
|
uwsgi --ini uwsgi.ini
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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.conf`.
|
||||||
|
|
||||||
|
An optional next step is to have your uWSGI run automatically at boot.
|
||||||
|
It is also *highly* recommended **to enable SSL for your EteSync server!**
|
||||||
|
More info on both of these can be found in the wiki.
|
Loading…
Reference in New Issue
Block a user