Another day in Paradise. So on this beautiful day, I was wondering how I can set up a reverse proxy for Atoma’s test and release tool. Every module of the product runs on different ports and for our clients, it is really a pain in the ass to open up ports on their firewalls. Banking is really secure domain so I was thinking, how I can use a reverse proxy instead of browsing the different modules on nonstandard ports. I use NGINX as a reverse proxy. It is a fast and trusted open-source solution. Here is how I did it.
Firstly, add the NGINX image in Docker. You may use the docker command-line interface:
$ docker pull nginx
or use Portainer:
![Docker pull nginx image](http://eduroll.eu/wp-content/uploads/2020/01/docker_pull_nginx.png)
The next step is to add the image to the stack. Again we are using the good old Portainer to make this job.
![Edit the stack file to use the NGINX image.](http://eduroll.eu/wp-content/uploads/2020/01/docker_stack_nginx.png)
Here you need to define the ports that you want to use.
ports: - "80:80" - "443:443"
Then we need to define the volumes as well. The first two volumes are the let’s say default ones. I added a volume for the config file so I do not have to edit the default.conf inside the container. So it can be edited on the docker server.
/opt/docker/nginx-config:/etc/nginx/conf.d:ro
And one volume for the SSL certificates. The application does have its own certificates so I just used them. If you need to create SSL certification then there are many quick guides on the internet.
/opt/docker/tarisga/ssl:/etc/ssl/certs:ro
In the /opt/docker/nginx-config create the file default.conf with the following content:
server { listen 443 ssl default_server; listen [::]:443 ssl default_server; # New root location ssl_certificate /etc/ssl/certs/taris.pem; ssl_certificate_key /etc/ssl/certs/taris.key; location / { root /usr/share/nginx/html; # return 404; } # You may need this to prevent return 404 recursion. location = /404.html { internal; } location /portainer/ { proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_pass https://172.19.0.1:9000/; } location /portainer/api/websocket/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_pass https://172.19.0.1:9000/api/websocket/; }
The main parts were highlighted. For the portainer we need to set a path, eg. /portainer/ and pass the request to the application running on the container on port 9000. Also, we need to add the API, because on the container it is running on the /api/websocket/ path but because portainer is running under the /portainer/ folder we have to add it separately.
Here is the result:
![Accessing portainer on port 443 using nginx as reverse proxy.](http://eduroll.eu/wp-content/uploads/2020/01/portainer_with_nginx-1024x561.png)
And that’s all. Cheers,
4 replies on “NGINX Reverse Proxy for Docker Containers and for Portainer”
Very very very elegant and nice solution, I was trying to do using complex rewrite rules, but it breaks some api functions. Thanks for share 🙂
Been searching for a solution. The two proxy_set_header for /api/websocket were the key! Thanks so much for sharing this.
Thanks this was just what I needed.
Note that when proxying using a domain such as portainer.mydomain.com it is only necessary to add this to the default location /
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_http_version 1.1;
the /portainer and portainer/api locations are not needed in this scenario
Thanks!