Score:0

Setting up nginx as proxy between webservice docker containers

tn flag

I'm trying to set up a server to host a specific web application. I have registered a domain (lets say example.org) made a vps via digitalocean and set the DNS for example.org to point to it, so if I run a simple webserver, I get access to it by opening example.org in a web browser.

I want to use this server to host filebrowser (https://filebrowser.org/). If I just run it with default docker command, it works. However, I want to

  1. have it (and any other webservices) behind HTTPS.
  2. have it reachable at example.org/files. This is so I can use the domain for other things as well.

The idea is to run nginx in one docker container with ports 80 and 443 published. Then I have certbot in another following this guide: https://mindsers.blog/post/https-using-nginx-certbot-docker/. And finally I want to run filebrowser in a third docker container. This way, only nginx should be accessible from the outside and it handles all routing to other services. If I understand correctly, I then only need to set up ssl-certs for the nginx-container and it can communicate with normal http internally. My current docker-compose.yaml is:

version: '3'

services:
  webserver:
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/:ro
      - ./nginx/www/:/srv/www/:ro
      - ./certbot/www:/var/www/certbot/:ro
      - ./certbot/conf/:/etc/nginx/ssl:ro
  certbot:
    image: certbot/certbot:latest
    volumes:
      - ./certbot/www/:/var/www/certbot/:rw
      - ./certbot/conf/:/etc/letsencrypt/:rw
  filebrowser:
    image: filebrowser/filebrowser:latest
    volumes:
      - ./filebrowser/files:/srv
      - ./filebrowser/filebrowser.db:/filebrowser.db
      - ./filebrowser/filebrowser.json:/.filebrowser.json

From looking at this answer https://serverfault.com/a/813776/1037593, i have set up nginx with the following config:

server {
listen 80;
listen [::]:80;
server_name example.org www.example.org;
server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://example.org$request_uri;
    }
}


server {
    listen 443 default_server ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name example.org;

    ssl_certificate /etc/nginx/ssl/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/example.org/privkey.pem;

    location / {
        root /srv/www/;
    }

    location /files {
        return 302 /files/;
    }

    location /files/ {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
        add_header Pragma "no-cache";
        add_header Cache-Control "no-cache";

        proxy_pass http://filebrowser:8080/;

        sub_filter 'action="/' 'action="/files/';
        sub_filter 'href="/' 'href="/files/';
        sub_filter 'src="/' 'src="/files/';
        sub_filter_once off;
    }
}

And finally, the config for filebrowser is

{
  "port": 8080,
  "baseURL": "",
  "address": "",
  "log": "stdout",
  "database": "/filebrowser.db",
  "root": "/srv"
}

When I run this, the dummy index.html file nginx serves at / is shown when I navigate to example.org. When I try to navigate to example.org/files, I get the login-page for filebrowser, but when I input the username and password (which I know are correct) I get the error message "Wrong credentials", and the console from nginx shows an error about being unable to find a perticular file. The full output from running docker compose up and trying to log in is:

[+] Running 4/4
 ✔ Network webservices_default          Created    0.1s
 ✔ Container webservices-certbot-1      Created    0.1s
 ✔ Container webservices-filebrowser-1  Created    0.1s
 ✔ Container webservices-webserver-1    Created    0.1s
