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/
Related
I need to run QGIS server together with NGINX. I have to setup the environment using docker-compose. I am using the docker-compose file as mentioned in the comment.
And nginx.conf as below -
events {
worker_connections 4096;
}
http {
# error_log /etc/nginx/error/error.log warn; #./nginx/error.log warn;
client_max_body_size 20m;
proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;
server {
listen 80;
server_name xx.xx.xx.xxx;
# return 301 https://localhost:80$request_uri;
return 301 https://$server_name$request_uri;
# return 301 https://localhost:8008;
}
server {
listen 443 ssl http2;
server_name xx.xx.xx.xxx; # localhost;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
#ssl_certificate /etc/nginx/ssl.crt;
#ssl_certificate_key /etc/nginx/ssl.key;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:EECDH:EDH:!MD5:!RC4:!LOW:!MEDIUM:!CAMELLIA:!ECDSA:!DES:!DSS:!3DES:!NULL;
ssl_prefer_server_ciphers on;
keepalive_timeout 70;
location /qgis/ {
proxy_pass http://qgis:8080;
proxy_set_header X-Forwarded-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;
proxy_set_header Host $http_host;
}
}
}
After docker-compose up the nginx container is always in restarting state. docker-compose logs are as below -
web_server_1 | 2021/05/12 16:53:45 [emerg] 1#1: host not found in upstream "qgis" in /etc/nginx/nginx.conf:40
web_server_1 | nginx: [emerg] host not found in upstream "qgis" in /etc/nginx/nginx.conf:40
Thanks in advance!!
Use something like this as docker-compose.yml
services:
web_server:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./mime.types:/etc/nginx/conf/mime.types
- ./public:/data/www
- ./tile_cache:/tile_cache
- ./logs:/logs
ports:
- "80:80"
- "443:443"
restart: always
networks:
tile_network:
aliases:
- webserver
qgis_server:
image: camptocamp/qgis-server
volumes:
- ./qgisserver:/etc/qgisserver/
restart: always
environment:
- QGIS_PROJECT_FILE=/etc/qgisserver/project.qgs
networks:
tile_network:
aliases:
- qgis
Add in you nginx.conf the following location:
location /qgis/ {
proxy_pass http://qgis/;
proxy_set_header X-Forwarded-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;
proxy_set_header Host $http_host;
}
So you have a web server, that hide the QGIS Server and show it on ULR localhost/qgis
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;
}
I want to implement different ports for different docker containers . If request to 8080 port ,it should go nginx container and so on.
my docker-compose file
version: "3"
services:
ngnix:
image: nginx
ports:
- "8080:80"
volumes:
- ./nginx.conf/:/etc/nginx/nginx.conf
command: [nginx-debug, "-g", "daemon off;"]
apache:
image: httpd
command: bash -c "httpd -D FOREGROUND"
ports:
- "8081:80"
and my nginx.conf file below :
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
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;
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
}
}
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_redirect off;
}
}
}
But it does not work .Where is my mistake I spent my all time ?
I'm new with Docker and I'm setting up a new application where I have 2 services on my docker-compose file:
# Contains all my API servers
api_load_balancer:
build: ./microservices/load_balancer
restart: always
ports:
- "8080:80"
# Contains all my client servers
server_client:
build: ./microservices/client
ports:
- "80:80"
....
My microservices/load_balancer nginx.conf looks like this:
events { worker_connections 1024; }
http{
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream api_nodes {
server api_1:9000;
}
upstream socket_nodes {
ip_hash;
server socketio_1:5000;
}
# SERVER API
server {
location /socket.io/ {
proxy_set_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://socket_nodes;
# enable WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api/ {
proxy_set_header Access-Control-Allow-Origin *;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://api_nodes;
}
}
}
My load_balancer/Dockerfile looks like this:
FROM nginx:alpine
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./ssl ./etc/nginx/ssl
EXPOSE 80
When I try to connect from my client I'm able to do it from my client's server (using the api_load_balancer connection string as they're in the same docker network), but, when I try to do a call from the browser I need to change my connection string to something like localhost:8080 or some.ip.in.public.server:8080.
I don't like the idea of exposing neither my port nor my API configuration like that, so is there any way that I can implement a more transparent connection between those microservices? I don't know if it's even possible to do so.
I have two containers running on my DigitalOcean droplet. The first container is a REST api container running on port 9090. The second container is a ReactJS multistage container with Nginx running on port 4500. The docker-compose file is this:
version: '3'
services:
ubgrillmysql:
image: mysql:5.6
container_name: ubgrillmysql
environment:
- MYSQL_ROOT_PASSWORD=finder
- MYSQL_DATABASE=ubgrillData
- MYSQL_USER=ubgadmin
- MYSQL_PASSWORD=win(der90)Admin
volumes:
- /home/justicar/workspace/applications/data
networks:
- ubgrill_network
web:
image: ubgrill/web
container_name: web
depends_on:
- ubgrillmysql
environment:
- DATABASE_HOST=ubgrillmysql
- DATABASE_USER=ubgadmin
- DATABASE_PASSWORD=win(der90)Admin
- DATABASE_NAME=ubgrillData
- DATABASE_PORT=3306
ports:
- 9090:9090
networks:
- ubgrill_network
frontend:
image: ubgrill/frontend
container_name: frontend
build: ./src/main/ubgrill
depends_on:
- web
ports:
- 4500:80
networks:
- ubgrill_network
networks:
ubgrill_network:
external:
I have installed nginx on my droplet as I intend to transfer my blog there in the future. I created a server block using mu droplet's domain name and stored in /etc/nginx/sites-available with the name <domain>.com. The file is as follows:
upstream ubgrillapi{
server localhost:9090;
}
upstream ubgrillapp{
server localhost:4500;
}
server {
listen 80;
listen [::]:80;
root /var/www/<domain>.com/html;
index index.html index.htm;
server_name <domain>.com www.<domain>.com;
location / {
try_files $uri $uri/ =404;
}
location /ubgrill/api/ {
proxy_pass http://ubgrillapi;
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 /ubgrill/app/ {
proxy_pass http://ubgrillapp;
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;
}
}
When I try to access, http://<domain>.com/ubgrill/app, I get a 404(Not Found) error. The same goes for http://<domain>.com/ubgrill/api. I can access the app at http://<domain>.com:4500 and the api at http://<domain>.com:9090/ubgrill/api (The API actually starts with /ubgrill/api). I am a complete noob in nginx proxy and the tutorials online all deal with nginx in a separate container which is not my configuration. What is the problem with my configuration and can you please point me to a more comprehensive tutorial on nginx? Thanks.
In nginx conf :
proxy_pass http://ubgrillapp;
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Nginx proxy_pass shows the location
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
(http://example.com:9090/ubgrill/api)
In your case you i guess you should set this to:
proxy_pass localhost:9090/ubgrill/api