I have a quite standard Django application with a Vuejs frontend.
I have different environments (preprod
/dev
) in which I have file upload/download features.
For files, everything works fine because they are returned through standard API views in attachment (Content-Disposition: attachment
). When it comes to images though, like profile pictures, there is a problem.
In development (DEBUG=True
), I have this :
from django.conf import settings
from django.conf.urls.static import static
from django.urls import include, path
from backend.applications.base.views.authentication_views import LoginAPIView, LogoutAPIView
urlpatterns = [
path("api/login", LoginAPIView.as_view()),
path("api/logout", LogoutAPIView.as_view()),
path("api/base/", include("backend.applications.base.urls")),
path("api/contact/", include("backend.applications.contact.urls")),
path("api/helpdesk/", include("backend.applications.helpdesk.urls")),
path("api/inventory/", include("backend.applications.inventory.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # For serving media files when DEBUG=True
and images are correctly served (no nginx in dev mode, just frontend and backend dev servers django's runserver
).
My preprod however, is made of a nginx container which serves my built vuejs frontend, and a backend container which contains my Django (DEBUG=False
) application (which runs with gunicorn
this time, like this : gunicorn backend.wsgi:application --bind 0.0.0.0:8000 --access-logfile="-"
).
Before trying to serve images, I had this nginx configuration :
http {
client_max_body_size 5M;
upstream backend_api {
server backend:8000;
# 'backend' is the name of the backend service in my docker-compose config
}
server {
listen 80;
include /etc/nginx/mime.types;
root /usr/share/nginx/html;
index index.html;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location /api {
proxy_pass http://backend_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
location / {
try_files $uri $uri/ /index.html;
}
}
}
Then I thought that /media
requests should also be passed to the backend and I changed
location /api
into
location ~ ^/(api|media)/ {
My /api
URLs are still handled correctly but /media
URLs are answered by a 404 :
(trying to load profile pictures of my user(s) in a kanban view).
Also trying directly http://localhost/media/base/users/8/picture.jpg
directly in my browser doesn't work :
From here I don't know what to do to solve the issue. If something is missing, mention it and I'll update the post.