lloesche / valheim-server-docker

Valheim dedicated gameserver with automatic update, World backup, BepInEx and ValheimPlus mod support
https://hub.docker.com/r/lloesche/valheim-server
Apache License 2.0
1.94k stars 272 forks source link

Running supervisor behind reverseproxy #318

Closed dnewsholme closed 3 years ago

dnewsholme commented 3 years ago

Hi I've got supervisor running behind a reverse proxy using the following:

    location /valheim/ {
      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;

      # Fix the "It appears that your reverse proxy set up is broken" error.
      proxy_pass          http://valheimsupervisor/;
      proxy_read_timeout  600;
      proxy_pass_request_headers on;
      proxy_redirect      default;
}

Which kind of works however when you click any task in supervisor the relative path obviously doesn't have /valheim on it so never redirects back.

I've looked in the docker container and can see the supervisor scripts under /usr/local but can't see any config or how i would alter the relative urls.

Any idea on how i could achieve this?

lloesche commented 3 years ago

I don't think supervisor has any way of mapping to a different path but check http://supervisord.org/ The config is in /usr/local/etc/.

That said I think the issue is with the proxy config. The proxy introduces a new path prefix /valheim/ but does not remove it before issuing the backend request. I.e. if the proxy adds frontend.domain/valheim/index.html the backend request should go to backend.domain/index.html with the proxy-added prefix removed. At least that's how all service meshes I've worked with operate. I'm no nginx expert but from a glance at the docs I think rewrite ^/valheim/(.*) /$1 break; before the proxy_pass might work. Though I don't know what the effects of proxy_pass_request_headers is.. as in if that is the point where the original GET path is retained. Anyhow my approach would be to fix the backend request instead of trying to convince the backend to make itself available at a different path prefix.

dnewsholme commented 3 years ago

The trailing slash on proxypath does the same as what a rewrite would achieve.

You are right though it doesn't look like supervisor has any way of editing the base path. https://github.com/Supervisor/supervisor/issues/29

Even trying the hack:

Doesn't work as it will always send back to /?message=unexpected%20rpc%20fault%20%5B70%5D%20NOT_RUNNING%3A%20valheim-backup instead of /valheim/message=unexpected%20rpc%20fault%20%5B70%5D%20NOT_RUNNING%3A%20valheim-backup

I don't think it can be done until the merge from 5 years ago goes through on supervisor. https://github.com/Supervisor/supervisor/pull/593

Anyway it's nothing wrong with your docker image (which is great btw). I'll close this down now that i've added some more information in case anyone else has this issue.

lloesche commented 3 years ago

Like I said, the issue is not with supervisor, the issue is with your proxy config.

I just tested and here's an nginx config that works for me:

    location /valheim/ {
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_read_timeout 3600;
        proxy_pass http://172.17.0.2:9001/;
    }

With the IP obviously adjusted to your environment 🙂

The buffering and removal of keep-alive header is required for the log streaming to work. The read timeout determines how long you can view the streaming log before nginx will cut the connection.

To avoid any misunderstandings here's the complete file (it's just the default.conf from the standard nginx container with that /valheim/ location added):

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /valheim/ {
        proxy_buffering off;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_read_timeout 3600;
        proxy_pass http://172.17.0.2:9001/;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

which I ran like so:

docker run --rm -it --name nginx -p 80:80 -v $HOME/default.conf:/etc/nginx/conf.d/default.conf nginx

And works just fine. I'm able to restart/start/stop services and tail the growing stdout/stderr logs:

image

image

Hope this helps.

dnewsholme commented 3 years ago

You are right! The buffering off made all the difference. Today i learnt. Thank you!