I’m trying to load static files using nginx and gunicorn, it works when i go to http://0.0.0.0/static/css/base.css
static hosted via nginx, but doesn’t when i add django port http://0.0.0.0:8000/static/css/base.css
static not found using django server
these are the errors i get in my nginx container
nginx_1 | 172.22.0.1 - - [04/Oct/2023:04:59:33 +0000] "GET /static/css/base.css HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-"
nginx_1 | 2023/10/04 04:59:34 [error] 8#8: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.22.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/static/css/base.css"
nginx_1 | 172.22.0.1 - - [04/Oct/2023:04:59:34 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost/static/css/base.css" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" "-"
This is all what I’ve tried, in conf.d i put container name as server_name and tried to add types to determine css files, but it didnt work
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'
Dockerfile
FROM python:3.10
ENV PYTHONDONTWRITEBYTECODE=1
PYTHONBUFFERED=1
POETRY_VERSION=1.4.2
POETRY_VIRTUALENVS_CREATE="false"
RUN pip install "poetry==$POETRY_VERSION"
WORKDIR /education_platform
COPY pyproject.toml poetry.lock docker-entrypoint.sh ./
RUN poetry install --no-interaction --no-ansi --no-dev
COPY . /education_platform
EXPOSE 8000
RUN chmod +x wait-for-it.sh
docker-compose.yaml
version: '3'
services:
db:
image: postgres:13.1-alpine
restart: unless-stopped
env_file:
- ./.env
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
cache:
image: redis:7.0.4
restart: unless-stopped
volumes:
- .data/cache:/data
web:
restart: unless-stopped
build:
context: .
dockerfile: Dockerfile
command: [ "/education_platform/wait-for-it.sh", "db:5432", "--",
"gunicorn", "education_platform.wsgi:application", "-b", "0.0.0.0:8000"]
env_file:
- ./.env
volumes:
- .:/education_platform
- ./static:/education_platform/static
ports:
- "8000:8000"
environment:
- DJANGO_SETTINGS_MODULE=education_platform.settings.prod
- POSTGRES_DB=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
depends_on:
- db
- cache
nginx:
image: nginx:1.23.1
restart: unless-stopped
volumes:
- ./config/nginx/conf.d:/etc/config/nginx/conf.d/default.conf
- ./static:/usr/share/nginx/html/static
ports:
- "80:80"
command: ["/bin/sh", "-c", "nginx -g 'daemon off;'"]
depends_on:
- web
conf.d
server {
listen 80;
server_name education_platform_web_1;
error_log stderr warn;
access_log /dev/stdout main;
location / {
proxy_pass http://education_platform_web_1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
}
location /static/ {
alias /usr/share/nginx/html/static/;
}
location /media/ {
alias /education_platform/media/;
}
types {
text/javascript js;
application/javascript js;
text/css css;
}
}
2
Answers
Renaming conf.d to nginx.conf,listening to Joris Jansen advices and changing nginx container ports to "1336:80" and achieving after that website by localhost:1336 solved my problem
There are a couple of things missing for as far as I could see:
In order to prevent an extensive command in your docker-compose file I would like to suggest to following in your Dockerfile itself:
from this (docker-compose):
to something like this (at the end of your Dockerfile):
Now you might be wondering, where did my
wait-for-it.sh
script went to? And what isentrypoint.sh
doing.Here is the
entrypoint.sh
file:And, one more thing, I see two ways of specifying environment variables. Both the env_file and environment entries are being used in your docker-compose file. Now, there might be a valid reason in your case, but if not, it might be better to use one or the other: