Raphael
Raphael

Reputation: 99

Static files are not loading for Django product on Digital Ocean

I am about to publish my first Django project on a Digital Ocean droplet. I was following the official Digital Ocean guide to install Django on a droplet (https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-22-04#creating-systemd-socket-and-service-files-for-gunicorn) and everything worked fine but the serving of static files.

Here are key parts of my files:

settings.py

BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_ROOT = os.path.join(BASE_DIR,"static")

STATIC_URL = '/static/'

DEBUG = False

COMPRESS_ROOT = os.path.join(BASE_DIR,"static")

COMPRESS_ENABLED = True

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'compressor.finders.CompressorFinder',
]

urls.py

urlpatterns = [
    ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Here is my folder structure on digital ocean:

root/
    snap/
    gymtracker/
        gymenv/
        gymtracker/
            gymtrackerapp/
            static/

I see on in the terminal on digital ocean that all static files are in this location:

/root/gymtracker/gymtracker/static/

but when I load the page I get 403 for the static files ( the page loads fine otherwise):

Request Method: GET

Status Code: 403 Forbidden

Thanks so much for your help!

Upvotes: 1

Views: 2389

Answers (3)

ewulff
ewulff

Reputation: 2259

This issue is related to the permissions nginx has over the generated static folder. There's no need to modify your Django settings, static folder location or nginx.conf values. Instead, the following should be sufficient.

Assuming the Ubuntu@22 user "sammy" is running nginx run:

  1. sudo usermod -a -G sammy www-data
  2. sudo chown -R :www-data /home/sammy/your_django_project_directory

This will result in nginx having enough permissions to access your static files. To test this out, you can try loading the files from a web browser like <your-domain-or-ip-address>/static/admin/css/base.css.

Upvotes: 0

ElRey777
ElRey777

Reputation: 321

The other solution works, while there are few alternatives. I think the safest way is to move the /static/ folder out of /home/{user}/ directory

Creating the directories and setting permissions:

sudo mkdir -pv /var/www/{project_name_or_domain_etc}/static/

sudo chown -cR {user}:{user} /var/www/{project_name_or_domain_etc}/

Now changing the NGINX config:

sudo nano /etc/nginx/sites-available/{project_name_or_domain_etc}

replace the "location /static/" part with

location /static/ {
    alias /var/www/{project_name_or_domain_etc}/static/;
}

sudo systemctl restart nginx

Will need to change the DJANGO settings as well, replace the "STATIC_URL = " lines with:

STATIC_URL = '/static/'
STATIC_ROOT = '/var/www/{project_name_or_domain_etc}/static'
STATICFILES_DIRS = [BASE_DIR / 'static']

Now run collectstatic and it should work! Based on https://realpython.com/django-nginx-gunicorn/#serving-static-files-directly-with-nginx

Upvotes: 2

Raphael
Raphael

Reputation: 99

Found the solution.

The Digital Ocean tutorial (https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-22-04#creating-systemd-socket-and-service-files-for-gunicorn) missed one important Nginx config change at the end to make your static resources show up.

After you follow the tutorial you need to edit /etc/nginx/nginx.conf and change the user from www-data to your username (e.g sammy) by running

sudo nano /etc/nginx/nginx.conf

Upvotes: 3

Related Questions