Multiple instances with VENV, nginx, uwsgi, sao, certbot

Hello fellow friends,

my scenario is as follows:

  • ubuntu server with nginx and certbot certificates
  • generic (system) uwsgi
  • a number of Tryton instances, running in python VENVs, talking at ports 8000, 8001, 8002…
  • sao installed in every instance
  • different Tryton instances accessed through different port numbers, not subdomains; this for ease of scaling

I’d be very grateful for an example nginx config.

Cheers, Wolf

Here is a sample file we use for each deploy:

server {
        listen 80;
        listen [::]:80;
    	server_name domain.com;
        location /.well-known/acme-challenge {
            root /var/www/acme;
        }
        location / {
            return 301 https://$host$request_uri;
        }

server {
        # SSL configuration
        #
        listen 443 ssl;

        ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;

        client_max_body_size 50m;

	    access_log  /var/log/nginx/domain.com.access.log;

	    server_name domain.com;

        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 1d;
            proxy_pass http://localhost:8000;
        }

        location / {
            proxy_read_timeout 615s;
            proxy_send_timeout 615s;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://localhost:8000;
        }

}

You just need to adjutst the domain.com variable with the public domain you want to expose the server and update the 8000 port to the port you want to redirct the request.

1 Like

If you master the DNS, you can define wildcard certificates, so you can add a new vhost on the fly.

By the way, why do you use VENVs if you use system-wide uwsgi ?

Certainly, you know much more about it than I do. So, our assumption was that a system-wide uwsgi would improve performance; on the other side we have flexibility to run different version and module sets in VENVs. Tell me if that’s nonsense.

AFAIK, this works for a single Tryton instance, but we ran into trouble when trying to set up more at other ports. But tell me if I’m wrong.

All depends on what you aim. Lukio’s how to mentionned this possibility, but I didn’t understand what it was for.
I moved my answer to How to run uwsgi with different virtualenv - #16 by SISalp which is dedicated to this question.

I almost think it’s the other way around. When you install uwsgi in your virtual environment, the installer wants to compile uwsgi, so I would assume that the compiler would optimize uwsgi, based on the system libraries it finds.

Ever thought about using sockets?

But NginX should then also have the port so you can use something like:

domain.com:8000
domain.com:8001
domain.com:8002
domain.com:8003

To do that, you have to change the configuration from @pokoli and change the

listen 443 ssl

to

listen 8000 ssl

And do that for every port you want to access. Also keep the port of the proxy_pass equal to the listen port to keep everything simple.

I tried this in variations:

server {

       listen 8001 ssl http2;
       server_name [my-domain]:8001;



  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://0.0.0.0:8001;
  }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/[my-domain]/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/[my-domain]/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

I restarted trytond, then nginx, but get this error message in nginx’s journalctl:

nginx: [emerg] bind() to 0.0.0.0:8001 failed (98: Unknown error)

What’s wrong?

Have you done a nginx -t ? This command will check if your NginX configuration is right. And from what I can see, it’s not. I’m not going to tell you what is wrong … :nerd_face: but a good indentation will help a lot.

Also you are listening on port 8001 with NginX and probably also with Tryton. Those two are colliding and the first service started will win.

I tried several setups with one and two port numbers, I could not make one of these work. I asked at serverfault how to deal with different port numbers, but did not get any reply. So in the end I got the impression that it I’m too stupid (most likely) or it’s not supported. So i asked my admin for a batch of subdomains, which makes it easy.

One question remains:
How would I preset the database name in the nginx conf file? My guess was that the “location” section would do that, but attempts like

  location /#test-60 {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://127.0.0.1:8061;
  }

with or without a slash or a backslash in front of the database name failed as well. No problem to call my-sub.domain.de#my-database in the browser. Did anybody find a solution for this?

Cheers,
Wolf

I usually don’t use multiple databases on a production server.

You do not need to set the database on nginx. Just redirect to the server and the tryton server will manage all the needed databases.

What’s wrong?

server {
       listen 8001 ssl http2;

    proxy_pass http://0.0.0.0:8001;
}

You tell nginx to listen on 8001, while uwsgi (or what ever) already listens on that port.
Try starting nginx first and the other one will fail.

You can save a lot of time if you learn basics of network/socket communication and nginx config instead of trying-and-erroring :slight_smile: