4 Production setup using Nginx
Marc Walter edited this page 1 year ago

This page details how to create a production setup for the Etebase server. There exist many ways of doing this, but this guide uses uvicorn as ASGI and Nginx as web server.

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. In this guide, we will create the following stack:

the web client <-> Nginx <-> the socket <-> uvicorn <-> fastapi/Django

Uvicorn

If uvicorn is not yet set up, refer to the basic setup page, where it is explained.

Nginx

Nginx will be used as our proper web server.

Installing Nginx

Installation can be done via apt.

$ sudo apt-get install nginx

Setup Nginx

First of all, we 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 etebase_nginx.conf and paste the following into it. Don't forget to change server_name and the path to /static.

# etebase_nginx.conf

# the upstream component nginx needs to connect to
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)
}

# 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/etebase/static/; # Project's static files
    }

    location / {
        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;
    }
}

Now we move this file to /etc/nginx/sites-available and symlink it to /etc/nginx/sites-enabled. After restarting Nginx and launching Uvicorn (on port 8001), you should be able to surf to the same url as before and see "It works!".

$ 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
$ nginx -t
$ systemctl restart nginx
$ uvicorn etebase_server.asgi:application --port 8001 --host 0.0.0.0

If you encounter any errors, the Nginx log is located in /var/log/nginx/error.log.

Finalize Nginx & uvicorn setup

For testing purposes, uvicorn 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/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 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/etebase_server.sock. Now, we change the way we run Uvicorn to use the same file socket.

$ nginx -t
$ systemctl restart nginx
$ uvicorn etebase_server.asgi:application --uds /tmp/etebase_server.sock

That's it!

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 uvicorn run automatically at boot. More explanation can be found here: Run uvicorn at boot

It is also highly recommended to enable TLS for your Etebase server! A page detailing SSL setup can be found here: Setup HTTPS for Etebase