Docker Compose with Express.js and Nginx - 502 response - docker

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.

Related

Docker - Nginx proxy_pass "502 bad gateway" only with client routes?

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.

Why does my static Docker give 502 errors?

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;
}

Local subdomains using Nginx and Docker Compose

I want to test different subdomains locally, using nginx and docker-compose.
docker-compose.yml:
version: '2'
services:
...
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: unless-stopped
ports:
- 8081:80
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: p4ssw0rd!
...
nginx:
build: ./backend/nginx
links:
- phpmyadmin
ports:
- "4000:80"
volumes:
- "./backend/nginx/nginx.conf:/etc/nginx/nginx.conf"
nginx.conf:
worker_processes 1;
events { worker_connections 1024; }
http {
sendfile on;
upstream docker-phpmyadmin {
server phpmyadmin:8081;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://docker-phpmyadmin;
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;
}
}
}
Nginx Dockerfile:
FROM nginx:alpine
COPY ./nginx.conf /etc/nginx/nginx.conf
etc/hosts:
127.0.0.1 example.com
127.0.0.1 api.example.com
127.0.0.1 admin.example.com
When I run my nginx container and I navigate to api.example.com:4000 on my browser I see a 502 Bad Gateway page, and inside the container I get this message:
nginx_1 | 2019/07/27 12:17:00 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.21.0.1, server: api.example.com, request: "GET / HTTP/1.1", upstream: "http://172.21.0.4:8081/", host: "api.example.com:4000"
I guess that it should work using the port 80 instead of the 4000 but how can I test my configuration locally?
Thanks
I was able to fix it by changing my upstream server port to 80:
upstream docker-phpmyadmin {
server phpmyadmin;
}

Running two Docker containers (1 reverse proxy nginx, the other a dotnetcore app)

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

Nginx reverse proxy for Docker containers

I have a problem with reverse proxy to my Docker services. I have a local machine with IP 10.0.0.163 and with Docker stack running on it with nginx and portainer (for this question only they matter).
docker-compose.yml:
...
portainer:
image: portainer/portainer
ports:
- "9000:9000"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/mnt/StorageDrive/Portainer:/data"
deploy:
placement:
constraints: [node.role == manager]
networks:
...
- proxy
reverse-proxy:
image: reverseproxy:latest
ports:
- "80:80"
networks:
- proxy
networks:
...
proxy:
nginx.conf:
worker_processes 1; ## Default: 1
events { worker_connections 1024; }
http {
sendfile on;
server {
listen 80;
allow all;
location / {
proxy_pass http://10.0.0.163:9000;
}
}
}
Dockerfile for reverseproxy image:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
When trying to access 10.0.0.163 I get error 502 and logs from reverseproxy show this:
2017/10/09 07:43:02 [error] 5#5: *1 connect() failed (113: Host is unreachable) while connecting to upstream, client: 10.255.0.2, server: , request: "GET / HTTP/1.1", upstream: "http://10.0.0.163:9000/", host: "10.0.0.163"
10.255.0.2 - - [09/Oct/2017:07:43:02 +0000] "GET / HTTP/1.1" 502 575 "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
When typing 10.0.0.163:9000/ into browser - everything works fine. What is the problem? And how can I make it work with this URL
10.0.0.163/portainer/... -> 10.0.0.163:9000/...
Try to change nginx configuration
server {
listen 80;
allow all;
location / {
proxy_pass http://portainer:9000/;
resolver 127.0.0.11;
}
}
portainer is container name defined into your docker-compose.yml file
127.0.0.11 is embedded docker DNS server
Also. Alternative way. You can use jwilder/nginx-proxy instead of your reverse-proxy.
The problem same me.
I resolve below,
# Docker run command
docker run --name portainer --network devops-net -d -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
# Nginx
location /portainer/ {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://portainer:9000/;
}
location /portainer/api/websocket/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_pass http://portainer:9000/api/websocket/;
}
# Notice
Portainer default port 9000
Open brower >> https://domain-name.dev/portainer
Read more: https://portainer.readthedocs.io/en/stable/faq.html
Work for me. ^____^

Resources