Reverse proxy multiple Octoprint instances with nginx

This will allow you to access an Octoprint instance (or even multiple instances) from a single web server. Most commonly, this is used on a public-facing web server with HTTPS enabled.

Normally, setting this up a reverse proxy is straightforward, but the weird webcam support in Octoprint makes this a little tricky.

First, install nginx per normal, and set up a basic domain config in /etc/nginx/sites-available/<your_domain>. You can enable HTTPS at this time with certbot. That's all out of scope for us.

Next, edit the web server /etc/nginx/sites-available/<your_domain>. This example shows two Octoprint instances (with two location blocks per instance):

    location ~ ^/webcam/(.*) {
        rewrite ^/webcam/(.*) /printrbot/webcam/$1 redirect;
    }

    location /printrbot/ {
        if ($scheme != "https") {
            rewrite ^ https://$host$uri permanent;
        }
        # require login
        auth_basic           "OctoPrint: PrintrBot";
        auth_basic_user_file /etc/nginx/passwd-3dprinter.conf;
        
        # proxy
        rewrite ^/printrbot/(.*)$ /$1 break;
        proxy_pass http://192.168.0.42;
        proxy_redirect ~^http://192.168.0.42/(.*)$ $scheme://$host/printrbot/$1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Script-Name /printrbot;
        proxy_http_version 1.1;
        client_max_body_size 0;

        location /printrbot/webcam/ {
            auth_basic off; # no login for just the webcam
            rewrite ^/printrbot/webcam/(.*)$ /webcam/$1 break;
            proxy_pass http://192.168.0.42;
            proxy_redirect ~^http://192.168.0.42/(.*)$ $scheme://$host/printrbot/$1;
        }
    }

    # requires tweak to octopi config to use alternate absolute webcam url
    location ~ ^/webcam2/(.*) {
        rewrite ^/webcam2/(.*) /prusa/webcam/$1 redirect;
    }

    location /prusa/ {
        if ($scheme != "https") {
            rewrite ^ https://$host$uri permanent;
        }
        # require login
        auth_basic           "OctoPrint: Prusa";
        auth_basic_user_file /etc/nginx/passwd-3dprinter.conf;
        
        # proxy
        rewrite ^/prusa/(.*)$ /$1 break;
        proxy_pass http://192.168.0.46;
        proxy_redirect ~^http://192.168.0.46/(.*)$ $scheme://$host/prusa/$1;
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Script-Name /prusa;
        proxy_http_version 1.1;
        client_max_body_size 0;

        location /prusa/webcam/ {
            auth_basic off; # no login for just the webcam
            rewrite ^/prusa/webcam/(.*)$ /webcam2/$1 break;
            proxy_pass http://192.168.0.46;
            proxy_redirect ~^http://192.168.0.46/(.*)$ $scheme://$host/prusa/$1;
        }
    }

Then systemctl reload nginx.

Things to note:

Enabling webcam support for Octoprint instances after the first

We want to tweak each octoprint instances after the first as follows to give it a unique absolute URL to the webcam. This assumes Octoprint is installed as in Octopi.

Edit /etc/haproxy/haproxy.cfg, and add the two noted lines, with a new number (or other URL tweak) per instance:

frontend public
        use_backend webcam if { path_beg /webcam/ }
        use_backend webcam if { path_beg /webcam2/ } # <<add this line

backend webcam
        http-request replace-path /webcam/(.*) /\1
        http-request replace-path /webcam2/(.*) /\1  # <<add this line

Then systemctl reload haproxy.

Then, in Octoprint web UI, go to configuration, and in the "Classic Webcam" section, change Stream URL from /webcam/?action=stream to /webcam2/?action=stream (or whatever tweaked URL you did for this instance).

When done, the full UI including webcam should function both via direct connection to each Octoprint instance as well as via the URLs on the nginx proxy.