Reputation: 561
I'm trying to get django (on gunicorn) and nginx running with docker. Unfortunately, I keep getting a Bad Request (400)
error after I run docker-compose up -d --build
. Help.
I have tried changing directories, directory names, volumes, networks and exposed ports to no avail. I also tried adding and removing server_name
in my nginx.conf
file.
In settings.py
I have:
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
This is my docker-compose.yml
file:
version: '3.3'
services:
web:
build: ./app
command: gunicorn my_server.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./app/:/usr/src/app/
expose:
- 8000
environment:
- DATABASE=${DATABASE}
- SECRET_KEY=${SECRET}
- SQL_DATABASE=${POSTGRES_USER}
- SQL_ENGINE=django.db.backends.postgresql
- SQL_HOST=${POSTGRES_HOST}
- SQL_PASSWORD=${POSTGRES_PASSWORD}
- SQL_PORT=${POSTGRES_PORT}
- SQL_USER=${POSTGRES_USER}
- SU_NAME=${SU_NAME}
- SU_EMAIL=${SU_EMAIL}
- SU_PASSWORD=${SU_PASSWORD}
depends_on:
- db
logging:
driver: "json-file"
options:
max-size: "100k"
max-file: "20"
db:
image: postgres:11.2-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
logging:
driver: "json-file"
options:
max-size: "100k"
max-file: "20"
nginx:
build: ./nginx
restart: unless-stopped
volumes:
- static_volume:/usr/src/app/assets
ports:
- 80:80
depends_on:
- web
logging:
driver: "json-file"
options:
max-size: "100k"
max-file: "20"
volumes:
static_volume:
postgres_data:
external: true
and this is my nginx.conf
file:
upstream my_server {
server web:8000;
}
server {
listen 80;
location / {
proxy_pass http://my_server;
proxy_set_header Host $http_host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
}
location /assets/ {
alias /usr/src/app/assets;
}
location /robots.txt {
alias /var/www/html/robots.txt;
}
}
In my Dockerfile for django, I run makemigrations
and migrate
and I have confirmed that the database tables are created.
I expect to go to localhost
or 127.0.0.1
and see my website served there. Instead, I get this error: Bad Request (400)
.
When I run docker ps
I get:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2dbc6ff7be78 my_server_nginx "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp my_server_nginx_1
a6173e017c93 my_server_web "/usr/src/app/entryp…" 4 minutes ago Up 4 minutes 8000/tcp my_server_web_1
918e7bdae298 postgres:11.2-alpine "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 5432/tcp my_server_db_1
When I run docker logs my_server_nginx_1
I get lines like this:
172.18.0.1 - - [08/May/2019:22:25:07 +0000] "GET / HTTP/1.1" 400 37 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36" "-"
172.18.0.1 - - [08/May/2019:22:25:07 +0000] "GET /favicon.ico HTTP/1.1" 400 37 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36" "-"
Upvotes: 8
Views: 5501
Reputation: 1497
if you define allowed hosts in settings.py:
ALLOWED_HOSTS = ['localhost','127.0.0.1','my_domain.com']
if you define allowed hosts in .env as an environment
variable, you should use the following format (without brackets):
in .env file:
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 my_domain.com
and in settings.py
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1").split()
Upvotes: 0
Reputation: 561
While trying to implement upinder kumar's solution I stumbled upon the solution. I will add here for anyone else facing this problem in the future:
The nginx.conf
cannot have both
proxy_set_header Host $http_host;
and
proxy_set_header Host $host;
Deleting either one solved the problem.
Upvotes: 1
Reputation: 837
Create socket file using gunicorn and configure in our virtual host.
#############Gunicorn configuration###################
[unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=nginx
WorkingDirectory=/var/www/html/source
ExecStart=/var/www/html/env_source/bin/gunicorn --workers 3 --bind
unix:/var/www/html/source/source.sock application_name.wsgi:application
[Install]
WantedBy=multi-user.target
It will create file name source.sock just configure this sock file in nginx virtual host
###########nginx Configuratio server {
server_name example.com;
listen 80;
access_log /var/www/html//source/access.log;
error_log /var/www/html/source/error.log;
include /etc/nginx/default.d/*.conf;
location /static/ {
root /var/www/html/source/run;
}
location / {
proxy_pass http://unix:/var/www/html/source/source.sock;
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 $host;
}
}
Upvotes: 0
Reputation: 51938
Probaly you need to add my_server
to your allowed hosts(same as your upstream in NGINX config):
ALLOWED_HOSTS = ['my_server']
Upvotes: 7