Attaching to webservices-certbot-1, webservices-filebrowser-1, webservices-webserver-1
webservices-filebrowser-1  | 2023/07/26 12:49:57 Using config file: /.filebrowser.json
webservices-filebrowser-1  | 2023/07/26 12:49:57 Listening on [::]:8080
webservices-webserver-1    | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
webservices-webserver-1    | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
webservices-webserver-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
webservices-webserver-1    | 10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
webservices-webserver-1    | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
webservices-webserver-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
webservices-webserver-1    | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
webservices-webserver-1    | /docker-entrypoint.sh: Configuration complete; ready for start up
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: using the "epoll" event method
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: nginx/1.25.1
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: OS: Linux 5.15.0-78-generic
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: start worker processes
webservices-webserver-1    | 2023/07/26 12:49:57 [notice] 1#1: start worker process 21
webservices-certbot-1      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
webservices-certbot-1      | Certbot doesn't know how to automatically configure the web server on this system. However, it can still get a certificate for you. Please run "certbot certonly" to do so. You'll need to manually configure your web server to use the resulting certificate.
webservices-certbot-1 exited with code 1
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files HTTP/2.0" 302 145 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files/ HTTP/2.0" 200 4439 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 2023/07/26 12:50:17 [warn] 21#21: *1 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/1/00/0000000001 while reading upstream, client: 89.8.210.16, server: example.org, request: "GET /files/static/js/chunk-vendors.0f8eac7b.js HTTP/2.0", upstream: "http://172.20.0.4:8080/static/js/chunk-vendors.0f8eac7b.js", host: "example.org", referrer: "https://example.org/files/"
webservices-webserver-1    | 2023/07/26 12:50:17 [warn] 21#21: *1 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/2/00/0000000002 while reading upstream, client: 89.8.210.16, server: example.org, request: "GET /files/static/css/app.2991abc4.css HTTP/2.0", upstream: "http://172.20.0.4:8080/static/css/app.2991abc4.css", host: "example.org", referrer: "https://example.org/files/"
webservices-webserver-1    | 2023/07/26 12:50:17 [warn] 21#21: *1 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/3/00/0000000003 while reading upstream, client: 89.8.210.16, server: example.org, request: "GET /files/static/js/app.8ca2bdf9.js HTTP/2.0", upstream: "http://172.20.0.4:8080/static/js/app.8ca2bdf9.js", host: "example.org", referrer: "https://example.org/files/"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files/static/css/app.2991abc4.css HTTP/2.0" 200 50042 "https://example.org/files/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files/static/css/chunk-vendors.e9e545fd.css HTTP/2.0" 200 7539 "https://example.org/files/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files/static/js/chunk-vendors.0f8eac7b.js HTTP/2.0" 200 251297 "https://example.org/files/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:17 +0000] "GET /files/static/js/app.8ca2bdf9.js HTTP/2.0" 200 102234 "https://example.org/files/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:18 +0000] "GET /static/img/logo.svg HTTP/2.0" 404 153 "https://example.org/login?redirect=%2Ffiles%2Ffiles%2F" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"
webservices-webserver-1    | 2023/07/26 12:50:18 [error] 21#21: *1 open() "/srv/www/static/img/logo.svg" failed (2: No such file or directory), client: 89.8.210.16, server: example.org, request: "GET /static/img/logo.svg HTTP/2.0", host: "example.org", referrer: "https://example.org/login?redirect=%2Ffiles%2Ffiles%2F"
webservices-webserver-1    | 2023/07/26 12:50:53 [error] 21#21: *1 open() "/srv/www/api/login" failed (2: No such file or directory), client: 89.8.210.16, server: example.org, request: "POST /api/login HTTP/2.0", host: "example.org", referrer: "https://example.org/login?redirect=%2Ffiles%2Ffiles%2F"
webservices-webserver-1    | 89.8.210.16 - - [26/Jul/2023:12:50:53 +0000] "POST /api/login HTTP/2.0" 404 153 "https://example.org/login?redirect=%2Ffiles%2Ffiles%2F" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0" "-"

It seems like some resources are not queried from the filebrowser-service, but from /srv/www, meaning the proxying doesn't work properly. Initially, I didn't even get the login page, and there were similar error messages before I added the extra settings in the location /files/-block. Do I have to add some other sub_filters? I suppose this could be solved by using subdomains (files.example.org instead), but I think this looks neater. I also tried fiddling a bit with the baseURL and address-fields in the filebrowser-config, but that led nowhere. I couldn't find any documentation about these either. I also tried this: https://nginxproxymanager.com/, but I got mostly the same behavior as when I did it manually. I am pretty new to nginx and webservices in general, so any help would be appreciated.

Score:0
tn flag

I solved it by setting the baseURL variable to "/files" in filebrowser.json. I then changed the nginx-config to just proxy_pass http://filebrowser:8080 without the trailing slash and removed all the sub_filter-stuff. This way filebrowser handles the changes in URLs. I still get some error messages in the logs, but at least the application works for my needs.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.