Guides / Deploy Django to AWS: your options

Deploy Django to AWS: your options

There are five reasonable ways to deploy Django to AWS, and none of them is "click here". They trade control, cost and the amount of AWS you have to learn. This guide lays out what each one involves, what you'll have to configure for Django specifically, and how to choose.

What you need, whichever you pick

Every setup has to solve the same things for a Django app:

The options

OptionGood whenWhat you take on
EC2 (a virtual machine)You want full control and know Linux.The OS, patching, gunicorn and nginx, TLS renewal, process supervision, deploy scripts, backups. The most flexible, and the most work.
Lightsail (containers or instances)A small to medium app that needs predictable monthly pricing.Building and pushing a container image, setting environment variables, wiring a database, and a simpler (but less configurable) network.
Elastic BeanstalkYou want AWS to manage the instances and load balancer for a standard web app.Its configuration files (.ebextensions or platform hooks), the Django-specific settings above, and learning how its environments update.
ECS on FargateYou run containers and want no servers to manage, with room to grow.A task definition, a load balancer, IAM roles, networking, a registry and a pipeline for the migrations step. Powerful, with the most moving parts.
A tool that deploys to your AWS accountYou want the work above done for you, with the result still in your own account.Trusting the tool with access to your account, and its limits on what you can customize.

The Django-specific traps (on any of them)

These cause most first deploys to fail, wherever they run:

  1. A 400 DisallowedHost: the load balancer health check calls the instance by its IP address. See DisallowedHost: Invalid HTTP_HOST header.
  2. CSRF 403s because HTTPS ends at the load balancer: CSRF verification failed. Request aborted. and too many redirects.
  3. Unstyled pages: static files not loading.
  4. Missing tables because nothing runs migrate: unapplied migrations.
  5. Database access: the app can't reach RDS because of a security group, or RDS requires SSL. See connection refused.

A minimal, sensible path

If you want to do it yourself, the least fragile route is: a container image built from a pinned requirements.txt or lock file, run on ECS Fargate or Lightsail containers behind HTTPS, with RDS Postgres, environment variables from a secrets store, WhiteNoise for static files, and one release step that runs python manage.py migrate --noinput before the new tasks start. Keep every previous image so rolling back is a redeploy. Before launch, run python manage.py check --deploy (deployment checklist).

Whatever you choose, create the AWS account with MFA on the root user, use IAM roles and not long-lived access keys for deploys, and set a billing alarm. Check the AWS pricing pages before you commit, since prices vary by region and change.

Or skip it

Django Cloud deploys your Django project into your own AWS account, with HTTPS, static files, migrations before every release, rollbacks and logs handled. See what it costs on the pricing page, and how it compares on the compare pages.

pip install djangocloud-cli
djangocloud deploy

Get startedSee pricing

Free plans are available for students, AWS Activate startups, open-source, non-profit and research projects. See how Django Cloud compares with other ways to host Django.

Django is a registered trademark of the Django Software Foundation. Django Cloud is not affiliated with or endorsed by it. Found a mistake in this guide? Tell us and we will fix it.