I'm trying to have a docker container with nginx work as reverse proxy to other docker containers and I keep getting "Bad Gateway" on locations other other than the base location '/'.
I have the following server block:
server {
listen 80;
location / {
proxy_pass "http://game2048:8080";
}
location /game {
proxy_pass "http://game:9999";
}
}
It works for http://localhost but not for http://localhost/game which gives "Bad Gateway" in the browser and this on the nginx container:
[error] 7#7: *6 connect() failed (111: Connection refused)
while connecting to upstream, client: 172.17.0.1, server: ,
request: "GET /game HTTP/1.1", upstream: "http://172.17.0.4:9999/game",
host: "localhost"
I use the official nginx docker image and put my own configuration on it. You can test it and see all details here:
https://github.com/jollege/ngprox1
Any ideas what goes wrong?
NB: I have set local hostname entries on docker host to match those names:
127.0.1.1 game2048
127.0.1.1 game
I fixed it! I set the server name in different server blocks in nginx config. Remember to use docker port, not host port.
server {
listen 80;
server_name game2048;
location / {
proxy_pass "http://game2048:8080";
}
}
server {
listen 80;
server_name game;
location / {
# Remember to refer to docker port, not host port
# which is 9999 in this case:
proxy_pass "http://game:8080";
}
}
The github repo has been updated to reflect the fix, the old readme file is there under ./README.old01.md.
Typical that I find the answer when I carefully phrase the question to others. Do you know that feeling?
I had the same "502 Bad Gateway" error, but the solution was to tune proxy_buffer_size following this post instructions:
proxy_buffering off;
proxy_buffer_size 16k;
proxy_busy_buffers_size 24k;
proxy_buffers 64 4k;
See the nginx error log
sudo tail -n 100 /var/log/nginx/error.log
If you see Permission denied error in the log like below -
2022/03/28 03:51:09 [crit] 1140954#0: *141 connect() to
xxx.xxx.68.xx:8080 failed (13: Permission denied) while connecting to
upstream, client: xxx.xx.xxx.25, server: www.example.com
See whether the value of httpd_can_network_connect is enabled or not by running the command: sudo getsebool -a | grep httpd
If you see the value of httpd_can_network_connect is off then this is the cause of your issue.
Solution:
set the value of httpd_can_network_connect is on by run the command sudo setsebool httpd_can_network_connect on -P
Hope it will resolve your problem.
I had the same error, but for a web application that was just not serving at the IP and port mentioned in the config.
So say you have this:
location /game {
proxy_pass "http://game:9999";
}
Then make sure the web application that you expect at http://game:9999 is really serving from within a docker container named 'game' and the code is set to serve the app at port 9999.
For me helped this line of code proxy_set_header Host $http_host;
location / {
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;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://myserver;
}
In my case, after 4 hours, only I missed put the port with semanage command.
location / {
proxy_pass http://A.B.C.D:8090/test;
}
The solution was add 8090 port and works.
semanage port -a -t http_port_t -p tcp 8090
You have to declare an external network if the container you are pointing to is defined in another docker-compose.yml file:
version: "3"
services:
webserver:
image: nginx:1.17.4-alpine
container_name: ${PROJECT_NAME}-webserver
depends_on:
- drupal
restart: unless-stopped
ports:
- 80:80
volumes:
- ./docroot:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
networks:
- internal
- my-passwords
networks:
my-passwords:
external: true
name: my-passwords_default
nginx.conf:
server {
listen 80;
server_name test2.com www.test2.com;
location / {
proxy_pass http://my-passwords:3000/;
}
}
You may need to telnet on the upstream machine to check to wither it's connected:
tracing the /var/log/nginx/error.log would help.
Related
I'm trying to deploy simple FastAPI app with Docker and Nginx proxy on Google Cloud using simple ssh-terminal window.
My nginx.conf:
access_log /var/log/nginx/app.log;
error_log /var/log/nginx/app.log;
proxy_headers_hash_max_size 512;
proxy_headers_hash_bucket_size 128;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header Proxy "";
upstream app_server {
server example.com:8000;
}
server {
server_name example.com;
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /root/ssl/cert.pem;
ssl_certificate_key /root/ssl/key.pem;
location / {
proxy_pass "http://app_server";
}
}
My docker-compose.yml:
version: '3.8'
services:
reverse-proxy:
image: jwilder/nginx-proxy
container_name: reverse-proxy
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx:/etc/nginx/conf.d
- ./ssl/cert1.pem:/root/ssl/cert.pem
- ./ssl/privkey1.pem:/root/ssl/key.pem
- ./ssl/dhparam.pem:/etc/nginx/dhparam/dhparam.pem
networks:
- reverse-proxy
web:
environment: [.env]
build: ./project
ports:
- 8000:8000
command: gunicorn main:app -k uvicorn.workers.UvicornWorker -w 2 -b 0.0.0.0:8000
volumes:
- ./project:/usr/src/app
networks:
- reverse-proxy
- back
networks:
reverse-proxy:
external:
name: reverse-proxy
back:
driver: bridge
After run docker-compose up command and going to example.com address, I get error:
*3 upstream timed out (110: Connection timed out) while connecting to upstream...
Also, I have opened ports with Google Cloud Firewall service (checked with netstat command) and configured my VM's instance with network parameters from this article.
I don't understand why I receive 504 Gateway Time-out cause my service work with the similar configuration on a simple VPS hosting, and also it works from the inside Google Cloud VM's ssh-terminal when using curl and check localhost instead example.com domain. I want to know how to run my service on Google Cloud VM using only docker-compose util for this purpose?
In Nginx config file, try to mention the web container name:
upstream app_server {
server web:8000;
}
I have a setup that works successfully in Linux and MacOS, in which I run a docker nginx container to route all of my different services running locally.
The issue is that this same setup is throwing nginx Bad Gateway errors when running the docker container inside of Window's WSL2, presumably because I'm missing some additional routing configuration between Windows and WSL2.
A simplified version of my setup:
docker-compose.yml
nginx:
image: nginx:alpine
container_name: nginx
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
- 443:443
networks:
- backend
/config/nginx.conf
server {
listen 80;
server_name test.localhost;
location / {
set test.localhost host.docker.internal:3001;
proxy_pass http://test.localhost;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
server {
listen 80;
server_name test2.localhost;
location / {
set test2.localhost host.docker.internal:3002;
proxy_pass http://test2.localhost;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
windows hosts file
127.0.0.1 test.localhost
127.0.0.1 test2.localhost
WSL2 Debian /etc/hosts file
127.0.0.1 test.localhost
127.0.0.1 test2.localhost
Both services are running inside WSL2 at ports 3001 and 3002.
Browsing to localhost:3001 and localhost:3002 provides the expected result, but if I go to test.localhost or test2.localhost I get 502 Bad Gateway errors from nginx.
Any idea on what I may be missing or guidance will be greatly appreciated.
Maybe you could try with the workaround below, seen here.
127.0.0.1 test.localhost
::1 test.localhost localhost
You can use WSL2HOST which will automatically update your Windows hosts file with the WSL2 VM's IP address.
I've been trying to fix an issue which is when I try to login to pgAdmin (in docker container) behind Nginx Proxy I'm getting an error that The CSRF tokens do not match.
See https://en.wikipedia.org/wiki/Cross-site_request_forgery
Frankly, the problem is related within nginx or not I'm not sure but configuration files as below:
Docker Swarm Service :
pgAdmin:
image: dpage/pgadmin4
networks:
- my-network
ports:
- 9102:80
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}
- PGADMIN_CONFIG_SERVER_MODE=True
volumes:
- /home/docker-container/pgadmin/persist-data:/var/lib/pgadmin
- /home/docker-container/pgadmin/persist-data/servers.json:/pgadmin4/servers.json
deploy:
placement:
constraints: [node.hostname == my-host-name]
Nginx Configuration:
server {
listen 443 ssl;
server_name my-server-name;
location / {
proxy_pass http://pgAdmin/;
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-CSRF-Token $http_x_pga_csrftoken;
}
ssl_certificate /home/nginx/ssl/certificate.crt;
ssl_certificate_key /home/nginx/ssl/private.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_prefer_server_ciphers on;
server {
listen 80;
server_name my-server-name;
return 301 https://my-server-name $request_uri;
}
I can able to access to pgAdmin in two ways :
The first way is direct host ip like 172.23.53.2:9102
The second way is via Nginx proxy.
When I try to access to pgAdmin via direct host ip there is no error but when I try to access to via dns ( like my-server.pgadmin.com ) I'm getting an error when I logged into pgAdmin dashboard.
The error is :
Bad Request. The CSRF tokens do not match.
My first opinion about this error is nginx does not pass CSRF Token header to pgAdmin. For these reason I've changed nginx configuration file many many times but I'm still getting this error.
What could be source of this error and how could I solve this problem?
Try to use the default ports "5050:80". It's solved the same issue on my side.
Using strings is also recommended.
Cf: https://docs.docker.com/compose/compose-file/compose-file-v3/#ports
I used pgadmin4 deployed by Apache httpd,
the deployment method is similar, I also had the same problem,
my solution is Apache httpd loaded the lib of Apr/Aprl-util /pcre, Apache httpd will use token.
directory structure:
myapp
-- frontend
---- docker
------ frontend
-------- nginx
-------- nginx.conf
docker-compose.yml
docker-compose.yml: https://pastebin.com/THxMf0xM
(moved to pastebin to avoid that annoying "mostly code" error)
default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
location / {
proxy_pass http://vue:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
why do I get connect() failed (111: Connection refused) while connecting to upstream ?
https://pastebin.com/THxMf0xM line number 23, should be pointing to port 80 i.e. ports: - '8081:80'
fixed by changing proxy_pass http://vue:8081; to proxy_pass http://vue:8080;
notice the 8080 port.
secondly, rebuild the frontend service
and lastly, remove the ports option from vue service
thank you guys
First time using docker-compose. Attempting to set up a Nginx container as a webserver and a container that holds my dotnetcore app. The intention is for nginx to pass the call onto Kestrel. Both images build and run but getting error when accessing "http://localhost:8080":
proxy_1 | 2019/05/12 16:39:45 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://172.19.0.2:4000/", host: "localhost:8080"
The project structure is as follows:
Dockersingleproject
Dockersingleproject/ (dotnetcore app)
*app files'
DockerFile
Nginx/
nginx.conf
DockerFile
docker-compose.yml
I am under the impression that the issue is regarding the connection between the web server container and the app container is refusing but I cannot figure out why. Below is the app Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /Dockersingleproject
COPY bin/Debug/netcoreapp2.2/publish .
ENV ASPNETCORE_URLS http://+:4000
EXPOSE 4000
ENTRYPOINT ["dotnet", "Dockersingleproject.dll"]
The app docker file is exposing port 4000. The nginx.conf:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-nginx {
server app:4000;
}
server {
listen 8080;
location / {
proxy_pass http://docker-nginx;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
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;
proxy_cache_bypass $http_upgrade;
proxy_buffers 8 16k; # Buffer pool = 8 buffers of 16k
proxy_buffer_size 16k; # 16k of buffers from pool used for headers
}
}
}
The server is listening on port 8080 and proxies the request to port 4000 on server "app". Which is defined in the docker-compose file:
version: '2'
services:
app:
build:
context: ./Dockersingleproject
dockerfile: Dockerfile
ports:
- "4000:4000"
proxy:
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- "8080:8080"
links:
- app
The app service maps port 4000 requests to 4000 and in my head this should be working.
The IP of the nginx container is: 172.19.0.3
The IP of the app container is: 172.19.0.2
Please let me know where my confusion lies. I am on the point of accusing my PC of being the issue. Any information is appreciated.
Getting Connection refused when accessing the site resulting in a nginx 502 bad gateway
This uses the Microsoft-provided ASP.NET Core sample:
docker-compose.yaml:
version: "3"
services:
app:
image: mcr.microsoft.com/dotnet/core/samples:aspnetapp
expose:
- "80"
proxy:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- "8080:80"
NB
The ASP.NET Core sample runs on :80 and is expose'd
The Nginx container also runs on :80 and is exposed on the host on :8080
nginx.conf:
events {}
http {
server {
listen 80;
location / {
proxy_pass http://app:80;
}
}
}
NB
Nginx listens on :80 because its container requires it
The proxy configuration references the service name (app) on :80
And:
curl \
--silent \
--write-out "%{http_code}" \
--output /dev/null \
http://localhost:8080
200