Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom script for proxy host. #15

Closed
zaywalker opened this issue Sep 10, 2018 · 6 comments
Closed

Custom script for proxy host. #15

zaywalker opened this issue Sep 10, 2018 · 6 comments

Comments

@zaywalker
Copy link

zaywalker commented Sep 10, 2018

First of all, thanks for the awesome proxy manager! it's very easy to use like synology reverse proxy.

It's almost no problem, but some server won't work properly, so I digged in and I found nginx configuration.

https://portainer.readthedocs.io/en/stable/faq.html?highlight=proxy

upstream portainer {
    server ADDRESS:PORT;
}

server {
  listen 80;

  location /portainer/ {
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      proxy_pass http://portainer/;
  }
  location /portainer/api/websocket/ {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
      proxy_pass http://portainer/api/websocket/;
  }
}

But the problem is I have no idea where to put this in.. I've tried to use the advanced tab's custom configuration, but it doesn't work..

Any help and how to guides would be great!

Sorry about this noob question.;;

@jc21
Copy link
Member

jc21 commented Sep 10, 2018

You're almost there, the advanced config actually gets inserted into the server block and the location / is already forwarded, so all you need is the websocket part, this should work:

location /api/websocket/ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_pass http://$server:$port/api/websocket/;
}

@SGStino
Copy link

SGStino commented Sep 10, 2018

can't seem to get this working.

the generated config looks as following now:

# ------------------------------------------------------------
# portainer.docker
# ------------------------------------------------------------

server {
  set $server 192.168.48.198;
  set $port   9000;

  listen 80;

  server_name portainer.docker;






  access_log /data/logs/proxy_host-2.log proxy;

location /api/websocket/ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_pass http://$server:$port/api/websocket/;
}

  location / {



    # Proxy!
    include conf.d/include/proxy.conf;
  }
}

However, it's still missing this section:

map $http_upgrade $connection_upgrade {
    ''                      'close';
    default                 'upgrade';
}

But i can't find a way to inject this into the generated config? Aside from editing the template in the docker image, that is.

@zaywalker
Copy link
Author

zaywalker commented Sep 10, 2018

@jc21 Thanks for the answere! I've tried, but unfortunatly it didn't work for me. T_T But that's very good hint to learn how to use custom field. :)

these even I did, but it shows offline.

  location / {
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      proxy_pass http://$server:$port/;
  }
  location /api/websocket/ {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_http_version 1.1;
      proxy_pass http://$server:$port/api/websocket/;
  }

refer to @SGStino 's way, I've tried edit directly, but it didn't work. I guess

proxy_pass http://$server:$port/; this one is problem.

When I remove that line, I can reach the web, but the web ui doesn't work properly. I can't open container's bash console just like before.

# ------------------------------------------------------------
# portainer.mydomain.com
# ------------------------------------------------------------

server {
  set $server 192.168.123.123;
  set $port   9000;

  listen 80;

  server_name portainer.mydomain.com;



# Asset Caching
  include conf.d/include/assets.conf;


  # Block Exploits
  include conf.d/include/block-exploits.conf;


  access_log /data/logs/proxy_host-9.log proxy;

location /api/websocket/ {
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";
   proxy_http_version 1.1;
   proxy_pass http://$server:$port/api/websocket/;
}

  location / {
   proxy_set_header Connection "";
   proxy_http_version 1.1;

    # Proxy!
    include conf.d/include/proxy.conf;
  }
}

Thanks again!

@jc21
Copy link
Member

jc21 commented Sep 10, 2018

@SGStino So this is a bit of a limitation at the moment, you can't specify any custom configuration for hosts that are meant to sit outside of the server block. In your case, map does in fact sit outside of the block and as a result, the $connection_upgrade variable would be available to all nginx configurations options if it were to exist. I haven't found a nice, simple way to illustrate this in the interface yet. The goal of the software is to make life easy for people as much as possible. But I do want to have some more advanced configuration in there for users like yourself.

@zaywalker I'm using the latest Portainer myself (1.16.5 stable Docker version) and I'm not seeing any websocket upgrade requests at all in the interface. Even so, I've added the custom code I first mentioned to my proxy hosts and not only does the config show up on disk as part of the nginx config, it works just fine and reports online.

If you have a look at the proxy config template file you'll see where the advanced_config is placed. You'll also see that there is already a location / { section which cannot exist twice in the same server block.

If v1.19 of Portainer absolutely needs the websocket upgrade, you should only need this advanced config content:

location /api/websocket/ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_pass http://$server:$port/api/websocket/;
}

When you save the Host in the interface and the host shows "Offline", hover the "Offline" text and you should see the error in the Tooltip. Let me know what that says

@jc21
Copy link
Member

jc21 commented Sep 10, 2018

@zaywalker Ok I was a little bit mistaken, I found out where the api/websocket requests are happening and it was indeed failing for me too. I found the source of the problem and it's actually Portainers documentation that was wrong. This is the advanced config I'm using and I can get to my consoles now:

location /api/websocket/ {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_pass http://$server:$port;
}

Note that the proxy_pass doesn't need a path and if one is set, it ignored the path of the request when it's forwarded. In this specific case, /api/websocket/exec was being sent to /api/websocket/ and returning 400 errors for me.

@zaywalker
Copy link
Author

@jc21 Oh thanks for the solution! It works perfectly!! thanks for the help! even I've learn a lot with this! Thansk!

@jc21 jc21 closed this as completed Sep 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants