nginx redirect to multi docker container - docker

I need to configure a redirect to two different containers through the server.
My docker-compose file:
web_app:
image: ${WEB_APP_IMAGE}
ports:
- ${WEB_APP_PORT}:80
dashboard:
image: ${DASHBOARD_IMAGE}
ports:
- ${DASHBOARD_PORT}:80
nginx.conf:
location / {
proxy_set_header Host $host;
proxy_pass http://web_app;
proxy_redirect off;
}
location /admin {
proxy_set_header Host $host;
proxy_pass http://dashboard;
proxy_redirect off;
}
The web app is working correctly, but the "location /admin" doesn't redirect me to the dashboard container. What am I doing wrong?

Nginx is docker-agnostic. Since you are using docker-compose to spin up your containers, you need to provide the IP:PORT to the proxy_pass directive.
Also, you might want to switch the location directives between each other.
Try this:
location /admin {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:${DASHBOARD_PORT};
proxy_redirect off;
}
location / {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:${WEB_APP_PORT};
proxy_redirect off;
}

Related

Docker Gitlab container with nginx container

I have set up a gitlab container and nginx for proxy_pass but not working.
For example, I type example.com/gitlab, it can proxy_pass to 8086 port.
It can successful to display login page with out photo and the button is not working.
I find that if I add back the port number, it is work normally http://example.com:8086/projects/new
But proxy_pass address is http://example.com/projects/new, it cannot find the file and display 404.
location /gitlab {
proxy_pass http://example.com:8086;
}
how can I handle this case?
http://example.com/projects/new
http://example.com:8086/projects/new
Pass the GITLAB_HOST env in to container
docker run -e GITLAB_HOST=http://example.com/gitlab ....
and pass the request header and proxy port to the proxy server in nginx config
location /gitlab {
proxy_pass http://example.com:8086;
proxy_redirect off;
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;
}

nginx, access to other servers on internal network

I have a docker network running with this configuration (from docker-compose.yaml):
networks:
network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.28.1.0/24
(My network is named network)
I have an Angular frontend running in a container on this network (172.28.1.4). The frontend web server is an nginx server.
From the web server I would like calls to various backends (authentication and database) to go directly to these servers without exposing them to the outside world.
I.e to authenticate a user, something like this: httpClient.post('172.28.1.5:8080/_user/login', credentials)
I believe this should be done in the nginx configuration, but I am pretty clueless on how to allow access to 172.28.1.5 from nginx without exposing 172.28.1.5
The servers are visible to each other seen from a Docker perspective
I have tried using a reverse proxy and that works, but I cannot block access to the location from external ips
location ~/_user(/.*)*/?$ {
proxy_pass http://auth_server:8080; //auth_server points to 172.28.1.5
proxy_redirect off;
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-Host $server_name;
}
The proxy setup. I have changed the names of the servers to clarify their role in the network.
The frontend can call the database_server like this:
http://external.ip.address:443/_api/any_path
Unfortunately, so can anyone else :)
server {
listen 443;
server_name localhost;
location ~/_user(/.*)*/?$ {
proxy_pass http://authentication_server:8080;
proxy_redirect off;
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-Host $server_name;
}
location ~/_api(/.*)*/?$ {
proxy_pass http://database_server:80;
proxy_redirect off;
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-Host $server_name;
}
location ~/ {
proxy_pass http://ui_frontend_server:8080;
proxy_redirect off;
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-Host $server_name;
}
}
My docker setup makes this possible as it maps the name "authentication_server" with 172.28.1.3
authentication_server_service:
container_name: authentication_server
build: ../authentication_server/
image: authentication_server_image:latest
networks:
network:
ipv4_address: 172.28.1.3

Grafana doesn't work with nginx proxy_pass variable

We're running grafana and nginx in docker swarm, and proxying the url /foobar/ to the swarm instance of grafana. Using this guide, this works with the following config:
# nginx config
server {
resolver 127.0.0.11 valid=30s;
...
location /foobar/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://grafana:3000/;
proxy_next_upstream error timeout http_502;
}
}
# docker-compose
grafana:
image: ${REGISTRY}foo/grafana:${IMAGE_VERSION}
networks:
- foo
volumes:
- grafana:/var/lib/grafana
environment:
- GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/foobar/
However, this causes nginx to die on startup if the grafana service is not available. So to resolve this, we use a variable for the proxy_pass directive and change it to this:
server {
resolver 127.0.0.11 valid=30s;
...
location /foobar/ {
set $grafana http://grafana:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass $grafana/;
# proxy_pass http://grafana:3000/;
proxy_next_upstream error timeout http_502;
}
}
However, this causes grafana to reject the request somehow. I can verify that grafana is actually receiving the request (using GF_SERVER_ROUTER_LOGGING=true), and it claims the status is 200 ok, however the only thing I see on the page is
If you're seeing this Grafana has failed to load its application files
1. This could be caused by your reverse proxy settings.
2. If you host grafana under subpath make sure your grafana.ini root_path setting includes subpath
3. If you have a local dev build make sure you build frontend using: npm run dev, npm run watch, or npm run build
4. Sometimes restarting grafana-server can help
Why does grafana behave like this, and how can I set up the proxy pass such that nginx can start up without trying to resolve the grafana URL if it happens to be down?
When using variables complete URL is your responsibility in a proxy pass
location /foobar/ {
set $grafana http://grafana:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass $grafana$request_uri;
# proxy_pass http://grafana:3000/;
proxy_next_upstream error timeout http_502;
}
In case the base path is different then you will need to use regular expression to send part of the path
location ~ /foobar/(.*) {
set $grafana http://grafana:3000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass $grafana/$1;
proxy_next_upstream error timeout http_502;
}

Nginx returning error 404 when redirect to docker containers

I have a simple application with two separated containers: one to the backend (api-container) and other to the frontend (front-container).
I`d like to configure ngnix to redirect all requests from domain api.myurl.com to backend container and all requests from myurl.com to the frontend container.
To do that I configured the ngnix, as showed below:
server {
listen 80;
server_name myurl.com;
location / {
resolver 127.0.0.11;
proxy_pass http://front-container:80;
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;
}
}
server {
listen 80;
server_name api.myurl.com;
location / {
resolver 127.0.0.11;
proxy_pass http://api-container:3010;
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;
}
}
Everything works almost fine. When I access http://myurl.com everything is ok but when access another route like http://myurl.com/other the ngnix returns 404 error. This route works like a charm without ngnix.
What is wrong in my configuration?
Important: ngninx is running also in a container in the same network to other containers.

Docker compose network confused the nodes

Sometimes nginx server forwards request to wrong docker-compose service.
I have docker-compose config
version: "3.0"
services:
proj-reader:
image: repositry:5000/my-company.com/proj-reader
ports:
- "28090:8080"
- "28095:5005"
proj-helpdesk:
image: repository:5000/my-company.com/proj-helpdesk
ports:
- "29080:8080"
- "29085:5005"
proj-frontend:
image: repository:5000/my-company.com/proj-frontend
ports:
- "80:80"
links:
- "proj-helpdesk:backend"
- "proj-reader:reader"
...
Frontend is a nginx container with NodeJs application. And we have next nginx configuration:
upstream backend {
server backend:8080;
keepalive 30;
}
upstream reader {
server reader:8080;
keepalive 30;
}
server {
listen 80;
client_max_body_size 2m;
server_name localhost;
root /usr/share/nginx/html;
location /api/ {
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_pass http://backend;
proxy_read_timeout 600;
}
location /web-callback/ {
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_pass http://reader;
}
}
And sometimes I can see that request for /web-callback/ is recieved in other service which doesn't pointed in links section for frontend service. At first time I have thougt it happened after I have restarted reader service. But yerstaday this situation repeated and I know that reader haven't been restarted.
What cn it be? ANd how can I prevent this situation in future?
You should try to use:
location ^~ /api/ {
# Queries beginning with /api/ and then stops searching.
}
location ^~ /web-callback/ {
# Queries beginning with /web-callback/ and then stops searching.
}
https://www.keycdn.com/support/nginx-location-directive/

Resources