pythondjangodjango-staticfilesdjango-storagedjango-static

Django: How to set a new static path in production?


working with django 3.0.5, but i guess this relates also to < django 2.0.

I uploaded my first django app on my providers space, so far everything works. This is a Server Schema of my Provider...

        _
         (`  ).
        (     ).                 .-------.        .-------.
       _(       '`.  ----------> | nginx | -----> | httpd |
   .=(`( Internet )              '-------'        '-------'
   ((    (..__.:'-'                  |                => php via php-fpm
   `(       ) )                      |                => static files
     ` __.:'   )                     |                => htaccess
            --'                      |
                                     |            .--------------.
                                     '----------> | Web Backends |
                                                  '--------------'
                                                      => per-user nginx
                                                      => nodejs, python, ruby, ...
                                                      => gogs, mattermost, matrix, ...

However i am still do not understand some Django Static logics. My static files are served via a separate Apache service. My App called blackbird

The following is like a web backend print

blackbird.abc/blackbird_assets apache
blackbird.abc http:8080 Ok, listening : PID 10104, vassalsuWSGI worker 2

This is like my server account dir looks like

User
|
'-blackbird_app
|     '- manage.py
'-hmtl <symbolic link to my documentroot>
    '- blackbird_assets
          '- static_storage
                 '-production_static
                      '-css
                      '-img

If i like to rename my production_static folder on my apache site to hello_static and reboot my app, django did not find the static files. Alright i guess, but on the other hand how could django even find production_static because this are my current settings.py

settings.py Production

DEBUG=false

INSTALLED_APPS = [
     <...>
    'django.contrib.staticfiles',
    ]

 STATIC_URL = '/static/'
 # STATIC_ROOT = ''
 # STATICFILES_DIRS  = ''

I also tried to set off the whole django.contrib.staticfiles and django can still find production_static without it, but not hello_static

The only time i mention explicit static folders was in Development. Before i collectstatic and uploaded it to my apache folder and via Git my App. Sidenote: i do not have static folders in my blackbird production app folder.

settings.py Development

 STATIC_URL = '/static/'
 STATIC_ROOT = '/static_storage/'
 STATICFILES_DIRS  = [os.path.join(BASE_DIR, env('STATICFILES_DIRS'))]
 # env('STATICFILES_DIRS') = static_storage/development_static

Question

The Django Doc said STATIC_ROOT is only for collectstatic. So i use it as an export folder in dev. But it seems internally a little bit more is happened? Otherwise Django would not look outside his Project Folder in my Production App for static_storage/development_static but when i set my folder to static_storage/hello_static it missed it to find.

STATICFILES_DIRS - (additional folders) as an option - only relates in reference to collectstatic, or miss i something?

Is django saving the static folder path after collectstatic in the project internally?

Is there a way to set a new explicit static path in production for Django or do i have set alias via apache to a new static folder? I read about it, but first i have to understand the logic of django.


Solution

  • Alright, between Front and Backend i must have overlooked that my uWSGIservice for my App is mapping my static folder / STATIC_URL. I forgot about this.

    On the other hand STATIC_ROOT is maybe semantically misleading - unlike MEDIA_ROOT - STATIC_ROOT is only collecting static files in a folder, when collectstatic is executed. I mixed that up. I guess something like STATIC_COLLECT would be more obvious, to differentiate.

    However now static and media files are working in my production.

    Soltuion

    blackbird_app.ini (uWSGI)


    set-placeholder = var_static=/home/user/html/blackbird_assets
    <...>
    static-map = /static=%(var_static)/static
    static-map = /media=%(var_static)/media
    <...>
    

    Whenever Django uses STATIC_URL or MEDIA_URL uWSGI will map everything i put in my apache.

    setting.py


    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    print("BASE_DIR:", BASE_DIR)
    # Server Base Level or Project Dev Map
    SERVER_DIR = os.path.dirname(BASE_DIR)
    print("SERVER_DIR:", SERVER_DIR)
    
    <...>
    
    > settings.py
    # --- STATIC_URL
    STATIC_URL = '/static/'
    
    # --- STATIC_ROOT
    STATIC_ROOT = os.path.join(SERVER_DIR, env('STATIC_ROOT'))
    print("STATIC_ROOT:", STATIC_ROOT)
    # --- STATICFILES_DIRS
    STATICFILES_DIRS = [os.path.join(SERVER_DIR, env('STATICFILES_DIRS'))]
    print("STATICFILES_DIRS:", STATICFILES_DIRS)
    
    # -- MEDIA_URL
    MEDIA_URL = '/media/'
    print("MEDIA_URL:", MEDIA_URL)
    
    # -- MEDIA_ROOT
    if DEVELOPMENT_MODE == True:
        MEDIA_ROOT = os.path.join(SERVER_DIR, env('MEDIA_ROOT_DEV'))   
    else:
        MEDIA_ROOT = env('MEDIA_ROOT_PROD')  
    print("MEDIA_ROOT:", MEDIA_ROOT)
    print("\n")
    

    I used that much print() to track the issue. On the other hand, from now on i will use it to get a better view in my app logs

    .env


    i use django-environ to set my vars.

    <...>
    STATICFILES_DIRS=dev_static
    STATIC_ROOT=static_root
    MEDIA_ROOT_DEV=media_root
    MEDIA_ROOT_PROD=/var/www/virt/user_name/html/blackbird_assets/media
    <...>
    

    At first i had an Issue with MEDIA_ROOT_PROD because i did not understand how to name the path correctly. My Provider for example used something like /home/virt/.... in the Doc´s also the Django Doc´s spoke about /var/www/example.com/media/. So i used the path that my SFTP und FTP Client showed me and now it works.