I use Docker Compose along with this Dockerfile that copies the static folder into /static:
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip && pip install -r requirements.txt
COPY static /static/
COPY . /code/
And in my settings files I use:
if env == "dev":
DEBUG = True
else:
DEBUG = False
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = "DENY"
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [
# os.path.join(BASE_DIR, "static/"),
'/static'
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
The static files are working in dev but when I change the env to prod, I start getting 404 errors.
So you see the problem ?
Note: This answer is also correct but I accepted the above answer too (since my app will receive very low traffic.)
Thanks for your comments. They were useful.
This is my new docker compose file:
version: '3.5'
services:
nginx:
image: nginx:latest
ports:
- "8002:8000"
volumes:
- $PWD:/code
- ./config/nginx:/etc/nginx/conf.d
- ./static:/static
depends_on:
- web
networks:
- my_net
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
env_file: .env
volumes:
- $PWD:/code
- ./static:/static
expose:
- "8000"
networks:
- my_net
networks:
my_net:
driver: bridge
And this is the Nginx conf file:
upstream web {
ip_hash;
server web:8000;
}
server {
location /static/ {
autoindex on;
alias /static/;
}
location / {
proxy_pass http://web/;
}
listen 8000;
server_name localhost;
}
You should also add "web" to the allowed hosts:
ALLOWED_HOSTS = ['0.0.0.0', 'localhost', 'web']
Update: settings.py file:
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
# '/static'
]
STATIC_ROOT = '/static' #os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
Also as @dirkgroten said you can set an expiry header in the static files your serve.
Another solution would be using Whitenoise ( Thanks Daniel Roseman ).
While it is **strongly discouraged* to serve static files from Django in production (and for VERY good reasons), I often need to anyway.
In some cases its perfectly acceptable (low traffic, REST API only server, etc). If you need to do that, this snippet should help out. Adjust the re_path
or use url()
if thats your django flavor.
from django.contrib.staticfiles.views import serve as serve_static
def _static_butler(request, path, **kwargs):
"""
Serve static files using the django static files configuration
WITHOUT collectstatic. This is slower, but very useful for API
only servers where the static files are really just for /admin
Passing insecure=True allows serve_static to process, and ignores
the DEBUG=False setting
"""
return serve_static(request, path, insecure=True, **kwargs)
urlpatterns = [
...,
re_path(r'static/(.+)', _static_butler)
]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.