aws, django, unicorn and s3 - do I need nginx then? - django

I'm building app in django which I want to deploy on aws ec2 server. The app will run on gunicorn, and I want to place static files on s3. So my question is - do I need to use nginx at all?
Is there any other benefit of using nginx beside serving static files?
Arek

Putting nginx in the front of your stack not only allows you to route static content requests to your s3 storage but also give you the ability to do things like caching your django requests and lower the hits in your app and database. You can set up fine grain cache policies and have more control of exactly where requests will go, all while still under the same url structure as your set up in django.

Even though you're placing static files on S3, you still need a web server to serve them, right? I don't see how S3 changes the fact that with Apache/WSGI or gunicorn it's better to have something like nginx serving static files.
Also, read this: http://gunicorn.org/deploy.html

Related

Suggestions for hosting SPA on AWS

I have an application that has an Angular Frontend and a Django Backend. I've already set up my django application to run on Elastic beanstalk, however, I am unsure what I should do to serve static files. I'd rather not handle this within the django application.
I have tried using nginx reverse proxy with elastic beanstalk to properly serve files, however I'm unable to serve them on "/", only extensions like "/index" or "/dashboard", and the js files the index.html needs aren't found (404 error).
I thought about rewriting the entire nginx configuration but I'm unsure where to start. Any ideas would be very helpful!!
You can host your Angular frontend on S3 (with website hosting enabled). To make it more performant and cheap, add CloudFront in front of it. Different paths (APIs) of your application can be routed to backend via CloudFront "Behaviours" feature. You can set No-Caching for those dynamic paths.
Reference:
https://medium.com/#peatiscoding/here-is-how-easy-it-is-to-deploy-an-angular-spa-single-page-app-as-a-static-website-using-s3-and-6aa446db38ef

Why is it suggested to use a different service to host static files (like nginx or apache) for django?

I've seen many questions on stackoverflow about handling static files in django during deployment. I saw that many answers said something like this - "With debug turned off Django won't handle static files for you any more - your production web server (Apache or something) should take care of that."
Why can't we use the server hosting the django project to host the static files too?
Static files don't require any kind of logic or processing. It is more efficient to deliver them directly to the end-user directly from disk via a web server, rather than running them through the middle layer of Django. That middle layer (such as gunicorn, uwsgi, or mod_wsgi) is what allows things like views to be processed and for the ORM to connect with a database. Since static files require none of that, bypassing it is the most efficient. The same is true for media files that are uploaded by the end user. Good luck!

How to deploy a Django + Whitenoise application using gunicorn?

I am using Whitenoise to serve static files in my Django app. I am NOT using Nginx. I plan to use Whitenoise behind a CDN like Cloudfront in the future. See Whitenoise FAQs.
I have been looking for deployment instructions, which handle these questions:
Since I am not using nginx, I plan to bind gunicorn directly to port 80. This results in an error - Permission Denied. I can run gunicorn as root, but that seems like a bad approach.
How to handle SSL certificate stuff? Typically this is handled by servers like Nginx.
EDIT: I am deploying my application on a Ubuntu 18.04 VM on Google Cloud Compute Engine.
P.S.: Mine is not going to be a very high traffic website. Others have used this configuration to serve websites with a high traffic. See this Squeezing every drop of performance out of a Django app on Heroku.
TL;DR
I used nginx as the http server. I removed the configuration associated with static files in nginx, so the static file requests are passed to the wsgi layer (gunicorn) and are handled by Whitenoise. So you can follow any 'nginx + gunicorn + django' deployment instructions/tutorials, which are easily available with a simple google search.
This post cleared it up for me: Deploying your Django static files to AWS (Part 2).
Long Answer
As mentioned before there are many tutorials about deploying Django + Whitenoise applications on Heroku. As pointed out in the comments:
Heroku, which has its own proxy layer in the front end, and is therefore not at all relevant.
Without verifying this statement, I thought this must be true. gunicorn is not a full fledged webserver. In fact gunicorn creators strongly recommend using it behind a proxy server (Eg. Nginx). See docs.
I was confused because I always thought of Nginx as just a reverse proxy. Functioning as a reverse proxy for static assets is just one of the functions of nginx. It provides a lot more features like buffering slow clients, which gunicorn does not, which helps prevent denial-of-service attacks.
I knew this already. It would have been foolish to not use nginx or any other webserver.
Whitenoise is just there to set proper caching headers for static files and enable compression using gzip/brotli. When used with whitenoise.storage.CompressedManifestStaticFilesStorage, it will automatically generate versioned static files. Eg. /static/js/app.49ec9402.js if you have put your file in the template as {%statis%} 'js/app.js'. A versioned file will have max-age set to 10 years i.e. cached forever.
If you are not deploying on Heroku you will still need a web server like Nginx. So you can follow any 'nginx + gunicorn + django' deployment instructions/tutorials, which are easily available with a simple google search. One of which is Deploying your Django static files to AWS (Part 2), which helped me get this issue sorted out.

Django - Access and save files to remote server

I am currently developping an application using Django.
What I'm trying to achieve is to have a remote server that will host configuration files. Those files are going to be numerous but quite small.
The configuration of my server is the following : on the adress 172.x.x.51 I have my Django app running with uwsgi and on 172.x.x.52 I have my nginx service connected to my uwsgi instance.
What I would like is to host the files on the nginx server.
Inside the application, I will need to access to the files and to save them (they are calculated from data from the database, so there's no need for a fileupload).
I looked on the documentation and found that I can use a Custom Storage System. The thing is, I don't think that's what I need because I want to store them the way it's done by default. I would just like to define the place where the files should be updated from Django.
Would it be better if I stored them in the media folder on my nginx instance ? How would I say to Django to go look on nginx's instance for the files ? On the server where nginx is hosted, I already host my static files and it's working.
This isn't a question about Django really. Storage backends are for file uploads, but as you say you're not doing that.
You need some way of allowing your Django instance on *.51 write to your nginx server on *.52. This might be via SSH/SCP, or by sharing directories over NFS, for example. Then you can simply save the files over that protocol to the relevant place, from where nginx can serve them.

i'm confused about django statice files during deployment

I'm about two months in with django. I've been following tutorials on youtube and such and one of the tutorials says that I have to use two servers when deploying my site. Django will be served from heroku and static files from amazon s3. I have to pay for two seperate servers to deploy a django app? I did not expect this and this would not be within my budget if this is so. Is he wrong or is this just for special cases like his? Any help would be appreciated
No, sounds like the video is a bit confusing. There is a distinction between static assets, ie the CSS/JS etc that makes up your site, and dynamic media, ie any user-uploaded content.
Heroku can quite happily serve static assets from the filesystem, and their docs on deploying Django state exactly how to do this. However you cannot store dynamically uploaded content on Heroku, since the filesystem is ephemeral. If your app allows this, you need to save them somewhere permanent such as S3.
Note however that S3 is really cheap; hosting media files there should only cost you pennies.
You don't need 2 different servers for deploying your django project. You can just use a single Amazon EC2 instance then install Nginx/Apache+Supervisor+Gunicorn+Python. After that, you just need to configure the location of your static files from your virtualhost. Here's a tutorial from digital ocean.