Nginx can't find specific location - docker

I'm trying to run django + gunicorn + nginx by using docker-compose.
django and gunicorn now are working correctly and response to request, but, when I try to access to project within nginx (port 80), it can't find my project location.
following are nginx Dockerfile and nginx.conf:
FROM nginx:1.17.4-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/
and nginx.conf:
upstream back {
# in docker-compose.yml file, (django+gunicorn) service name is `backend` and is listening on port 8000.
server backend:8000;
}
server {
listen 80;
location /backend {
proxy_pass http://back;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
Now, gunicorn is listening on port 8000 and responses to requestes. if I go to 127.0.0.1, I see nginx default page. But if I go to 127.0.0.1/backend/, nginx shows me 404 page.
in docker-compose logs it shows me following line:
[error] 6#6: *1 open() "/usr/share/nginx/html/backend" failed (2: No such file or directory), client: 192.168.176.1, server: localhost, request: "GET /backend HTTP/1.1", host: "127.0.0.1" <br>
It seems, nginx are searching for /backend in his folders in usr/share and does not pass request to port 8000.
How can I solve this problem?
UPDATE
this is docker-compose.yml file:
version: '3'
services:
db:
...
redis:
...
backend:
hostname: backend
depends_on:
- db
- redis
volumes:
- ./backend/app/:/opt/
build:
context: .
dockerfile: ./backend/Dockerfile
working_dir: /opt/app/project
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
env_file:
- ./backend/.env
ports:
- 8000:8000
nginx:
image: nginx
build:
context: .
dockerfile: ./nginx/Dockerfile
ports:
- 80:80
depends_on:
- backend

I'm not very familiar with gunicorn, but your configuration looks basically correct.
When nginx does the proxy_pass, the path /backend is also proxy_pass'ed to your backend-service.
I assume, that your gunicorn does not know how to handle the /backend-path?
Maybe it would help, if you rewrite everything to /:
nginx.conf:
upstream back {
# in docker-compose.yml file, (django+gunicorn) service name is `backend` and is listening on port 8000.
server backend:8000;
}
server {
listen 80;
location /backend {
# # # this rewrites all requests to '/backend' to '/' ...
# # # ... before passing them to your backend-service
rewrite /backend.* / break;
# # #
proxy_pass http://back;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
I've adapted your docker-compose.yml for easy testing purposes:
docker-compose.yml:
version: '3'
services:
backend:
image: nginx:alpine
hostname: backend
expose:
- 80
nginx:
image: nginx:alpine
ports:
- 8080:80
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
default.conf:
upstream back {
# in docker-compose.yml file, (django+gunicorn) service name is `backend` and is listening on port 8000.
server backend:80;
}
server {
listen 80;
location /backend {
rewrite /backend.* / break;
proxy_pass http://back;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
docker-compose up:
╰─❯ docker-compose up
Starting test_backend_1 ... done
Starting test_nginx_1 ... done
Attaching to test_backend_1, test_nginx_1
backend_1 | 172.21.0.3 - - [03/Apr/2020:11:53:52 +0000] "GET / HTTP/1.0" 200 612 "-" "curl/7.64.1" "172.21.0.1"
nginx_1 | 172.21.0.1 - - [03/Apr/2020:11:53:52 +0000] "GET /backend HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"
curl:
╰─❯ curl localhost:8080/backend
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
nginx.org.<br/>
Commercial support is available at
nginx.com.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Related

nginx redirect http to https in docker container connection refused

I have a working redirect from HTTP traffic to HTTPS traffic. The environment consists of a flask application in a docker container that is being routed through an NGINX docker container. Below is the nginx.conf file. After running docker-compose up I am able to get the containers active. After running curl localhost, I am getting a 301 Moved Permanently. However, when running curl https://localhost, I am getting a curl: (7) Failed to connect to localhost port 443: Connection refused. I checked my local computer network settings on macOS Big Sur, and the firewall is turned off (any traffic should be allowed in). I'm not sure what else I need to do to get this to work. I have also exposed the port 443 in the docker-compose file for the nginx container. Any advice would be helpful.
NGINX.conf
http {
upstream flask {
server app:8000;
}
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/nginx/files/localhost.crt;
ssl_certificate_key /etc/nginx/nginx/files/localhost.key;
location / {
proxy_pass http://flask;
proxy_set_header Host "localhost";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Docker Compose
version: "3"
services:
app:
container_name: app
command: gunicorn --bind 0.0.0.0:8000 --workers 2 "app.server:app"
volumes:
- ./:/var/www
build: app
ports:
- 8000:8000
networks:
MyNetwork:
aliases:
- flask
nginx:
container_name: nginx
build: nginx
volumes:
- ./:/var/www
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
expose:
- "443"
networks:
- MyNetwork
networks:
MyNetwork:
At first you should add port 443 to your docker-compose like this:
ports:
- 80:80
- 443:443
Then you should volume /etc/nginx/nginx/files:
volumes:
- ./:/var/www
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/nginx/files:/etc/nginx/nginx/files

Nginx Reverse proxy for a docker container running at port 80

My docker compose looks like this:
version: '3.2'
services:
mediawiki:
image: mediawiki:lts
nginx:
image: nginx:stable-alpine
depends_on:
- mediawiki
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
#...
Where mediawiki is a docker container that runs on port 80 in docker and does not appear to have a way to change the port number.
I'm trying to expose mediwiki through ngninx and the nginx config looks like this:
events {
}
http {
server {
listen 80;
location / {
client_max_body_size 2M;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_pass http://mediawiki:80;
}
}
}
Since both nginx and mediawiki is running at port 80, I can't set portmap mediwiki 80:80.
I've tried mapping it to another port under mediawiki such as 7001:80 and in nginx config replace http://mediawiki:80 with http://mediawiki:7001 but this produces bad gateway error when loading the site url at port 80.
How might I fix this?
Let's have a look at reverse proxy in which case I use.
version: '3.2'
services:
mediawiki:
image: mediawiki:lts
nginx:
build: .
image: A_NEW_NAME:VERSION_TAG
depends_on:
- mediawiki
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./wiki.conf:/etc/sites-available/wiki.conf
ports:
- 80:80
This should be your wiki.conf contents:
server {
listen 80;
server_name THE_DOMAIN_NAME_OF_YOUR_MEDIAWIKI;
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_pass http://mediawiki:80;
proxy_redirect off;
# Socket.IO Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
And add a Dockerfile in the directory where your docker-compose file is:
FROM nginx:stable-alpine
COPY wiki.conf /etc/sites-available/
RUN cd /etc/sites-enabled/ && ln -s /etc/sites-available/wiki.conf
And keep your nginx.conf as default values, or change some values on your own but do not add any directives to serve wiki.
You can replace THE_DOMAIN_NAME_OF_YOUR_MEDIAWIKI wit the actual domain name. Like if you have media.com and your wiki wants to be accessible at wiki.media.com.
Now you can run docker-compose up -d --build and see the result.
Change the service port for media wiki to 8080, like
8080:80
and
Change the nginx port to 7001 inside the local nginx.conf and
proxy_pass http://mediawiki:8080;
./nginx.conf:/etc/nginx/nginx.conf
So, nginx will run on port 7001 and mediawiki on 80.
version: '3.2'
services:
mediawiki:
image: mediawiki:lts
nginx:
image: nginx:stable-alpine
depends_on:
- mediawiki
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:7001
#...
Then access the app at http://mediawiki:80

nginx container: unknown directive "events", .conf error

I'm using a nginx container with docker lihe proxy server. The real function is redirect the request from http://127.0.0.1:7003 to my asp .net rest app with expose port in 5000.
So I have been investigating where is the sintaxys error and what is happening.
nginx-container | 2020/01/28 08:34:06 [emerg] 1#1: unknown directive "events" in /etc/nginx/conf.d/Local.Project.Core.conf:1
nginx-container | nginx: [emerg] unknown directive "server" in /etc/nginx/conf.d/Local.Project.Core.conf:1
So there is my nginx Dockerfile:
FROM nginx:latest
# Copy virtual hosts config
RUN rm /etc/nginx/conf.d/default.conf
COPY ./wwwroot/config/Local.Project.Core.conf /etc/nginx/conf.d/
My docker compose where I put the connexions:
local-project:
image: project-mysql-image
container_name: project-mysql-container
ports:
- 127.0.0.1:7000:80
- 127.0.0.1:7001:433
- 127.0.0.1:7002:5000
expose:
- "5000"
environment:
ASPNETCORE_ENVIRONMENT: Production
ASPNETCORE_URLS: http://+:80;http//+:433;http:+:5000 # Is going to use Kestrel standard 5000 port, only http connection
ASPNETCORE_Kestrel__Certificates__Default__Path: /etc/ssl/certs/Local.Proyect.Core.pfx
ASPNETCORE_Kestrel__Certificates__Default__Password: local
volumes:
- .\wwwroot\cer\Local.Proyect.Core.cer:/etc/ssl/certs/Local.Proyect.Core.pfx
nginx:
image: nginx-image
container_name: nginx-container
ports:
- 127.0.0.1:7003:80
And the most important, the file.conf:
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
include /etc/nginx/sites-enabled/*;
upstrem project-mysql-container { server project-mysql-container:5000; }
server {
listen 80;
root /;
index index.html index.htm index.nginx-debian.html;
server_name *.Local.Project.Core;
location / {
proxy_pass http://project-mysql-container:5000;
}
location /ws/ {
proxy_pass http://project-mysql-container:5000/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
}
In your nginx configuration, you have upstrem project-mysql-container .... That upstrem should be upstream.

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

Resources