Django static files not serving in Nginx - python

My first website with Django on hobby production.
I'am follow the setting guide this tutorial https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-20-04#checking-for-the-gunicorn-socket-file
my setting.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media/')
and my nginx config
server {
listen 80;
server_name MYIP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/azhimeblog/needhobby;
}
location /media/ {
root /home/azhimeblog/needhobby;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
This result

Related

Django/Nginx - 403 on Static Files

I've recently uploaded a django project to an Ubuntu 22.04 DigitalOcean droplet. Nginx, gunicorn, and postgres have all been set up without a hitch, but the static files are all being 403'd.
In both development and production, I never used collectstatic. The reason being, I always put all my static files in a static folder in the root of my project, so I figured I didn't have to do it. I'm not sure if collectstatic needs to be done in order for static files to be shown in production, but it seems that other people have still encountered this problem even when they've done collectstatic.
My project on the server is called pyapps, and in that folder there are the static and media folders. The static folder is further broken down into css, js, and images folders. The media folder is further broken down into photos, then folder by year, month, then day, all of which correlate to the time the photos were uploaded.
Below are my settings.py, urls.py and /etc/nginx/sites-available/ files' code.
settings.py
STATIC_URL = 'static/'
STATICFILES_DIRS = [(os.path.join(BASE_DIR, 'static'))]
MEDIA_URL = 'media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py
urlpatterns = [
...
] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
/etc/nginx/sites-available/Car-terra
server {
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
alias /home/djangoadmin/pyapps/Car-terra/static/;
}
location /media/ {
alias /home/djangoadmin/pyapps/Car-terra/media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
server {
if ($host = www.carterrarfw.online) {
return 301 https://$host$request_uri;
} # managed by Certbot
}
if ($host = carterrarfw.online) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name 146.190.210.138 carterrarfw.online www.carterrarfw.online;
return 404; # managed by Certbot
}
What I've Tried
chmod 777 on the static folder (in retrospect not a good choice, but it didn't work nonetheless)
changing root /home/djangoadmin/pyapps/Car-terra; to alias /home/djangoadmin/pyapps/Car-terra/static/ and media;
changing debug to True just to see if there was a difference (there wasn't)
I'm not sure if this is a problem with collectstatic, or if I'm telling nginx to look in the wrong place.
Is running collectstatic absolutely mandatory?
Thank you for your help.

Multiple websites on single VPS (nginx + centos + django)

I'm using VPS with nginx + centos + django. I already have one website running on it. Now i want to add one more domain, but after reading a lot of articles i still have troubles with it.
Here is my nginx.conf file:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;
server {
listen 443 ssl;
server_name website1.com www.website1.com;
ssl_certificate /etc/ssl/www.website1.com.crt;
ssl_certificate_key /etc/ssl/www.website1.com.key;
location /static/ {
root /var/www/website1;
index index.html index.htm index.php;
}
location / {
root /var/www/website1;
proxy_pass http://127.0.0.1:8888;
index index.html index.htm index.php;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
}
}
server {
listen 80;
server_name website1.com www.website1.com;
return 301 https://$host:443$request_uri;
location = /favicon.ico {
alias /var/www/website1/static/img/favicon.png;
}
location /static/ {
root /var/www/website1;
index index.html index.htm index.php;
}
location / {
root /var/www/website1;
proxy_pass http://127.0.0.1:8888;
index index.html index.htm index.php;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
}
}
server {
listen 443 ssl;
server_name website2.com www.website2.com;
ssl_certificate /etc/ssl/www.website2.com.crt;
ssl_certificate_key /etc/ssl/www.website2.com.key;
location /static/ {
root /var/www/website2;
index index.html index.htm index.php;
}
location / {
root /var/www/website2;
proxy_pass http://127.0.0.1:8888;
index index.html index.htm index.php;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
}
}
server {
listen 80;
server_name website2.com www.website2.com;
return 301 https://$host:443$request_uri;
location = /favicon.ico {
alias /var/www/website2/static/img/favicon.png;
}
location /static/ {
root /var/www/website2;
index index.html index.htm index.php;
}
location / {
root /var/www/website2;
proxy_pass http://127.0.0.1:8888;
index index.html index.htm index.php;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
}
}
}
I've tried using one short main file and two files for each website with
server blocks same as in the file above. In this case both website doesn't open at all.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/sites-enabled/*.conf;
server_names_hash_bucket_size 64;
}
Here is my django settings file, it is almost the same for both domains, so i leave here only one
"""
Django settings for apartment project.
Generated by 'django-admin startproject' using Django 2.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os
# Logging settings for django projects, works with django 1.5+
# If DEBUG=True, all logs (including django logs) will be
# written to console and to debug_file.
# If DEBUG=False, logs with level INFO or higher will be
# saved to production_file.
# Logging usage:
# import logging
# logger = logging.getLogger(__name__)
# logger.info("Log this message")
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'website1.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'website1.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'website1', "static")
]
What i'm doing wrong? Now it seems to me both website adress the same path, so i get the same content for different domains, but i can't find where is my mistake.
it seems for me, you are trying to start django manually, at some port and connect it with nginx
but it is wrong, nginx can serve only static files, and defualt django core python manage.py runserver isn't good enough to use it in production, it is only for testing purpose. You need to connenct it with gunicorn, gunicorn can serve scripts, and nginx for static files. I'll share my configuration which is 100% working with multiple django projects, but i use it on ubuntu
this example project called mail, so you can change "mail" on what you want
mail project deployment:
mkdir mail
cd mail
virtualenv venv
source venv/bin/activate
pip install django gunicorn nginx
django-admin.py startproject mail ~/mail
nano ~/mail/mail/settings.py
in settings.py add:
8.a) import os
8.b) ALLOWED_HOSTS = ["*"]
8.c) TIME_ZONE = 'Europe/Moscow'
8.d) STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
python manage.py runserver 0.0.0.0:8000
13.a) go to "(ip)0.0.0.0:8000/admin" in your browser
the site should work and css styles should be in the admin panel
gunicorn --bind 0.0.0.0:8000 mail.wsgi
14.a) (run command above^^ in a folder with manage.py )
14.b) go to "(ip)0.0.0.0:8000/admin" the site should work and css styles MUST NOT work
deactivate
sudo nano /etc/systemd/system/mail.service
Carefully replace all the words "mail" with the name of your project,
/home/admin/mail >> this is root folder (in config under), keep it in mind, you can check your real path to your project by typing pwd command inside your projects folder
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=admin
Group=www-data
WorkingDirectory=/home/admin/mail
ExecStart=/home/admin/mail/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/admin/mail/mail.sock mail.wsgi:application
[Install]
WantedBy=multi-user.target
sudo systemctl start mail
sudo systemctl enable mail
in the mail project folder (where manage.py ) The file SHOULD (MUST) appear “mail.sock”, if it doesn't go to 16 paragraph, you made misstake there
list your folders:
~/mail$ ls
output should look like this:
db.sqlite3 mail mail.sock manage.py static venv
sudo systemctl status mail
it will check status of service for project mail, which should start it with gunicorn
Nginx configuration:
sudo nano /etc/nginx/sites-available/mail
replace mail in the config with your project (3 places and 1 address)
/home/admin/mail >> this is root folder (in config under), keep it in mind, you can check your real path to your project by typing pwd command inside your projects folder
server {
listen 80;
server_name adress.mail.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/admin/mail;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/admin/mail/mail.sock;
}
}
sudo ln -s /etc/nginx/sites-available/mail /etc/nginx/sites-enabled
23.a) cd /etc/nginx/sites-enabled
23.b) type ls
project mail must appear in this folder
sudo nginx -t
this will check nginx for errors
sudo systemctl reload nginx
next you need to assign a domain name in this example adress.mail.com to your ip adress of you virtual machine, with CNAME or A type. But if you have no any domains name, you can assign you ip adress server_name 222.333.444.555;, but in this case you can't use different port, so no multiple django projects for you (buy a domain)
your project will work super good if you done all correctly, if you want to add one more project, just simply redo everything in this list

Django admin dashboard CSS is missing

I just deployed my application to DigitalOcean. Everything works very well, excep admin panel's styling although I've used nginx. Here are my codes:
settings.py:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static_root")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
nginx configuration:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static_root/ {
root /home/my_username/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/my_username/myproject/myproject.sock;
}
}

How to configure static and media files with django and nginx?

I have next settings.py on my local server.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_root")
MEDIA_URL = '/media/'
MEDIA_ROOT= os.path.join(os.path.dirname(BASE_DIR), "media_root")
I know that in production Nginx should handle static and media. Okay.
I use gunicorn and supervisor on my prod server.
My nginx config:
server {
listen 8000;
server_name 194.87.95.46;
access_log /var/log/nginx/example.log;
location /static {
alias /home/split/static_root/;
}
location /media {
alias /home/split/media_root/;
}
location / {
proxy_pass http://127.0.0.1:8003;
proxy_set_header Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
But nginx doesnt handle static and media, what's the problem?
I think your issue is caused by trailing slashes - you haven't provided a trailing slash in the location definition, but you have in the alias. Try this instead:
location /static/ {
alias /home/split/static_root/;
}
location /media/ {
alias /home/split/media_root/;
}

django+nginx deployment not loading static files correctly

server {
listen 80;
server_name 13.xx.xx.xxx;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/studykarma/django-react-redux-base/src/;
}
location / {
include proxy_params;
include /etc/nginx/mime.types;
proxy_pass http://unix:/home/ubuntu/studykarma/django-react-redux-base/src/djangoreactredux.sock;
}
}
my nginx config file
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static_dist'),
)
my settings.py
I have my static files in static_dist folder and my reactjs code in static
folder.
My static files are not loading and giving me 404,
If i change path to /static_dist/ then also i am getting empty content.
I am using this template: https://github.com/Seedstars/django-react-redux-base
About Nginx configuration
location /static/ {
root /home/ubuntu/studykarma/django-react-redux-base/src/;
}
This configuration tells Nginx that on accessing via say example.com/static/app.js, look app.js file inside src folder root, if you want static_dist, then the configuration change will be
location /static/{
root /home/ubuntu/studykarma/django-react-redux-base/src/path/to/static_dist/;
}
About Django configuration
Your Django settings is logically wrong,
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
Above settings tells django that you expect all your static files from STATICFILES_DIRS to STATIC_ROOT, the configuration is effective/used by django when you use collectstatic django manage command, which ineffect copies all your files from STATICFILES_DIRS to STATIC_ROOT( but this also means that, you have to point /static/ location nginx config to static_root instead of static_dist.
Use this,
location /static_root/ { root /home/ubuntu/studykarma/django-react-redux-base/src/static_r‌​oot/; }
it will work

Categories

Resources