I am running a dockerized Django application on an AWS EC2 instance, and the page loads without the static files, even though NGINX has them collected. I find this pretty strange, as it had not happened to me until now (at least on my local machine). It would be greatly appreciated if you could help me solve this issue.
This is my docker-compose.yml file:
version: "3"
services:
web:
restart: always
build: .
command: bash -c "
python manage.py makemigrations &&
python manage.py migrate &&
python manage.py creategroups &&
python manage.py initializesuperuser &&
python manage.py collectstatic --noinput &&
daphne -b 0.0.0.0 -p 80 DL.asgi:application"
expose:
- 80
environment:
- DJANGO_SETTINGS_MODULE=DL.production_settings
volumes:
- static_volume:/usr/src/app/DL/static/
- media_volume:/usr/src/app/media_cdn
nginx:
restart: always
build: ./nginx
ports:
- "80:80"
volumes:
- static_volume:/static/
- media_volume:/media/
depends_on:
- web
volumes:
static_volume:
media_volume:
Here's production_settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = "/usr/src/app/DL/static/"
A snippet of the file structure inside the web container (DL_app is the name of the Django app):
usr
|
|──src
|
|──app
|
|──DL
|
|──DL
|
|──DL_app
| |
| |──static
|
|──manage.py
|
|──static
And, lastly, here's nginx.conf:
upstream web {
server web:80;
}
server {
listen 80;
location / {
proxy_pass http://web;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_redirect off;
}
location /static/ {
alias /usr/src/app/DL/static/;
}
location /protected/ {
alias /media/;
}
}
You have mounted static files in nginx container at /static path:
nginx:
restart: always
build: ./nginx
ports:
- "80:80"
volumes:
- static_volume:/static/ # here
But your NGINX configuration defines they are at /usr/src/app/DL/static/
location /static/ {
alias /usr/src/app/DL/static/; # there is no such path in NGINX container
#alias /static/; # this should work
}
Related
In my project, I am using Django and nginx, but I want to manage my cloud databases through phpmyadmin.
Django is working fine but I can't do the same with phpmyadmin because it is running in apache at localhost:8080, when I want it to run in nginx at localhost/phpmyadmin.
here is the docker-compose.yml
version: "3.9"
services:
web:
restart: always
build:
context: .
env_file:
- .env
volumes:
- ./project:/project
expose:
- 8000
nginx:
restart: always
build: ./nginx
volumes:
- ./static:/static
ports:
- 80:80
depends_on:
- web
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
environment:
PMA_HOST: <host_address>
PMA_USER: <user>
PMA_PASSWORD: <password>
PMA_PORT: 3306
UPLOAD_LIMIT: 300M
ports:
- 8080:80
and nginx default.conf
upstream django{
server web:8000;
}
server{
listen 80;
location / {
proxy_pass http://django;
}
location /pma/ {
proxy_pass http://localhost:8080/;
proxy_buffering off;
}
location /static/ {
alias /static/;
}
}
I hope somebody will be able to tell me how to make nginx work as a reverse proxy for the phpMyAdmin docker container.
If some important information is missing please let me know.
You can access another docker container with its hostname and the internal port (not the exposed one).
Also a rewrite of the url is necessary.
location ~ \/pma {
rewrite ^/pma(/.*)$ $1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://phpmyadmin;
}
I tested with this docker-compose.yml:
version: "3.9"
services:
nginx:
image: nginx:latest
volumes:
- ./templates:/etc/nginx/templates
ports:
- 80:80
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
I am using the below docker compose 'local.yml' to run django on ec2 server
services:
django: &django
build:
context: .
dockerfile: ./compose/local/django/Dockerfile
image: name_docker
container_name: django
depends_on:
- mariadb
- mailhog
volumes:
- .:/app:z
env_file:
- ./.envs/.local/.django
- ./.envs/.local/.mariadb
oom_kill_disable: True
deploy:
resources:
limits:
cpus: '0.50'
memory: '3G'
ports:
- "8000:8000"
command: /start
it starts with start.sh script which is written as
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# python /app/manage.py collectstatic --noinput
/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:8000 --timeout 10000 --workers 5 --threads 5 --chdir=/app
On ec2 after deployment, server is running fine with gunicorn.
Now I added nginx configuration as
server {
listen 3000;
server_name domain_name.in;
access_log /var/log/nginx/django_project-access.log;
error_log /var/log/nginx/django_project-error.log info;
add_header 'Access-Control-Allow-Origin' '*';
keepalive_timeout 5;
# path for staticfiles
location /static {
autoindex on;
alias /static;
}
location / {
proxy_set_header Host $http_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_pass http://0.0.0.0:8000;
}
}
This configuration is also running fine and I can access it locally on example.in:3000.
But when I try to open admin page then I am not able to see static files there.
Also I tried to collectstatic with the below command
docker-compose -f local.yml run --rm django python manange.py collectstatic --no-input
The files are collected successfully.
What should i do to serve the static files ?
Map your /app/static/ folder from the container into a folder on the host, lets say: /home/ec2/static/ and make sure your nginx has access there.
volumes:
- /home/ec2/static/:/app/static
nginx.conf
...
location /home/ec2/static/ {
autoindex on;
alias /static/;
}
...
I'm building my first project with Django, NGINX and Docker. Below the nginx.conf:
upstream project {
server website:8000;
}
server {
listen 80;
server_name MY-DOMAIN;
location / {
proxy_pass http://project;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
client_max_body_size 4G;
}
location /static/ {
alias /app/static-folder/;
}
location /media/ {
alias /app/media-folder/;
}
}
And the docker-compose:
version: '3.7'
services:
website:
container_name: web_project
image: project/django
build: ./djangodocker
restart: always
env_file: prod.env
command: sh -c "cd djangodocker/ &&
gunicorn djangodocker.wsgi:application --bind 0.0.0.0:8000"
volumes:
- static-folder:/app/static-folder
- media-folder:/app/media-folder
expose:
- 8000
nginx:
container_name: nginx_web_project
image: project/nginx
build: ./nginx
volumes:
- static-folder:/app/static-folder
- media-folder:/app/media-folder
ports:
- 8000:80
depends_on:
- website
volumes:
static-folder:
media-folder:
I can build the image but I can't see the website into the correct url. I see the website at MY-DOMAIN:8000 instead of MY-DOMAIN and this is my problem.
You map the nginx port to port 8000 on the line
- 8000:80
in your docker-compose file. Change that to
- 80:80
That way, nginx listens on port 80 on the host machine and you don't need to specify the port number.
I am configuring Nginx for ASGI(with Daphne), WSGI(Gunicorn) as well as Redis and Postgres to deploy Django Project.
it was working find but all of sudden the browser is not able to access the server(172.0.0.1:1337) after set up django settings.py for check --deploy with following Nginx logs, I don't think it can cause problems because I just added some configurations in local compose file but compose.prod.yml for production.
I didn't set the .sh file yet, every pages that I googled for below messages mention those files for running docker-compose in production. would it be a problem not configuring that .sh file? but It was working even without the file.
which part should I check for this problem and any configurations that I need to add?
Thanks in advance!
if more information needed, let me know.
nginx | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
nginx | 10-listen-on-ipv6-by-default.sh: /etc/nginx/conf.d/default.conf is not a file or does not exist, exiting
nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
nginx Dockerfile
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
#########
EDIT
** here I changed 2nd line COPY ./nginx.conf /etc/nginx/conf.d/default.conf and now nginx logs display like below**
nginx | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
nginx | 10-listen-on-ipv6-by-default.sh: info: /etc/nginx/conf.d/default.conf differs from the packaged version
#########
Nginx.conf
upstream web {
server web:8000 fail_timeout=0;
}
upstream daphne {
server daphne:8001 fail_timeout=0;
}
server {
listen 80;
location / {
proxy_pass http://web;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /ws/ {
proxy_pass http://daphne;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /staticfiles/ {
alias /Users/kz/Desktop/projects/community_app/staticfiles/;
}
location /media/ {
alias /Users/kz/Desktop/projects/community_app/media/;
}
}
docker-compose.prod.yml
version: '3.8'
services:
web:
build: .
container_name: web
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/address/
- media_volume:/address/
expose:
- 8000
depends_on:
- commu_db
- redis
environment:
- "DJANGO_SETTINGS_MODULE=config.settings"
- "DJANGO_SECRET_KEY=##"
daphne:
build: .
restart: always
container_name: daphne
command: daphne -b 0.0.0.0 -p 8001 config.asgi:application
volumes:
- static_volume:/address/
- media_volume:/address/
expose:
- 8001
# ports:
# - "8001:8001"
environment:
- "DJANGO_SETTINGS_MODULE=config.settings"
- "DJANGO_SECRET_KEY=###"
depends_on:
- redis
- commu_db
- web
nginx:
build: ./nginx
container_name: nginx
volumes:
- static_volume:/address/
- media_volume:/address/
ports:
- 1337:80
depends_on:
- web
- daphne
commu_db:
image: postgres:13
container_name: postgres
volumes:
- postgres_test_data:/var/lib/postgresql/data/
ports:
- 5433:5432
environment:
- "POSTGRES_PASSWORD=postgres"
redis:
container_name: redis
hostname: comm_redis
restart: always
image: redis:5
ports:
- "6379:6379"
volumes:
postgres_test_data:
static_volume:
media_volume:
I currently have a Django website that runs on a server using Nginx an Docker. Every time I update my main css file and deploy it, nothing changes, despite hard refreshing the site. When new static files are added, they end up working, but modified files don't seem to change.
This led me to believing that nginx or Docker was caching the file.
I've tried the following:
Clearing the cache in the nginx container, setting the lines expires -1 and sendfile off, rebuilding the containers, with no luck.
The last time I had this problem, I believe I had to delete the volume for it to refresh, which I don't think is a good solution.
Can someone explain what I am doing wrong?
Settings:
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_FINDERS = [
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
nginx configuration:
upstream my_server {
server web:80;
}
server {
listen 80;
server_name mywebsite.com;
location / {
proxy_pass http://my_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $Host;
proxy_redirect off;
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location /static/ {
alias /code/staticfiles/;
expires -1;
}
}
server {
listen 443 ssl;
server_name mywebsite.com;
ssl_certificate /etc/letsencrypt/live/mywebsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mywebsite.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://my_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
location /static/ {
alias /code/staticfiles/;
expires -1;
}
}
Docker Compose File
version: '3.7'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
environment:
- ENVIRONMENT=production
- SECRET_KEY=#^la7#2kl%8$$o9rl)8$$aqvrwq5_x1=r!xc-1p#+(!m4r2vue*&
- DEBUG=0
- EMAIL_HOST_USER=apikey
- EMAIL_HOST_PASSWORD=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
volumes:
- .:/code
- static_volume:/code/staticfiles
networks:
- nginx_network
- db_network
depends_on:
- db
nginx:
image: nginx:1.17.0
ports:
- 80:80
- 443:443
volumes:
- ./config/nginx/conf.d:/etc/nginx/conf.d
- static_volume:/code/staticfiles
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
depends_on:
- web
networks:
- nginx_network
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s
reload; done & nginx -g \"daemon off;\"'"
db:
image: postgres:11
env_file:
- config/db/db_env
networks:
- db_network
volumes:
- db_volume:/var/lib/postgresql/data/
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew;
sleep 12h & wait $${!}; done;'"
networks:
nginx_network:
driver: bridge
db_network:
driver: bridge
volumes:
db_volume:
static_volume:
Dockerfile:
# Pull base image
FROM python:3.7
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Install dependencies
COPY Pipfile Pipfile.lock /code/
RUN pip install pipenv && pipenv install --system
# Copy project
COPY . /code/
RUN apt update
RUN apt install -y cron
CMD /code/script_prod.sh