How can I serve Django static files via nginx Docker container? - django

During development I like to deploy Django static files in an as close to production as possible setup. To achieve this I wrap the Django backend into an image (Dockerfile) and frontend JS and backend Django static files into another image together with nginx configured as webserver (Dockerfile_nginx). The setup is as follows:
File system structure:
<projekt-repo>
/frontend
/backend
/static (generated with python manage.py collectstatic)
settings.py
manage.py
nginx.conf
Dockerfile
Dockerfile_nginx
settings.py:
STATIC_ROOT = os.path.join(BASE_DIR, "backend/static")
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
nginx.conf:
server {
listen 0.0.0.0:8080;
root /var/www;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 0.0.0.0:8000;
root /var/www/django;
location /static/ {
autoindex on;
alias /var/www/django/static/;
}
}
Dockerfile_nginx:
FROM nginx:1.17.8-alpine
COPY nginx.conf /etc/nginx/conf.d/nginx.conf
COPY edge_frontend/www /var/www
COPY edge_backend/static /var/www/django/static
If I run the application and try to login via the Django admin site (localhost:8000/admin) the site is not styled properly and the log output states
backend | Not Found: /static/admin/css/base.css
backend | Not Found: /static/admin/css/login.css
backend | Not Found: /static/admin/css/responsive.css
backend | Not Found: /favicon.ico
backend | Not Found: /static/admin/css/base.css
backend | Not Found: /static/admin/css/login.css
backend | Not Found: /static/admin/css/responsive.css
backend | Not Found: /favicon.ico
Obviously there is some mismatch in the setup which I am not able to spot right now? Can someone help?

create a folder in your project with the name "static" and then
add in your settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
or you want another path?

You have to set BASE_DIR, STATIC_URL and STATIC_ROOT in settings.py as below...
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
And run python manage.py collectstatic

Related

Django admin interface missing css styling in production

The user interface is working well, and all CSS styling and static files are served correctly, but the admin interface is missing CSS styling. I looked at similar posts but in those posts people had the issue with both the user and the admin interface. My issue is only with the admin interface.
Please see my static file settings below from settings.py:
STATIC_URL = '/static/'
#Location of static files
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
And this is my nginx configuration:
server {
listen 80;
server_name MY_SERVER_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/MYUSERNAME/myproject;
}
location /media/ {
root /home/MYUSERNAME/myproject;
}
I already executed python manage.py collectstatic on the server and got this message:
0 static files copied to '/home/MYUSERNAME/myproject/staticfiles', 255 unmodified.
I restarted nginx after that and also tried emptying my browser cache, but the issue persisted.
More info as requested by #Omar Siddiqui.
Using Django 3.2
My mysite/urls.py contains:
from django.contrib import admin
from django.urls import path, include
# Imports to configure media files for summernote editor
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('qa.urls')),
path('summernote/', include('django_summernote.urls')),
path('chatbot/', include('chatbot.urls')),
]
# Enable media files for summernote editor
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Could you please try below steps and let me know if it's working or not?
Apply below changes in settings.py file:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Remove below line from your settings.py:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
Execute below command in production:
python manage.py collectstatic
Update nginx file like below one:
server {
listen 80;
server_name MY_SERVER_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
autoindex on;
autoindex_exact_size off;
root /home/MYUSERNAME/myproject;
}
location /media/ {
autoindex on;
autoindex_exact_size off;
root /home/MYUSERNAME/myproject;
}
}
Explanations:
STATIC_ROOT is the folder where static files will be stored after
using python manage.py collectstatic
STATICFILES_DIRS is the list of folders where django will search for additional static files aside from the static folder of each app installed.
In this case our concern was Admin related CSS files that why we use STATIC_ROOT instead of STATICFILES_DIRS
Try changing STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') to:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Then re-run python manage.py collectstatic. This has worked in the past for some people
Try passing an alias to the static location in nginx, like so:
location /static/ {
alias /home/MYUSERNAME/myproject/staticfiles/
}
Don't forget to restart nginx afterwards.

Cannot upload media files in Django production to external folder

I have an issue on my Django production server.
When I try to upload images, they always go to the app/media/ folder.
However I want them to be uploaded to /mnt/data.
In the admin panel, when I upload the image, it is always uploading in the app/media/ folder.
I tried adjusting the Nginx config file and the settings.py, but I guess I am lost.
Here is my Nginx configuration:
location /static/ {
root /home/somthing/something/;
}
location /media/ {
root /mnt/data/;
}
and the Settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = (
os.path.join(BASE_DIR, 'media')
)
and in my model this is how I create the image:
pictures = models.ImageField(
upload_to='postings/',
verbose_name=_('Posting_picture'),
blank=True, null=True,
validators=[validate_image],
)
I guess following this configuration, the uploaded picture is supposed to be in mnt/data/media/postings.
The media folder on the mnt/data/ is chmod 777, I did it when I lost hope in writing/reading the folder.
Currently you are uploading to:
MEDIA_ROOT = (
os.path.join(BASE_DIR, 'media')
)
Basically means:
/path/to/project/media
In your case it should be:
MEDIA_ROOT = '/mnt/data'
I finally figured it out, Debendera was right for the path, but the Nginx configuration was wrong. I changed it to :
location /media/ {
alias /mnt/data/;
}
and then it worked. If I am not mistaken, it was better to use alias instead of root.
This is my reference: Nginx -- static file serving confusion with root & alias

