cookiecutter-django
cookiecutter-django copied to clipboard
Add option to serve media files locally using nginx
Description
This PR proposes an example solution to issue #2449. It allows selecting a local nginx instance to serve media files.
This is just a bare bones implementation that could serve as a base for serving media files.
I added an nginx container. This container has a volume mapped where django stores its media files. Routes and services are added in the traefik configuration to route {{domain.name}}/media/*
requests to the nginx instance which serves them.
Rationale
It makes deploying very simple and small scale projects easier as @demestav eloquently expressed in his issue.
Use case(s) / visualization(s)
When using AWS or GCP is not a good option. Serve the /media
files using nginx.
/media/ --> nginx -----------|
django ---> uwsgi -----------o--> user
/static/ -> whitenoise ------|
@ArkadiuszMichalRys, I pulled your version and got the following error:
Creating my_awesome_project_django_1_499f9d077e92 ... error
ERROR: for my_awesome_project_django_1_499f9d077e92 Cannot create container for service django: invalid volume specification: 'my_awesome_project_production_django_media:my_awesome_project/media:rw': invalid mount config for type "volume": invalid mount path: 'my_awesome_project/media' mount path must be absolute
ERROR: for django Cannot create container for service django: invalid volume specification: 'my_awesome_project_production_django_media:my_awesome_project/media:rw': invalid mount config for type "volume": invalid mount path: 'my_awesome_project/media' mount path must be absolute
Looks like there's a slash missing: services:django:volumes - production_django_media:my_awesome_project/media
should be services:django:volumes - production_django_media:my_awesome_project/media
.
@dahifi, thank you for the feedback. I will look into it. The two volume configurations you posted look identical so I guess there's a typo in the second one.
@dahifi, I should have tested my initial changes better. There were a few issues which should now be resolved. This time I tested the generated files without modifying anything so I couldn't forget to commit any changes I made.
Hi ! Thank you, I was exactly looking for something like this. I tried your setup, but have you tried it on production with https enabled ? For now I couldn't find my media. I'm digging into Nginx. Anyway, it's a good idea.
Edit : Okay after some trial and fails I manage to find out what's missing.
traefik.yml
rule: "Host(`pinock.io`) && PathPrefix(`/media/`)"
entryPoints:
- web-secure
middlewares:
- csrf
service: django-media
tls:
certResolver: letsencrypt
You need to add the :
tls:
certResolver: letsencrypt
Now it's working for me !
@sorasful Thank you for your suggestions! They were all justified so I implemented them as you suggested.
@sorasful Thank you for your suggestions! They were all justified so I implemented them as you suggested.
Great stuff, what's happened to this cool enhancement? I got that nginx media server going in no time! Thanks for that!
I think it might be because this seems like a very niche application. I just added it because I was using it for my own server. The repository seems to be aimed at more advanced deployments where you would really benefit from hosting the media on Amazon S3 or Google Cloud Storage.
I am happy to fix any issues in case there is something I need to add to get this merged.
I think it might be because this seems like a very niche application. I just added it because I was using it for my own server. The repository seems to be aimed at more advanced deployments where you would really benefit from hosting the media on Amazon S3 or Google Cloud Storage.
I am happy to fix any issues in case there is something I need to add to get this merged.
INHO, Cookiecutter leaves a hole by not providing an option for local media serving. @browniebroke What say you?
Thanks a lot! This was helpful to me.
Do we have news about this ? This could really be a great feature.
Do we need to fork this to fix conflict and merge this ?
Hey @sorasful,
I suppose we will need to fork and sort it out.
Thank you very much for this PR @arrys it helped me set this up for my project. Can you give advice on what needs to be further implemented so media links can only be accessed by logged in users?
Hopefully this helps you, @Braintelligence.
I don't know if this would be the best approach so take this with a grain of salt. Depending on your requirements you might just make the file names hard to guess. This is not exactly secure, just a deterrent.
You could also try authentication based on subrequest results. This would be slightly more work to get implemented and might not suit your access control model.
As far as I know there is no easy way to serve the media files through nginx while using Djangos access control. You could make Django serve the media files but this is discouraged by the Django developers.
@sorasful, @Afrowave, Is there something I should do? There seems to be another take on this by @ghostforpy in a different pull request: #3260.
I am not entirely sure on how to proceed here.
I've updated this with the latest changes from master. I changed to using nginx as soon as cloud provider is none, which I think is pretty much what folks need?
I've updated the documentation, could folks proof read it and let me know whether what I wrote is clear, understandable, without typos, etc...? Thanks
Thanks for contributing this feature!