That's an excellent question (and an idea for a follow-up blog post). In most cases I'd go with Django+Gunicorn+Nginx setup (as described here http://goodcode.io/blog/django-nginx-gunicorn/), with Nginx (or Apache) just being the reverse proxies and serving the static assets.
Django is still needed here if you want to have form processing (unless you use 3rd party service), and useful if you want to have templating (unless you want to use Jekyll, Hyde, or similar static-generator tools).
So, while Nginx/Apache would definitely speed up things, they're not enough. On the other hand, you can build a reasonably[0] fast "almost" static site with Django, and have it deployed on either your Linux server, or Heroku, or another PaaS.
[0] What's "reasonably fast"? my hunch tells me that the simple setup outlined here could take quite a beating (unless intentionally attacked with slowloris or similar attacks, or serving heavy static assets). It'll be fun to test it.
You can also setup a CloudFront deployment and point it to your app server as the origin. Fast and cheap way to serve static files without having to configure nginx/apache. Well...cheap as long as you don't need SSL.
One nice thing with Django is that you can separate out truly static files into your apps static folder, and configure nginx to serve the /static/ URL. Configure a `STATIC_ROOT` for your app, run:
./manage.py collectstatic
and you have nginx serving the truly static files while still allowing Django to manage your non-static assets.
This is how I run my site, and it works pretty darned well. Let nginx do the caching of static files, compression, and SSL management, letting Django just worry about its small domain of non-static files.
The one downside is that nginx will not necessairly detect when a static file has changed, requiring a bit of effort to ensure that new versions of a static file are puled, either through filename versioning, or `?1` on the end of your static URLs.
Absolutely. But, this being an article on Django, serving a combination of static and semi-static assets, commenting on this Django feature seemed appropriate.
If you're looking to django for static mostly for the templating engine and some build time python, I'd check out the excellent Cactus. Apparently there's a new downloadable mac app for it, which I've yet to try, but as a Django templater / designer, Cactus was always my goto for static sites.
It's surprisingly easy, though I believe the tests expect one to be configured (I haven't checked precisely why, or if it can be configured not to expect a database).
It can be configured not to expect a database. You just subclass the DjangoTestSuiteRunner to skip setting up and tearing down the DB, then set that as TEST_RUNNER. See here for an example: http://stackoverflow.com/questions/5917587/django-unit-tests...
Flask doesn't make as many decisions for you as Django does. Some things that come bundled in Django are packages in Flask. A lot of the packages for Flask make fewer assumptions than similar packages for Django, which often makes using an uncommon data backend (ElasticSearch, Mongo, RethinkDB, Redis, etc) a little easier (you don't have to rewrite as much).
Flask (for python) and Sinatra[0] (for Ruby) are awesome. I just recently did two side projects using both. I use Webaction[1] for my hosting provider for "small" projects and getting Flask/Sinatra requires very little setup (just enough to make it fun). They also have one click installers for Rails/Django/etc. Super easy to setup if you're a dev noob like me.
Have you seen Frozen-Flask? It's a clever extension that "freezes" a dynamic flask site into HTML files and static assets you can upload anywhere. http://pythonhosted.org/Frozen-Flask/
I'm in the process of moving away from a static site for my website.
Simply put, a web interface is often more convenient so I can update things easier on the go, and it's good to have a place to host experiments too.
I have used various static site generators but none of them seemed to be significantly less work to get going than a small django app on heroku. Though I've been using Django for a few years, so there is simply no learning curve left.
What'll happen then? My Django-based blog handled hundreds of thousands of visits in a day without breaking a sweat. What it does is basically "fetch the whole page from memcached and serve it".
I had the same problem (updating content), so I wrote a small script to download deltas from my Dropbox and parse them. Now I can edit my posts with vim:
I'd recommended checking out Mezzanine[1]. I use it for everything now, regardless if I need a full CMS. The included fab file makes deployment dead simple[2] and the caching strategy[3] results in nearly zero DB hits.
I think his point is that it's quite likely you'll begin without a need for a database but later want to add some functionality requiring one. And at that point, you will have been better off starting with Django (or similar) as now you'll need to migrate everything over anyway.
That point is wrong. Setting up a Django deployment that won't fall over when you get traffic is more work than moving Jekyll templates into a Django install. Plus, if he'd started with Jekyll, he might have chosen to store his weights as a flat file that Jekyll could use to generate static charts.
Database-first thinking for content sites is just wrong. I've done it based on this same argument, and I've learned my lesson.
If you need a DB that's read only and updated infrequently you can just store the content in JSON files and parse them client side. Of course if you need to do writes it gets more complicated.
How will a static site fall over with Django? My page generation times are only a few ms, they're just fetched from cache, same as the static files.
The problem isn't showing the data, it's storing it. I have different computers gathering the data and deploying my site, so I would have to set up an elaborate solution, and I would still not be able to do A/B tests, sending email for new content, auto-Tweeting, etc.
The solution you've chosen is probably right for your situation. However, lots of people (including me not too long ago) create static sites in Django because they dream of making it more dynamic that way. That's usually a bad approach in my experience.
Something that I've been playing around with is hosting sites on S3. Then you can have a simple cron job that will just update an HTML or JSON data file at whatever frequency you want.
Nice way to keep the site static but add a bit of variability.
Yea - it can work just as easily on your own server but the idea is that you don't have to worry about hosting at all and rely on S3 which is the most reliable AWS service.
You can also just deploy your static site to BitBalloon, then any contact form will start working and accepting form submissions. (Disclaimer, I'm the founder).
I built a decently large static content site with a dynamic backend (http://yareallyarchive.com) on django.
With aggressive caching of all static pages it is fast as hell, and I love the django ecosystem. Adding search was as easy as dropping in django-haystack and adding like 5 lines of code. django-mptt has been brilliant for easily querying and manipulating comment trees.
It's possible to do small sites with django but it requires you to learn a lot of stuff you don't necessarily need. Flask is a better choice for small/nearly-static sites if you're not already familiar with a web framework.
This is exactly the method my company uses when one of the stories on our website is getting hammered by Reddit. I manually wget the rendered template, save it to a templates/static/ dir, and serve it directly.
We cache everything, but this simply takes care of not having to think about it. It might not be the best method, but it sure is the least troublesome/least cognitive load when things hit the fan.
$ pip install djangothis
$ cat > views.py
from importd import d
@d
def hello(request):
return d.HttpResponse("hello there")
^D
$ djangothis
Validating models...
0 errors found
February 18, 2014 - 16:43:31
Django version 1.6.2, using settings None
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Any html files would be automatically served, files in static folder in current folder will automatically be mapped to /static/ and so on.
56 comments
[ 3.2 ms ] story [ 114 ms ] threadDjango is still needed here if you want to have form processing (unless you use 3rd party service), and useful if you want to have templating (unless you want to use Jekyll, Hyde, or similar static-generator tools).
So, while Nginx/Apache would definitely speed up things, they're not enough. On the other hand, you can build a reasonably[0] fast "almost" static site with Django, and have it deployed on either your Linux server, or Heroku, or another PaaS.
[0] What's "reasonably fast"? my hunch tells me that the simple setup outlined here could take quite a beating (unless intentionally attacked with slowloris or similar attacks, or serving heavy static assets). It'll be fun to test it.
Especially with virtualenvs and such.
This is how I run my site, and it works pretty darned well. Let nginx do the caching of static files, compression, and SSL management, letting Django just worry about its small domain of non-static files.
The one downside is that nginx will not necessairly detect when a static file has changed, requiring a bit of effort to ensure that new versions of a static file are puled, either through filename versioning, or `?1` on the end of your static URLs.
https://github.com/koenbok/Cactus?source=c
http://flask.pocoo.org/docs/quickstart/
I used it in conjunction with Bootstrap and Heroku to throw a personal site together in an evening, following this tutorial:
http://www.shea.io/lightweight-python-apps-with-flask-twitte...
What am I missing by not knowing Flask?
[0] - http://www.sinatrarb.com/ [1] - http://www.webfaction.com/?affiliate=mbesto
Simply put, a web interface is often more convenient so I can update things easier on the go, and it's good to have a place to host experiments too.
I have used various static site generators but none of them seemed to be significantly less work to get going than a small django app on heroku. Though I've been using Django for a few years, so there is simply no learning curve left.
http://www.stavros.io/posts/this-blog-is-dropbox-enabled/
This one if I remember correctly: https://github.com/timmyomahony/django-pagedown
One unintended (and great) side-effect of a Dropbox-hosted site is that you get mirrors for free (they all update together).
[1]http://mezzanine.jupo.org/ [2]http://mezzanine.jupo.org/docs/deployment.html [3]http://mezzanine.jupo.org/docs/caching-strategy.html
Database-first thinking for content sites is just wrong. I've done it based on this same argument, and I've learned my lesson.
The problem isn't showing the data, it's storing it. I have different computers gathering the data and deploying my site, so I would have to set up an elaborate solution, and I would still not be able to do A/B tests, sending email for new content, auto-Tweeting, etc.
Nice way to keep the site static but add a bit of variability.
Also, the bigger problem was, indeed, data storage, not display.
Link: https://www.bitballoon.com
[1] http://docs.getpelican.com/en/3.3.0/
With aggressive caching of all static pages it is fast as hell, and I love the django ecosystem. Adding search was as easy as dropping in django-haystack and adding like 5 lines of code. django-mptt has been brilliant for easily querying and manipulating comment trees.
It's possible to do small sites with django but it requires you to learn a lot of stuff you don't necessarily need. Flask is a better choice for small/nearly-static sites if you're not already familiar with a web framework.
http://cactusformac.com
Works like a charm.
[1]: https://github.com/amitu/djangothis