Django Nginx Gunicorn - Media Files Not Showing (DigitalOcean Deployment)

I have deployed a Django project on Ubuntu 16.04 with Nginx and Gunicorn. I have gotten everything, including the static files but my media files will not serve properly.
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
models.py
resume_upload = models.FileField(blank=False, upload_to='resumes', null=True, validators=[FileExtensionValidator(allowed_extensions=['pdf']), validate_file_size])
What I have listed in /etc/nginx/sites-available/ is
server {
listen 80;
server_name website.com www.website.com ;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/syed/btawebsite;
}
location = /media/ {
root /home/syed/btawebsite;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/syed/myproject.sock;
}
}
I would like go on the admin, click on the uploaded file and be able to view the file in the browser. Anyone have any ideas on how I can achieve this? I have verified through using the terminal and looking through the directories that the files are in fact adding to ~btawebsite/media/resumes but I am unable to view them when I click the admin url.
When I click on that url I get an error:
Not Found
The requested resource was not found on this server.
Update:
I have changed settings.py to
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
And nginx settings to
location /static/ {
alias /home/syed/btawebsite/static/;
}
location = /media/ {
alias /home/syed/btawebsite/media/;
}
Static is still working, however, media is not.
For nginx configuration, the "=" sign after location means this is the exact location match. So change your settings to
location /media/ {
root /home/syed/btawebsite;
}
and same for /static/. It's correct for the favicon. For more about the nginx location directive, check this.

Django CDN with Nginx and uWSGI

I having difficulty serving static files with Django 1.10, uWSGI and Nginx.
I have an index.html file, which contains CDN's.
The Django documentation, which is here says to "transfer the static files to the storage provider or CDN." What does that mean, "transfer to the CDN"? Isn't the CDN where you get files from?
settings.py contains,
STATIC_URL = '/static/'
STATIC_ROOT = 'nonAppBoundStaticDirectory'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
Running
$ python manage.py collectstatic
does this place all CDN's in my directory 'nonAppBoundStaticDirectory'?
If so then how do i use that in the template?
Excerpt from index.html
<!-- Bootstrap -->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css">
Excerpy from /etc/nginx/nginx.conf
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name example.com; # substitute your machine's IP address or FQDN
charset utf-8;
#Max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/ofey/djangoForum/fileuploader/uploaded_files; # your Django project's media files
}
location /static {
alias /home/ofey/djangoForum/noAppBoundStaticDirectory; # your Django project's static files
}
........
Thanks,
It might be just a spelling mistake. In your settings.py you have an extra n in the directory name.
STATIC_ROOT = 'nonAppBoundStaticDirectory'
In your nginx config, you have a different spelling.
location /static {
alias /home/ofey/djangoForum/noAppBoundStaticDirectory;
Make sure that the path point to the exact same directory. It's can be a good idea to use absolute paths in both cases.
Working in development server
If you are working in development server- remove STATIC_ROOT from settings.py. Your settings.py should now look like this:
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
Production
If you are working in production- remove STATICFILES_DIRS from settings.py. Your settings.py should now look like this:
STATIC_URL = '/static/'
STATIC_ROOT = 'nonAppBoundStaticDirectory'
And don't forget to run:
python manage.py collectstatic

Static files in Nginx, Gunicorn in Django

i have try every configuration that i found and the static files don't get loaded, so i doesn't know what's wrong. I create the app using Pycharm.
Can someone give me a hand to fix this?
Here are the configurations.
settings.py
MEDIA_ROOT = ''
MEDIA_URL = '/Users/gcarranza/PycharmProjects/clouddemyTest/'
STATIC_ROOT = ''
STATIC_URL = '/Users/gcarranza/PycharmProjects/clouddemyTest/static/'
STATICFILES_DIRS = (
'/Users/gcarranza/PycharmProjects/clouddemyTest/static',)
nginx conf:
server {
listen 80;
server_name localhost;
location /static/ {
autoindex on;
alias /Users/gcarranza/PycharmProjects/clouddemyTest/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
}
}
Gunicorn:
gunicorn_django -b localhost:8000
You got the root and url backwards. Should be:
STATIC_ROOT = '/Users/gcarranza/PycharmProjects/clouddemyTest/static/'
STATIC_URL = '/static/'
And same for media