I am trying to create a docker deployable django site with a seperate static Nginx server. This used to work fine, but suddenly stopped working. I now keep getting 502 errors when trying to access the static folder. The Django app is running on a gunicorn server.
This is my nginx.conf
# nginx.default
upstream staticserver {
ip_hash;
server staticserver:9010;
}
server {
location / {
proxy_pass http://127.0.0.1:8010;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
proxy_pass http://staticserver;
}
listen 9000;
server_name localhost;
}
My docker compose is this
version: '3'
services:
staticserver:
build:
context: .
dockerfile: ./staticserver/Dockerfile
ports:
- "9010:80"
djangoserver:
build:
context: .
dockerfile: Dockerfile
ports:
- "9000:9000"
depends_on:
- staticserver
If I go to 127.0.0.1:9000 I get the django site
If I go to 127.0.0.1:9010 I get the root of the static server
But, if I go to 127.0.0.1/static I get a 502 error.
The logs show entries like these
[error] 10#10: *25 connect() failed (111: Connection refused) while connecting to upstream, client: 172.21.0.1, server: localhost, request: "GET /static HTTP/1.1", upstream: "http://172.21.0.2:9010/static", host: "127.0.0.1:9000"
This seems counterintuitive, as I'd expect it to be http://172.21.0.2:9010/ with the static folder names stripped.
I've tried some of the other answers on relating topics, but so far, it seems it just stopped working. I suspect some issue in the config files that I am simply not aware of, but I can't seem to find my mistake.
Referring to a port on the inner network solved the issue;
upstream staticserver {
ip_hash;
server staticserver;
}
instead of
upstream staticserver {
ip_hash;
server staticserver:9010;
}
Related
I have a web service powered via plotly dash running in a docker container reverse proxied by an nginx container, all coordinated via docker compose.
docker-compose.yaml
services:
reverse_proxy:
image: nginx:1.17.10
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:Z,ro # nginx configuration
- ../../resources:/usr/share/nginx/html/:Z,ro # static assets, 404.html etc
- /etc/pki/tls/certs/:/etc/pki/tls/certs/:Z,ro # SSL stuff
ports:
- "80:80"
- "443:443"
depends_on:
- my_server
my_server:
image: my_server:v1.2.3
command: --config /app/configs/prod.yaml --port 8050 8051
nginx.conf
upstream my_server {
ip_hash;
server my_server:8050;
server my_server:8051;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl;
server_name my-server.com;
root /usr/share/nginx/html; # I assume this has something to do with it!
ssl_certificate /etc/pki/tls/certs/2022/my-server.crt;
ssl_certificate_key /etc/pki/tls/certs/2022/my-server.key;
ssl_password_file /etc/pki/tls/certs/2022/my-server.txt;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /prod/app/ {
proxy_pass http://my_server/;
proxy_redirect off;
proxy_buffering 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;
}
location = / {
root /usr/share/nginx/html; # or this...?
index index.html;
}
Upon running docker compose up --remove-orphans --force-recreate --renew-anon-volumes
I see the success message that my Dash server is running:
Dash is running on http://0.0.0.0:8050/
and the nginx container starts without error. However when I query my service via https://my-server.com/prod/app/
nginx fails to (cache?) and load plotly Dash javascript within its specified root directory:
# the location seems to be found and routed correctly
10.10.193.8 - - [28/Oct/2022:15:31:21 +0000] "GET /prod/app/ HTTP/1.1" 200 5324 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0" "-"
# fails due to css file not found
my-server-reverse_proxy-1 | 2022/10/28 15:31:21 [error] 7#7: *1 open() "/usr/share/nginx/html/assets/styles.css" failed (2: No such file or directory), client: 10.10.193.8, server: my-server.com, request: "GET /assets/styles.css?m=1666209805.0 HTTP/1.1", host: "my-server.com", referrer: "https://my-server.com/prod/app/"
# fails due to javascript not found
my-server-reverse_proxy-1 | 2022/10/28 15:31:21 [error] 7#7: *1 open() "/usr/share/nginx/html/_dash-component-suites/dash/dcc/dash_core_components.v2_6_2m1666209805.js" failed (2: No such file or directory), server: my-server.com, request: "GET /_dash-component-suites/dash/dcc/dash_core_components.v2_6_2m1666209805.js HTTP/1.1", host: "my-server.com", referrer: "https://my-server.com/prod/app/"
To debug I examined the contents of my nginx container the root directory does exist:
root#4c7190ea055a:/usr/share/nginx/html# ls
404.html 40x.html 50x.html bg.jpg index.html
I am not sure which of the following is causing this error:
nginx mis-configuration (I need to specify the server block root dir somewhere else?)
plotly Dash mis-configuration (I need to tell it to cache / load somewhere else?)
nginx docker volume issue (Doesnt seem to be the issue since I can view the folder inside the container?)
Any help is greatly appreciated!
I have the following docker compose:
version: '3.1'
services:
backend:
container_name: backend
image: backendnode
restart: always
ports:
- 3000:3000
frontend:
container_name: frontend
image: frontnginx
restart: always
ports:
- 4200:80
apigw:
image: reverseproxy
restart: always
ports:
- 80:80
depends_on:
- frontend
- backend
This is the reverseproxy image nginx.conf:
worker_processes auto;
events { worker_connections 1024; }
http {
server {
listen 80;
server_name localhost 127.0.0.1;
location / {
proxy_pass http://frontend:4200;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /api {
proxy_pass http://backend:3000;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
When running docker-compose run, I get the following results:
localhost:80/api/users: works great, nginx redirects to backend properly.
localhost:80/index.html: not working, I get the following error:
connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: localhost, request: "GET /index.html HTTP/1.1", upstream: "http://172.20.0.5:4200/index.html", host: "localhost:80"
Frontend is a simple nginx web server, this is its nginx.conf:
events{}
http {
include /etc/nginx/mime.types;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
}
Any idea why reverse proxy it's not working with frontend routes?
Created answer from the comment thread:
Docker networking works like this: if you use communication within docker's network, you need to refer to the internal ports. Since port mapping is used for the "outside world". So in your case, you would need to refer to "frontend:80" instead of 4200.
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
I'm trying to use express.js and nginx as a reverse proxy with Docker. The express app works fine with docker on its own, but when I add nginx I get 502 response. It prints this:
nginx_1 | 2019/03/30 21:14:04 [error] 6#6: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:20000/", host: "localhost:21000"
docker-compose.yml
version: '3.3'
services:
app:
image: node:latest
volumes:
- ./app:/usr/src/service/app
working_dir: /usr/src/service/app
command: ["node", "app"]
ports:
- 20000:18000
nginx:
image: nginx:latest
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/error.log:/etc/nginx/error_log.log
- ./nginx/cache/:/etc/nginx/cache
ports:
- 21000:80
nginx.conf
events {
}
http {
upstream upstream_server {
server localhost:20000;
}
server {
listen 127.0.0.1;
listen 80;
server_name localhost;
location / {
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://upstream_server;
break;
}
}
}
Your nginx container & app container are on the same network but not on the same host - hence localhost is not where you'll find your app running.
Try app as the server parameter in upstream - this should resolve to the IP of the app container in the compose network.
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.