I have two docker containers: one running nginx and another running my server app in flask. When sending requests with HTTP, all of server's endpoints are reachable both directly and through nginx. However, after adding certificate using mkcert(and allowing exception in browser) only the index page of my server is reachable.
Below are my nginx.conf and relevant part of docker-compose.yml
nginx.conf
server {
listen 80;
server_name example.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
location / {
proxy_pass http://server:5000;
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;
}
}
docker-compose.yml
services:
server:
build:
context: ./server
dockerfile: Dockerfile.prod
container_name: flask
networks:
backend:
restart: always
command: gunicorn --bind 0.0.0.0:5000 run:app
volumes:
- ./server/:/usr/src/server/
expose:
- 5000
env_file:
- ./server/.env.prod
nginx:
build: ./nginx
container_name: nginx
networks:
backend:
frontend:
restart: always
ports:
- "8080:80"
- "443:443"
volumes:
- ./server/certs:/etc/nginx/certs
Attempting to reach any of the endpoints results in nginx responding with 404 not found error. Using address http://example.com redirects me 'Welcome to nginx!' successful installation site, making me believe that the redirect part of nginx.conf is somehow faulty as well.
I have used port 8080 as port 80 was in use. lsof -i :80 returned nothing.
This config is working for me:
events {
worker_connections 4096; ## Default: 1024
}
http {
server {
listen 80;
server_name example.internal.test;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.internal.test;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
location / {
proxy_pass http://server:8080;
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;
}
}
}
and:
services:
server:
image: adminer
restart: always
networks:
- frontend
nginx:
image: nginx
container_name: nginx
depends_on:
- server
restart: always
command: [nginx-debug, "-g", "daemon off;"] // add this for debugging
networks:
- frontend
ports:
- "80:80"
- "443:443"
volumes:
- ./server/certs:/etc/nginx/certs
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
frontend:
name: frontend
I used an adminer server instead of a flask app but the concept remains the same.
You can probably try checking if your /etc/hosts is properly configured for example.com. Also make sure you flush cache dscacheutil -flushcache
.
Finally try using curl instead of the browser. curl https://example.com --insecure
Make sure to add command: [nginx-debug, "-g", "daemon off;"]
to your docker file so you can debug if requests are arriving to your nginx server and if they are being redirected properly.