ckulka/baikal-docker

Use nginx as reverse proxy for baikal-docker (which also uses nginx)

ArPhil opened this issue · 2 comments

Hi and thanks for providing the docker image of baikal!

I am able to get it working when providing direct access to the baikal docker container with port (let`s say) 9999. The setup Wizzard works also perfectly. Now I would like to use my own (docker based) nginx instance as reverse proxy for baikal-docker (and other services).

Although my setup with nginx as reverse proxy works with other docker container services perfectly, I am not able to get it running with the baikal-docker container (Getting 502 Bad Gateway by nginx). I suspect, that something (forward headers?) is missing when forwarding / proxy_passing from nginx docker container to the baikal docker container.

My nginx configuration:

server {
        listen 9999;
        location / {
            proxy_pass http://baikal:5555/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

My docker-compose setup for baikal (including nginx):

version: '3'

services:
  nginx:
    image: docker.io/nginx:1.23.3
    container_name: nginx
    ports:
      - "9999:9999"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    networks:
      - somenetwork
    depends_on:
      - "baikal"

  baikal:
    image: docker.io/ckulka/baikal:0.9.3-nginx
    container_name: baikal
    ports:
      - "5555:80"
    volumes:
      - /home/baikal/config:/var/www/baikal/config
      - /home/baikal/Specific:/var/www/baikal/Specific
    networks:
      - somenetwork

networks:
   somenetwork:
      name: somenetwork

The idea is to expose port 9999 to the outer world via nginx and then route internally by nginx to port 5555 of the baikal container which is bound by the baikal-docker container to internal port 80.

What I know is:

  • Ports (especially 9999) are open and this is not an issue, since I used the same configuration but just proxy_passed successfully to another docker container based service (with same ports)
  • The docker-compose part for baikal seems to be OK, because I can access the baikal instance in my browser when I open port 5555 (not going through nginx).
  • Setting the base URI in baikal.yaml does not show the wished effect
  • The trailing slash "/" in proxy_pass http://baikal:5555/; seems not to matter (tried it with and withouth slash)

What am I missing here, since the baikal docker instance obviously is running perefectly (config files are also persisted), but cannot be accessed behind another nginx reverse proxy instance?

I solved a part of the problem and added some SSL support. What I figured out while doing this:

  1. The docker-compose service for baikal does not need to publish a port which maps to port 80, since the baikal container and nginx container are running in the same network. That means that the nginx container can connect directly to the baikal container. No port publishing required.
  2. Because of 1., my nginx configuration was wrong, since it proxy_passed to the published (5555) but not the exposed (80) port of the baikal container.
  3. I had to set the host / domain name explicitely since $host (for what reason ever) does not provide the expected results.

The updated configs:

nginx:

server {
        listen 443 ssl;
        server_name some.domain.com

       #Some SSL specific stuff like certificates goes here.

        location / {
            proxy_pass http://baikal:80;
            proxy_set_header Host some.domain.com;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

docker-compose:

version: '3'

services:
 nginx:
   image: docker.io/nginx:1.23.3
   container_name: nginx
   ports:
     - "443:443"
   volumes:
     - ./nginx/nginx.conf:/etc/nginx/nginx.conf
   networks:
     - somenetwork
   depends_on:
     - "baikal"

 baikal:
   image: docker.io/ckulka/baikal:0.9.3-nginx
   container_name: baikal
   volumes:
     - /home/baikal/config:/var/www/baikal/config
     - /home/baikal/Specific:/var/www/baikal/Specific
   networks:
     - somenetwork

networks:
  somenetwork:
     name: somenetwork

This results in (some part of the) baikal page to show up with the browser confirming a valid SSL certificate. However, some images are missing. Looking into the browser network tab shows, that css and javascript files are requested via http and not https. Initially I thought, that setting the parameter base_uri as https://some.domain.com/ in the baikal config would solve the problem, but this results just in appending the base_uri to the host in a way like http://some.domain.com/https://some.domain.com for all referenced js and css files in the html page. So for obvious reasons, loading these still failes and the page is borken (although visible and with SSL support). Adding :443 to proxy_set_header Host some.domain.com does not help, neither does using $http_host.

How can one tell the baikal-docker container when using nginx to use https instead of http?

(The idea is to terminate SSL at the nginx docker container and not at the baikal container, so that only the nginx has to be configured for ssl and not all docker services behind it)

I finally managed to get things working. I was missing one nginx header proxy_set_header X-Forwarded-Proto, which sets the protocol as header (https and not http). The complete nginx server config for baikal docker looks like this for me:

server {
        listen 443 ssl;
        server_name some.domain.com

        #Some SSL specific stuff like certificates goes here.

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
}

Issue closed.