I'm trying to deploy a Django and React website using gunicorn, nginx and docker.
I can't get nginx to read my static files for example the django admin panel. I already ran python manage.py collecstatic and the files are in recommendations-be/backend/static
Here is the docker-compose.yml file:
version: '3'
services:
backend:
build:
context: ./recommendations-be
command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000 --timeout 0
ports:
- "8000:8000"
volumes:
- static:/django/backend/static
frontend:
build:
context: ./recommendations-fe
volumes:
- react_build:/react/build
nginx:
image: nginx:latest
ports:
- "80:8080"
volumes:
- ./nginx/nginx-setup.conf:/etc/nginx/conf.d/default.conf:ro
- react_build:/var/www/react
- static:/django/backend/static
depends_on:
- backend
- frontend
volumes:
static:
react_build:
Here is my nginx conf file:
upstream api {
server backend:8000;
}
server {
listen 8080;
location / {
root /var/www/react;
}
location /api/ {
proxy_pass http://api;
proxy_set_header Host $http_host;
}
location /static/ {
alias /django/backend/static;
}
}
Here's the Dockerfile in backend directory recommendations-be:
FROM python:3.10.8-slim-buster
ENV PYTHONUNBUFFERED 1
WORKDIR /django
COPY requirements.txt requirements.txt
RUN pip install --upgrade pip --no-cache-dir
RUN pip install -r requirements.txt --no-cache-dir
COPY . .
And the django settings.py:
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "backend", "static")
Here is the file structure in my project: file structure
In your nginx configuration, please make the following change:
location /static/ {
alias /static/
}
Then, in your docker-compose.yml file, in the volume definitions of Nginx, please replace the line
- static:/django/backend/static
with the following:
- static:/static
Nginx should now be able to serve your static files.
Related
I've been dealing with nginx for about 1 week. I have 4 services that I set up with docker, django postgresql fastapi and nginx, but nginx does not serve django's static files. I'm facing 403 error. I tried the solutions of all similar error fields, but it doesn't work (file permission granting file path control) below I am sharing the files I use please help.
docker-compose.yml:
django_gunicorn:
build: .
command: gunicorn sunucu.wsgi:application --bind 0.0.0.0:7800 --workers 3
volumes:
- ./static:/root/Kodlar/kodlar/static
env_file:
- .env
environment:
- DATABASE_URL="**"
ports:
- "7800"
depends_on:
- db
nginx:
build: ./nginx
volumes:
- ./static:/root/Kodlar/kodlar/static
ports:
- "80:80"
depends_on:
- django_gunicorn
volumes:
static_files:
Django Docker File:
FROM python:3.8-slim-buster
WORKDIR /app
ENV PYTHONUNBUFFERED=1
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
RUN python manage.py migrate --no-input
RUN python manage.py collectstatic --no-input
CMD ["gunicorn", "server.wsgi:application", "--bind", "0.0.0.0:7800","--workers","3"]
Django Settings py:
STATIC_URL = '/static/'
STATIC_ROOT = '/root/Kodlar/kodlar/static/'
DEBUG = False
Nginx Docker File:
FROM nginx:1.19.0-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
Nginx Conf File:
upstream django {
server django_gunicorn:7800;
}
server {
listen 80;
server_name mydomain.com;
error_page 404 /404.html;
location = /404.html {
root /root/Kodlar/kodlar/templates;
internal;
}
if ($host != 'mydomain.com') {
return 404;
}
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
alias /root/Kodlar/kodlar/static/;
}
}
I want my django service to run actively with gunicorn and serve static files in nginx
i am a beginner in the docker and i want to deploy my django project
using nginx and postgres on vps using docker so I create a dockerfile and docker-compose but it is not working it means that postgres is on the port but django and nginx is not working i don't have any idea can you help me
my dockerfile
FROM python:3.8-slim-buster
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y build-essential libpq-dev
RUN rm -rf /var/lib/apt/lists/*
COPY . .
RUN pip install --upgrade pip && pip install -r requirements.txt
my docker compose
version: '3.8'
services:
database:
container_name: database
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- postgres:/var/lib/postgresql/data
restart: always
app:
build:
context: .
container_name: django-app
command: >
sh -c "python3 manage.py migrate &&
gunicorn config.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static:/usr/src/app/static
- media:/usr/src/app/media
depends_on:
- database
environment:
- DEBUG=False
- ALLOWD_HOST=*
- DATABASE-NAME=postgres
- DATABASE-USER=postgres
- DATABASE-PASSWORD=postgres
- DATABASE-HOST=database
- DATABASE-PORT=5432
nginx:
image: nginx
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx:/etc/nginx/conf.d
- static:/var/www/static
- media:/var/www/media
volumes:
postgres:
static:
media:
I presume you want to serve Django static files in Nginx (reverse proxy feature in that case).You lack binding Nginx with Gunicorn served port and static file catalogue here.
So you will need to configure nginx to do that in the conf file.
For example. file default.conf
upstream backend {
server app:8000;
}
server {
listen 80;
# Django admin (if implemented)
location /admin {
proxy_pass http://backend;
autoindex off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
# Django static assests.
location /static/ {
autoindex off;
alias /usr/src/app/staticfiles/; # if thats where you copied your app files in docker container
}
Also will need static files to be configured in settings.py
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
static files regards catalogue in project root.
You will also have to make some dirs in Dockerfile for Django before you will copy project - in order to avoid error in collectstatic.
$WORKDIR your_workdir_path_in_docker_cotainer
# Make static files dirs in order to avoid error from collectstatic.
RUN mkdir $WORKDIR/staticfiles && \
mkdir $WORKDIR/staticfiles/admin && \ # if you implemented - to keep css/js
mkdir $WORKDIR/staticfiles/rest_framework #if you using DRF - to keep css/js
Last thing is to add add collectstatic command in you Docker-compose section where Gunicorn is started like.
command: >
sh -c "python manage.py migrate --noinput &&
python manage.py collectstatic --no-input &&
gunicorn config.wsgi:application --bind 0.0.0.0:8000"
Maybe its worthy to create separate Dockerfile for Nginx
FROM nginx:1.21-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY your_path_for_file/default.conf /etc/nginx/conf.d
CMD ["nginx", "-g", "daemon off;"] # To start Nginx
You can start that aditional container in Docker-compose by specifying path to Dockerfile
dockerfile: your_path_to_nginx_dockerfile/Dockerfile.nginx
Trying to deploy website with nginx + gunicorn + docker + django. But ngingx isn't serving static files. Following are the configurations:
Django project structure
settings file production.py
STATIC_URL = "/static/"
"""STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)"""
STATIC_ROOT = "/app/forex/static/admin/"
Docker file for nginx
FROM nginx:1.19.0
COPY ./default.conf /etc/nginx/conf.d/default.conf
nginx configurations
upstream django {
server website:8000;
}
server {
listen 80;
client_max_body_size 100M;
proxy_set_header X-Forwarded-Proto $scheme;
location / {
proxy_pass http://django;
}
location /media/ {
alias /app/media/;
}
location /static/ {
alias /app/forex/static/admin/;
}
}
Gunicorn docker file
FROM python:3
ADD requirements.txt /app/requirements.txt
ADD . /app
WORKDIR /app
EXPOSE 8000:8000
RUN pip install --upgrade pip && pip install -r /app/requirements.txt
RUN python manage.py collectstatic --no-input --settings=forex.settings.production
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "forex.wsgi:application", "DJANGO_SETTINGS_MODULE=forex.settings.production"]
docker-compose.yml
services:
website:
build:
context: .
dockerfile: Dockerfile.app
env_file:
- env
container_name: website_container_8
nginx:
build: ./nginx
volumes:
- static:/app/forex/static/admin/
ports:
- "80:80"
depends_on:
- website
volumes:
static:
FROM nginx container, it isn't copying static files.
What do I need to change to make it working?
Your files are located at your website container, you need to share it, with the nginx container:
services:
website:
build:
context: .
dockerfile: Dockerfile.app
env_file:
- env
container_name: website_container_8
volumes:
- static:/app/forex/static/admin/ #<-- you want to share this
nginx:
build: ./nginx
volumes:
- static:/app/forex/static/admin/ #<-- with this folder
ports:
- "80:80"
depends_on:
- website
volumes:
static: #<-- you can do it through this
I am trying to dockerize a django project and use nginx to serve static files. Everything seems to be working except the static files are not served. When I go to the admin page, always get Not Found: /django_static/rest_framework/css/prettify.css for files in django_static folder.
folder structure:
backend
server
apps
django_static
media
...
docker
backend
Dockerfile
wsgi-entrypoint.sh
nginx
production
default.conf
development
default.conf
Dockerfile
Here is my docker-compose:
services:
nginx:
build: ./docker/nginx
ports:
- 1234:80
volumes:
- ./docker/nginx/production:/etc/nginx/conf.d
- django_static:/app/backend/server/django_static
- media:/app/backend/server/media
depends_on:
- backend
restart: "on-failure"
backend:
build:
context: .
dockerfile: ./docker/backend/Dockerfile
entrypoint: /app/docker/backend/wsgi-entrypoint.sh
ports:
- "8001:8001"
volumes:
- django_static:/app/backend/server/django_static
- media:/app/backend/server/media
expose:
- 8001
volumes:
django_static:
media:
dockerfile for django:
FROM python:3.7-slim
WORKDIR /app
ADD ./backend/requirements.txt /app/backend/
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install --upgrade pip
RUN pip install gunicorn
RUN pip install -r backend/requirements.txt
ADD ./backend /app/backend
ADD ./docker /app/docker
wsgi-entrypoint.py
#!/bin/sh
until cd /app/backend/server
do
echo "Waiting for server volume..."
done
until ./manage.py migrate
do
echo "Waiting for db to be ready..."
sleep 2
done
./manage.py collectstatic --noinput
gunicorn server.wsgi --bind 0.0.0.0:8001 --workers 1 --threads 1
#./manage.py runserver 0.0.0.0:8003
nginx docker file:
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
CMD ["nginx", "-g", "daemon off;"]
nginx config file:
upstream glf {
server 0.0.0.0:8001;
}
server {
listen 80;
location / {
proxy_pass http://0.0.0.0:8001;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /django_static/ {
alias /app/backend/server/django_static/;
}
location /media/ {
alias /app/backend/server/media/;
}
}
settings.py
MEDIA_URL = '/media/'
STATIC_URL = '/django_static/'
STATIC_ROOT = BASE_DIR / 'django_static'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Any hint is appreciated!
I have this docker-compose.yml file:
version: '2'
services:
nginx:
image: nginx:latest
container_name: nz01
ports:
- "8001:8000"
volumes:
- ./src:/src
- ./config/nginx:/etc/nginx/conf.d
depends_on:
- web
web:
build: .
container_name: dz01
depends_on:
- db
volumes:
- ./src:/src
expose:
- "8000"
db:
image: postgres:latest
container_name: pz01
ports:
- "5433:5432"
volumes:
- postgres_database:/var/lib/postgresql/data:Z
volumes:
postgres_database:
external: true
And this dockerfile:
FROM python:3.5
ENV PYTHONUNBUFFERED 1
RUN mkdir /src
RUN mkdir /static
WORKDIR /src
ADD ./src /src
RUN pip install -r requirements.pip
CMD python manage.py collectstatic --no-input;python manage.py migrate; gunicorn computationalMarketing.wsgi -b 0.0.0.0:8000
The web and postgres server does not return an error log, just the success when I run docker-compose build and docker-compose up -d.
At this moment the three containers are running, but when I go to the browser and navigate to: localhost:8001 it does not work.
It shows the "connection has been restarted" error message.
Despite that, the web server still does not return any error, so I guess that I have everything properly configurated in my Django app. I really believe that the problem is related to Nginx, because when I review the Nginx log (using kinematic) it is still empty.
Why wouldn't Nginx be listening to connections?
Hint:
This error is happening in a new project. I tried to understand whether I have anything wrong, I'm running an old project and it works perfectly. I tried to copy the working project in my new folder and remove all existent containers and then try to run this old project in a new folder and there is the surprise. It does not work now, despite being an exact copy of the project that works in the other folder...
EDIT
In my repo I have a config/nginx folder with the helloworld.conf file:
upstream web {
ip_hash;
server web:8000;
}
server {
location /static/ {
autoindex on;
alias /src/static/;
}
location / {
proxy_pass http://web/;
}
listen 8001;
server_name localhost;
}
Still with the same error... I do not see any log error.
Django container log
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
No migrations to apply.
[2018-11-05 13:00:09 +0000] [8] [INFO] Starting gunicorn 19.7.1
[2018-11-05 13:00:09 +0000] [8] [INFO] Listening at: http://0.0.0.0:8000 (8)
[2018-11-05 13:00:09 +0000] [8] [INFO] Using worker: sync
[2018-11-05 13:00:09 +0000] [11] [INFO] Booting worker with pid: 11
You nginx configure should be like:
upstream web {
ip_hash;
server web:8000;
}
server {
location / {
proxy_pass http://web/;
}
listen 8001;
server_name localhost;
}
Since this kind of problems usually are difficult to debug/reproduce I have created dummy example to just run Django app and serve it via Nginx. You can try to adjust it to your needs. Please forgive me if I have missed something, or done that shouldn't be, but I'm unfamiliar with Django framework.
Dockerfile for Django container:
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code && \
pip install django
WORKDIR /code
ADD helloworld /code
docker-compose.yml:
version: '3'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
volumes:
- ./config/nginx:/etc/nginx/conf.d
depends_on:
- web
web:
build: .
container_name: django
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./helloworld:/code
expose:
- "8000"
config/nginx/django.conf:
upstream web {
ip_hash;
server web:8000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web/;
}
}
Django app is inside helloworld folder.
For this example, traffic is simply passed. Proper way would be using Unix sockets instead of ports but again I'm unfamiliar with Django.