0

I have a Django Rest Framework project running on a subpath /api, together with the frontend on the root /. When I go to /api and /api/admin I get messages in the console saying that the static is missing. The urls listed are /static/... instead of the expected /api/static/.... I found out that this was bug a bug in Django before version 3.1 by looking at the answers to related questions. Hence I upgraded to version 3.2.2. This should have fixed the problem, but it did not. Neither did clearing cache, recollecting static and restarting apache. What else could be the issue?

Note: An environment with the same apache settings works when not placed on a subpath and not behind the proxy.

The errors

enter image description here enter image description here

Settings:

My pip packages:

  • apache2.4
  • django version 3.2.2
  • python 3.8
  • djangorestframework 3.11.2

My Apache conf:

<VirtualHost *:443>
        ...
        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off
        ProxyPreserveHost on
        ProxyPass "/admin" "https://localhost:8081/api/admin"
        ProxyPassReverse "/admin" "https://localhost:8081/api/admin"
        ProxyPass "/api" "https://localhost:8081/api"
        ProxyPassReverse "/api" "https://localhost:8081/api"

        <Directory ${docroot}>
                Options FollowSymlinks
                Require all granted
                FallbackResource /index.html
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/frontend-error.log
        CustomLog ${APACHE_LOG_DIR}/frontend-access.log combined
</VirtualHost>

<VirtualHost *:8081>
        ...
        <Directory ${docroot}/${project}>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIDaemonProcess API python-path=${docroot}:${docroot}/venv/lib/python3.8/site-packages display-name=api
        WSGIProcessGroup API
        WSGIScriptAlias /api ${docroot}/${project}/wsgi.py process-group=API
        WSGIPassAuthorization On

        Alias /robots.txt ${docroot}/${project}/static/robots.txt
        Alias /favicon.ico ${docroot}/${project}/static/favicon.ico

        Alias /media ${docroot}/${project}/media
        Alias /static ${docroot}/${project}/static

        <Directory ${docroot}/${project}/static>
                Require all granted
        </Directory>

        <Directory ${docroot}/${project}/media>
                Require all granted
        </Directory>

        <DirectoryMatch "^/.*/\.git/">
                Require all denied
        </DirectoryMatch>

        ErrorLog ${APACHE_LOG_DIR}/api-error.log
        CustomLog ${APACHE_LOG_DIR}/api-access.log combined
</VirtualHost>

My django static settings:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = os.path.join('media/')
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = 'static/'

Links

Explanation of how to do the apache:

Similar issues:

Link for how django commit/branch explaning how to enable static on subpath:

ChocolateRain
  • 203
  • 2
  • 9

2 Answers2

0

you have to replace this ${docroot}/${project}/static with this /${docroot}/${project}/static for more information check this post https://stackoverflow.com/a/24947686/14457833

Ankit Tiwari
  • 4,438
  • 4
  • 14
  • 41
0

After a bunch of testing and fiddling with parameters, it turns out that the environ variable SCRIPT_NAME which control the static url prefix is not getting recognized. If I add FORCE_SCRIPT_NAME = "/api", then the SCRIPT_NAME should always be "/api". However, it is not prefixed in the static urls. I do not know why this happens. This should have been fixed in django 3.1+.

This is a my workaround. This is by not a proper solution, but hopefully it is of use to someone.

My new Apache conf:

<VirtualHost *:443>
        ...
        SSLProxyEngine on
        SSLProxyVerify none
        SSLProxyCheckPeerCN off
        SSLProxyCheckPeerName off
        SSLProxyCheckPeerExpire off
        ProxyPreserveHost on
        ProxyPass "/admin" "https://localhost:8081/api/admin"
        ProxyPassReverse "/admin" "https://localhost:8081/api/admin"
        ProxyPass "/api" "https://localhost:8081/api"
        ProxyPassReverse "/api" "https://localhost:8081/api"

        <Directory ${docroot}>
                Options FollowSymlinks
                Require all granted
                FallbackResource /index.html
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/frontend-error.log
        CustomLog ${APACHE_LOG_DIR}/frontend-access.log combined
</VirtualHost>

<VirtualHost *:8081>
        ...
        <Directory ${docroot}/${project}>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIDaemonProcess API python-path=${docroot}:${docroot}/venv/lib/python3.8/site-packages display-name=api
        WSGIProcessGroup API
        WSGIScriptAlias /api ${docroot}/${project}/wsgi.py process-group=API
        WSGIPassAuthorization On

        Alias /robots.txt ${docroot}/${project}/static/robots.txt
        Alias /favicon.ico ${docroot}/${project}/static/favicon.ico

        Alias /api/media ${docroot}/${project}/media
        Alias /api/static ${docroot}/${project}/static

        <Directory ${docroot}/${project}/static>
                Require all granted
        </Directory>

        <Directory ${docroot}/${project}/media>
                Require all granted
        </Directory>

        <DirectoryMatch "^/.*/\.git/">
                Require all denied
        </DirectoryMatch>

        ErrorLog ${APACHE_LOG_DIR}/api-error.log
        CustomLog ${APACHE_LOG_DIR}/api-access.log combined
</VirtualHost>

My new django static settings:

FORCE_SCRIPT_NAME = "/api"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/api/media'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/api/static/'
ChocolateRain
  • 203
  • 2
  • 9