How to serve devpi with https?

2

I have an out-of-the-box devpi-server running on http://.

I need to get it to work on https:// instead.

I already have the certificates for the domain.

I followed the devpi documentation for nginx-site-config, and created the /etc/nginx/conf.d/domain.conf file that has the server{} block that points to my certificates (excerpt below).

However, my devpi-server --start --init is totally ignoring any/all nginx configurations.

How do I point the devpi-server to use the nginx configurations? Is it even possible, or am I totally missing the point?

/etc/nginx/conf.d/domain.conf file contents:

server {
    server_name localhost $hostname "";

    listen              8081 ssl default_server;
    listen              [::]:8081 ssl default_server;
    server_name         domain;
    ssl_certificate     /root/certs/domain/domain.crt;
    ssl_certificate_key /root/certs/domain/domain.key;
    ssl_protocols       TLSv1.1 TLSv1.2;
    ssl_ciphers         EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;

    gzip             on;
    gzip_min_length  2000;
    gzip_proxied     any;
    gzip_types       application/json;

    proxy_read_timeout 60s;
    client_max_body_size 64M;

    # set to where your devpi-server state is on the filesystem
    root /root/.devpi/server;

    # try serving static files directly
    location ~ /\+f/ {
        # workaround to pass non-GET/HEAD requests through to the named location below
        error_page 418 = @proxy_to_app;
        if ($request_method !~ (GET)|(HEAD)) {
            return 418;
        }

        expires max;
        try_files /+files$uri @proxy_to_app;
    }
    # try serving docs directly
    location ~ /\+doc/ {
        try_files $uri @proxy_to_app;
    }
    location / {
        # workaround to pass all requests to / through to the named location below
        error_page 418 = @proxy_to_app;
        return 418;
    }
    location @proxy_to_app {
        proxy_pass https://localhost:8081;
        proxy_set_header X-outside-url $scheme://$host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

Noam Musk

Posted 2019-05-09T01:51:57.040

Reputation: 21

Answers

1

Devpi doesn't know anything about Nginx, it will just serve HTTP traffic. When we want to interact with a web-app via HTTPS instead, we as the client need to talk to a front-end which can handle it (Nginx) which will in turn communicate with our web-app. This application of Nginx is known as a reverse proxy. As a reverse proxy we can also benefit from Nginx's ability to serve static files more efficiently than getting our web-app to do it itself (hence the "try serving..." location blocks).

Here is a complete working Nginx config that I use for devpi. Note that this is /etc/nginx/nginx.conf file rather than a domain config like yours because I'm running Nginx and Devpi in docker with compose but you should be able to pull out what you need:

worker_processes 1;

events { 
    worker_connections 1024; 
}

http {
    # Define the location for devpi
    upstream pypi-backend {
        server localhost:8080;
    }

    # Redirect HTTP to HTTPS
    server {
        listen 80;
        listen [::]:80;
        server_name _;
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name example.co.uk; # This is the accessing address eg. https://example.co.uk

        root /devpi/server; # This is where your devpi server directory is
        gzip             on;
        gzip_min_length  2000;
        gzip_proxied     any;

        proxy_read_timeout 60s;
        client_max_body_size 64M;

        ssl_certificate             /etc/nginx/certs/cert.crt; Path to certificate
        ssl_certificate_key         /etc/nginx/certs/cert.key; Path to certificate key

        ssl_session_cache           builtin:1000  shared:SSL:10m;
        ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers                 HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers   on;

        access_log                  /var/log/nginx/pypi.access.log;

        # try serving static files directly
        location ~ /\+f/ {
            error_page 418 = @pypi_backend;
            if ($request_method !~ (GET)|(HEAD)) {
                return 418;
            }

            expires max;
            try_files /+files$uri @pypi_backend;
        }

        # try serving docs directly
        location ~ /\+doc/ {
            try_files $uri @pypi_backend;
        }

        location / {
            error_page 418 = @pypi_backend;
            return 418;
        }

        location @pypi_backend {
            proxy_pass              http://pypi-backend; # Using the upstream definition
            proxy_redirect          off;
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-outside-url $scheme://$host:$server_port;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Host $server_name;
        }
    }
}

With Nginx using this configuration and devpi running on http://localhost:8080, you should be able to access https://localhost or with your machine with appropriate DNS https://example.co.uk. A request will be:

client (HTTPS) > Nginx (HTTP) > devpi (HTTP) > Nginx (HTTPS) > client

This also means that you will need to make sure that Nginx is running yourself, as devpi start won't know any better. You should at the very least see an Nginx welcome page.

inkychris

Posted 2019-05-09T01:51:57.040

Reputation: 111