Serve Senaite with Nginx

I would like to make my installation available to other users in the network. For that I setup an nginx server that reverse-proxies the requests to localhost:8080 where senaite runs. Though, the links that Senaite creates all start with localhost:8080. How can I tell Senaite that it runs on a different domain/port?

Cheers
Soren

Hi @soerendip, you need to add a rewrite rule in NGINX, e.g.

server {
    [...]
    location / {
        proxy_set_header        Host            $http_host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite                 ^(.*)$ /VirtualHostBase/$scheme/$host/senaite/VirtualHostRoot/$1 break;
        proxy_pass              http://127.0.0.1:8080;
    }
}

Also see the official NGINX docs

1 Like

I tried that, but when I go to the server it returns:

<h2>Site Error</h2> <p>An error was encountered while publishing this resource. </p> <p><strong>Resource not found</strong></p> Sorry, the requested resource does not exist.<p>Check the URL and try again.</p><p><b>Resource:</b> senaite GET</p> <hr noshade=“noshade”/> <p>Troubleshooting Suggestions</p> <ul> <li>The URL may be incorrect.</li> <li>The parameters passed to this resource may be incorrect.</li> <li>A resource that this resource relies on may be encountering an error.</li> </ul> <p>For more detailed information about the error, please refer to the error log. </p> <p>If the error persists please contact the site maintainer. Thank you for your patience. </p>

Probably your Senaite site does not call senaite?

Change this line according to your site ID:
rewrite ^(.*)$ /VirtualHostBase/$scheme/$host/<SENAITE-SITE-ID>/VirtualHostRoot/$1 break;

I don’t understand what information I should put in there. What is SENAITE-SITE-ID standing for?? My domain? Interestingly, without the rewrite I can now access senaite, but the CSS does not work. And I get (blocked:mixed-content) for the css files. Probably, because I am serving via https.

Oh, now it works. My configuration now looks like this:

location / {
    proxy_set_header        Host            $http_host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    rewrite                 ^(.*)$ /VirtualHostBase/$scheme/$host/lims/VirtualHostRoot/$1 break;
    proxy_pass              http://127.0.0.1:8080;

}

I had configured senaite so that it serves the LIMS under example.com/lims, though also pages as example.com/dashboard work fine. So, I am not sure why I have to put “lims” into the rewrite. I find this syntax not very intuitive and I am not sure what is going on and why it works. I would be glad if someone could give me an example.

Also, I am happy that it is working now, though I would like to serve senaite only at a certain folder. E.g. example.com/lims/… so that the senaite dashboard is shown under example.com/lims/dashboard.

1 Like

can you please tell me in details how you solved this problem?

Hi @David_Hendrix

What issues do you have using Nginx and errors are you getting?

1 Like

@ronaldm Please I want to run senaite on nginx server and I don’t know how to.

Hi @David_Hendrix

Please follow this documentation if you face specific issues please post back and we will do our best to assist.

1 Like

Thank you very much.

1 Like

My docker instance still won’t connect using nginx docker instance with the following config with my Senaite instance as “NBLims”:

# This adds security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
#add_header Content-Security-Policy "default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'";
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'";

# This specifies which IP and port Plone is running on.
# The default is 127.0.0.1:8080
upstream plone {
    server 127.0.0.1:8080;
}

# Redirect all www-less traffic to the www.site.com domain
# (you could also do the opposite www -> non-www domain)
server {
    listen 80;
    server_name this.ismy.domain;
    access_log /var/log/nginx/this.ismy.domain.access.log;
    error_log /var/log/nginx/this.ismy.domain.error.log;

    # Note that domain name spelling in VirtualHostBase URL matters
    # -> this is what Plone sees as the "real" HTTP request URL.
    # "Plone" in the URL is your site id (case sensitive)

    location / {
        proxy_set_header        Host            $http_host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite                 ^(.*)$ /VirtualHostBase/$scheme/$host/NBLims/VirtualHostRoot/$1 break;
        proxy_pass              http://127.0.0.1:8080;
    }
}

Nginx container starting fine. domain resolves to IP. Can hit the application on localhost:8080 but still doesn’t work with mydomain.com.

Thoughts?

nginx starting fine. When i go to mydomain.com I get the congats page from nginx that it’s running but the reverse proxy isn’t doing what it needs to. Help!

Please check this comment for an exemplary docker-compose file including a custom NGINX config: Bug: Setting the password fails · Issue #12 · senaite/senaite.docker · GitHub

The NGINX config should look like this:

events {
    worker_connections  1024;
}

http {
    server_tokens off;
    charset utf-8;

    proxy_connect_timeout       3600;
    proxy_send_timeout          3600;
    proxy_read_timeout          3600;
    send_timeout                3600;

    server {
        listen 443 ssl http2;
        server_name "_";

        ssl_certificate /etc/nginx/ssl/nginx.cert;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        # https://docs.pylonsproject.org/projects/waitress/en/latest/reverse-proxy.html

        proxy_set_header    X-Forwarded-Proto    $scheme;
        proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Host     $host:$server_port;
        proxy_set_header    X-Forwarded-Port     $server_port;
        proxy_set_header    Host                 $http_host;
        proxy_set_header    X-Real-IP            $remote_addr;

        location / {
            rewrite    ^(.*)$ /VirtualHostBase/$scheme/$host/senaite/VirtualHostRoot/$1 break;
            proxy_pass http://haproxy:80/;
        }
    }
}

Please note that the path senaite in the rewrite rule must match the ID of your SENAITE site!