cookiecutter-django icon indicating copy to clipboard operation
cookiecutter-django copied to clipboard

Add option to serve media files locally using nginx

Open arrys opened this issue 4 years ago • 15 comments

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 ------|

arrys avatar Feb 23 '20 00:02 arrys

@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 avatar Mar 10 '20 19:03 dahifi

@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.

arrys avatar Mar 17 '20 14:03 arrys

@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.

arrys avatar Mar 17 '20 15:03 arrys

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 avatar Mar 31 '20 15:03 sorasful

@sorasful Thank you for your suggestions! They were all justified so I implemented them as you suggested.

arrys avatar Apr 05 '20 10:04 arrys

@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!

maltebeckmann avatar Oct 21 '20 18:10 maltebeckmann

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.

arrys avatar Oct 22 '20 00:10 arrys

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?

maltebeckmann avatar Oct 22 '20 08:10 maltebeckmann

Thanks a lot! This was helpful to me.

mkrtchian avatar May 07 '21 06:05 mkrtchian

Do we have news about this ? This could really be a great feature.

sorasful avatar Jun 08 '21 12:06 sorasful

Do we need to fork this to fix conflict and merge this ?

sorasful avatar Jun 28 '21 19:06 sorasful

Hey @sorasful,

I suppose we will need to fork and sort it out.

Afrowave avatar Jun 28 '21 19:06 Afrowave

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?

Braintelligence avatar Aug 15 '21 19:08 Braintelligence

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.

arrys avatar Aug 17 '21 04:08 arrys

@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.

arrys avatar Aug 17 '21 04:08 arrys

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?

browniebroke avatar Jan 31 '23 23:01 browniebroke

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

browniebroke avatar Feb 02 '23 12:02 browniebroke

Thanks for contributing this feature!

browniebroke avatar Mar 04 '23 18:03 browniebroke