Deploy a Django App to AWS

Build a Django web app and deploy it live on AWS with Elastic Beanstalk.

Introduction

30 Second Summary

Building something on your computer is satisfying. Deploying it to the internet so anyone can visit takes it to a whole new level.

In this project, you will build a personal "About Me" website with Django and deploy it live on AWS using Elastic Beanstalk. You'll go from an empty folder to a publicly accessible URL.

What You'll Build

A personal website built with Django and deployed to AWS Elastic Beanstalk, complete with a custom homepage, styled layout, and a live public URL.

By the end of this project, you'll have:

  • A working Django project with a custom app, view, and HTML template running on your machine.
  • An Elastic Beanstalk configuration that tells AWS how to run your app.
  • A live deployment accessible via a public .elasticbeanstalk.com URL.
  • A second "Projects" page with navigation links, deployed through the full update cycle.

Are there any prerequisites?

You'll need an AWS account with Free Tier credits available and comfort using the command line. The project walks you through installing everything else.

Set Up Your Python Environment and EB CLI

Before you can build and deploy a Django app, you need a few tools installed on your machine. Python runs the code. The EB CLI deploys it to Elastic Beanstalk on AWS.

In this step, you'll install Python, pip, virtualenv, and the Elastic Beanstalk CLI. Then you'll create a virtual environment to keep your project's packages separate from everything else on your computer.

In this step, get ready to:
  • Install and verify Python 3.12 and pip.
  • Install virtualenv and the Elastic Beanstalk CLI.
  • Create and activate a virtual environment for the project.
Install and verify Python 3.12

Python is the programming language that Django is built with. You need version 3.12 for this project.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or Command Prompt (Windows) and press Enter to open it.
  • Check your Python version by running this command:
python --version

Pro tip: macOS uses python3

On macOS, Python 3 installs as python3 and pip installs as pip3. Use python3 wherever this project says python, and pip3 wherever it says pip.

I see Python 3.12.x

Python 3.12 is ready.

  • Confirm pip is installed by running this command:
pip --version

You should see a version number and a reference to Python 3.12. You're all set to move to the next substep.

I don't have Python 3.12

  • Open your browser and go to the Python downloads page.
  • Download the Python 3.12 installer for your operating system.

macOS

  • Open the downloaded .pkg file.
  • Follow the installer prompts and click Install.

Windows

  • Open the downloaded .exe file.
  • Check the box labeled Add Python to environment variables at the bottom of the installer window.
  • Click Install Now.
  • Close your terminal completely and reopen it.
  • Verify the installation by running:
python --version

You should see Python 3.12.x in the output. On macOS, use python3 --version instead.

  • Confirm pip is installed by running:
pip --version

You should see a version number and a reference to Python 3.12.

Still not seeing the right version?

  • Make sure you downloaded Python 3.12 specifically from the python.org downloads page, not a different version.
  • On Windows, if python still shows an old version, the new installation's PATH entry may be lower priority. Uninstall the old version from Apps & features and try again.
  • Help me troubleshoot my Python installation.
Install virtualenv and the EB CLI

Two more tools to install before you start building. virtualenv creates isolated Python environments for your projects. The EB CLI lets you deploy your app to Elastic Beanstalk from the terminal.

  • Install virtualenv by running this command:
pip install virtualenv
  • Install the EB CLI by running this command:

macOS

pip3 install awsebcli --upgrade

Windows

pip install awsebcli --upgrade --user

What are these tools?

  • virtualenv creates a virtual environment, which is an isolated folder where your project's Python packages live. This prevents conflicts between different projects on your machine.
  • The EB CLI (eb) is a command-line tool from AWS. It handles creating, deploying, and managing your Elastic Beanstalk applications without needing to click through the AWS console.
  • Verify the EB CLI installed correctly by running:
eb --version

I see a version number

The EB CLI is ready. You should see something like EB CLI 3.x.x.

Command not found

Your terminal cannot find the eb command. This usually means the install location is not in your PATH.

macOS

  • Try closing and reopening your terminal.
  • If it still does not work, reinstall with:
sudo pip3 install awsebcli --upgrade
  • Run eb --version again to confirm it works.

Windows

You need to add the EB CLI's install location to your PATH.

  • Press the Windows key and type Environment Variables.
  • Click Edit the system environment variables.
  • Click the Environment Variables button.
  • Under User variables, select Path and click Edit.
  • Click New and paste this path:
%USERPROFILE%\AppData\Roaming\Python\Python312\Scripts
  • Click OK on all open dialogs.
  • Close and reopen Command Prompt.
  • Run eb --version again to confirm it works.

Still seeing command not found?

Help me fix the eb command not found error on my machine.

Create and activate a virtual environment

A virtual environment is an isolated space for your project's Python packages. Anything you install inside it stays separate from other projects on your machine.

  • Create a virtual environment called eb-virt by running this command:

macOS

virtualenv ~/eb-virt

Windows

virtualenv %HOMEPATH%\eb-virt

This creates a folder called eb-virt in your home directory with its own copy of Python and pip.

  • Activate the virtual environment by running:

macOS

source ~/eb-virt/bin/activate

Windows

%HOMEPATH%\eb-virt\Scripts\activate

You should see (eb-virt) at the beginning of your terminal prompt. This confirms the virtual environment is active.

Why a virtual environment?

Without a virtual environment, every Python project on your machine shares the same packages. If one project needs Django 5.2 and another needs Django 4.0, they would conflict.

Virtual environments solve this by giving each project its own isolated set of packages. Everything you install from now on goes into eb-virt, not your system Python.

Don't see (eb-virt) in your prompt?

  • Make sure you ran the activate command, not the create command again.
  • On Windows, check that you are using Command Prompt, not PowerShell. The activate command syntax differs between them.
  • Try closing your terminal, reopening it, and running the activate command again.
  • Help me activate my virtual environment.

Your development environment is ready. Next up, you'll create your Django project and build a custom homepage.

Create Your Django Project and App

Your tools are installed and your virtual environment is ready. Time to build something with them.

Django is a Python web framework that helps you build websites quickly. In this step, you'll create a Django project, add a custom homepage, and see it running on your own machine.

In this step, get ready to:
  • Install Django and scaffold a new project.
  • Create a pages app with a custom view and URL.
  • Build an HTML template for your homepage.
Install Django and create your project

Your virtual environment isolates this project's packages from the rest of your system. Every package you install while the environment is activated stays contained inside it.

  • Make sure your virtual environment is activated. You should see (eb-virt) at the start of your terminal prompt.
  • Navigate to your Desktop by running this command:

macOS

cd ~/Desktop

Windows

cd %USERPROFILE%\Desktop
  • Install Django by running this command:
pip install django==5.2.13
  • You should see Successfully installed Django-5.2.13 in the output.

Install failed or permission error?

  • Make sure your virtual environment is activated. If you don't see (eb-virt) in your prompt, re-activate it before running the install command.
  • Check that you typed the version number exactly as django==5.2.13 with two equals signs.
  • Why can't I install Django in my virtual environment?
  • Create a new Django project and move into its folder by running these commands:
django-admin startproject ebdjango
cd ebdjango

What did this create?

The startproject command scaffolded a new folder called ebdjango with the core files every Django project needs.

  • manage.py is the command-line tool you'll use to run the server, create apps, and manage your project.
  • ebdjango/settings.py holds all your project's configuration.
  • ebdjango/urls.py maps web addresses to the code that handles them.
  • Confirm the project files exist by running:

macOS

ls

Windows

dir
  • You should see manage.py and an ebdjango folder in the output.

django-admin not found?

  • This usually means Django didn't install correctly. Re-run pip install django==5.2.13 and check for errors.
  • Make sure your virtual environment is still activated. Look for (eb-virt) in your prompt.
  • Why is django-admin not recognized in my terminal?

Django comes with a built-in development server. Let's use it to confirm everything is working.

  • Start the development server by running:
python manage.py runserver
  • Open your browser and visit http://127.0.0.1:8000/.

You should see Django's default welcome page with a rocket ship graphic and the message "The install worked successfully!" This confirms Django is installed and your project is configured correctly.

  • Press Ctrl+C in your terminal to stop the server.

Don't see the welcome page?

  • Make sure the server is still running. Your terminal should show Starting development server at http://127.0.0.1:8000/ with no error messages below it.
  • Check the URL in your browser. It must be exactly http://127.0.0.1:8000/ including the port number.
  • If you see "port is already in use," another process is using port 8000. Close other terminals and try again.
  • Help me troubleshoot why Django's welcome page isn't loading.
Create the pages app and add your homepage view

Django organizes features into "apps." Each app handles a specific part of your website. You'll create an app called pages to hold your homepage.

  • Create the app by running this command:
python manage.py startapp pages
  • Confirm the app was created by running:

macOS

ls

Windows

dir
  • You should see a new pages folder alongside manage.py and the ebdjango folder.

Django doesn't automatically know about new apps. You need to register pages in your project's settings file.

  • Open ebdjango/settings.py in your text editor.
  • Find the INSTALLED_APPS list. It looks like this:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  • Add 'pages' as the last item in the list, so it looks like this:
# Add 'pages' to INSTALLED_APPS
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages',
]

What does this change do?

Adding 'pages' to INSTALLED_APPS tells Django your app exists. Without this, Django won't be able to find your app's views, templates, or models.

  • Save settings.py.

Now you'll create a "view" to tell Django what to display when someone visits your homepage. In Django, a view is a Python function that receives a web request and returns a response.

  • Open pages/views.py in your text editor and replace its contents with this code:
from django.shortcuts import render

# Display the homepage when a visitor arrives
def home(request):
    return render(request, 'pages/home.html')

What does this code do?

  • render is a Django helper that takes an HTML template and turns it into a web page.
  • The home function receives a request (information about the visitor) and returns the rendered pages/home.html template.
  • Save pages/views.py.

You won't see a change yet. This view needs a URL to connect it to, which you'll set up next.

Django uses a URL configuration file to map web addresses to views. You'll update this file to point the homepage URL to your new home view.

  • Open ebdjango/urls.py in your text editor and replace its contents with this code:
from django.contrib import admin
from django.urls import path
from pages import views

urlpatterns = [
    path('admin/', admin.site.urls),
    # Map the root URL to the homepage view
    path('', views.home, name='home'),
]

What does this code do?

  • from pages import views imports the views file from your pages app so you can reference its functions.
  • path('', views.home, name='home') maps the root URL (the homepage) to the home function you just created. The empty string '' means "the base URL with no extra path."
  • Save ebdjango/urls.py.

You won't see a change in the browser yet. Your view is trying to render a template that doesn't exist. You'll create it next.

Awesome, I've got everything!

Double check you've saved both pages/views.py and ebdjango/urls.py.

I'd like to double check the full code

Here's what pages/views.py should look like:

from django.shortcuts import render


def home(request):
    return render(request, 'pages/home.html')

Here's what ebdjango/urls.py should look like:

from django.contrib import admin
from django.urls import path
from pages import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.home, name='home'),
]
Build your homepage template

Django templates are HTML files that your views render and send to the browser. They live in a specific folder structure: pages/templates/pages/. The double nesting ensures Django finds the right template when multiple apps exist in a project.

  • Create the template directory structure by running this command:

macOS

mkdir -p pages/templates/pages

Windows

mkdir pages\templates\pages
  • Confirm the directory was created by running:

macOS

ls pages/templates/pages

Windows

dir pages\templates\pages

The folder should exist and be empty for now. If you see an error saying the directory doesn't exist, re-run the mkdir command and check the path for typos.

  • Create a new file called home.html inside pages/templates/pages/ and add this code:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About Me</title>
    <style>
        /* Page layout and background */
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 60px auto;
            padding: 0 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        /* Main heading color */
        h1 {
            color: #2c3e50;
        }
        /* White card for the bio section */
        .bio {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        /* Spacing for the skills list */
        .skills {
            margin-top: 20px;
        }
        .skills li {
            margin-bottom: 5px;
        }
    </style>
</head>
<body>
    <!-- Replace [Your Name] with your actual name -->
    <h1>Hi, I'm [Your Name]</h1>
    <div class="bio">
        <p>Welcome to my personal site! I'm learning Django and cloud deployment with AWS.</p>
        <div class="skills">
            <h2>What I'm Learning</h2>
            <ul>
                <li>Python and Django</li>
                <li>AWS Cloud Services</li>
                <li>Web Development</li>
            </ul>
        </div>
    </div>
</body>
</html>

What's in this template?

  • The <style> block adds CSS styling directly in the HTML. It centers the page, sets a light gray background, and wraps your bio in a white card.
  • The .bio class creates a card effect with rounded corners and a subtle shadow.
  • Replace [Your Name] with your actual name. Feel free to customize the bio text and skills list too.
  • Save home.html.

Awesome, I've got everything!

Double check you've saved pages/templates/pages/home.html.

I'd like to double check the full code

Here's what pages/templates/pages/home.html should look like:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About Me</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 60px auto;
            padding: 0 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        h1 {
            color: #2c3e50;
        }
        .bio {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .skills {
            margin-top: 20px;
        }
        .skills li {
            margin-bottom: 5px;
        }
    </style>
</head>
<body>
    <h1>Hi, I'm [Your Name]</h1>
    <div class="bio">
        <p>Welcome to my personal site! I'm learning Django and cloud deployment with AWS.</p>
        <div class="skills">
            <h2>What I'm Learning</h2>
            <ul>
                <li>Python and Django</li>
                <li>AWS Cloud Services</li>
                <li>Web Development</li>
            </ul>
        </div>
    </div>
</body>
</html>

Time to see your custom homepage in action.

  • Start the development server by running:
python manage.py runserver
  • Open your browser and visit http://127.0.0.1:8000/.

You should see your custom homepage with your name, a bio paragraph, and a "What I'm Learning" list inside a white card. The default Django rocket page is gone.

  • Press Ctrl+C in your terminal to stop the server.

Seeing a TemplateDoesNotExist error?

  • Check that your file is in the correct location: pages/templates/pages/home.html. The path must match exactly, including the double pages nesting.
  • Make sure 'pages' is listed in INSTALLED_APPS in settings.py. Django can only find templates from registered apps.
  • Verify that the template name in views.py is 'pages/home.html' (not just 'home.html').
  • Help me fix a TemplateDoesNotExist error in my Django project.

Your Django app is running locally with a custom homepage. Next, you'll configure it for deployment to AWS so anyone on the internet can visit it.

Configure Django for Elastic Beanstalk

Your Django app runs perfectly on your machine. But Elastic Beanstalk has no idea how to start it, what packages it needs, or where to find your static files.

In this step, you'll add three small pieces of configuration that bridge that gap. Once these are in place, Elastic Beanstalk will have everything it needs to run your app on AWS.

In this step, get ready to:
  • Generate a requirements.txt file listing your project's dependencies.
  • Create an Elastic Beanstalk configuration file that tells AWS how to start your app.
  • Configure static file handling for production.
Generate your requirements file

When Elastic Beanstalk sets up your app on a server, it needs to install the same Python packages you use locally. A requirements.txt file is the standard way to list those packages and their exact versions.

  • Make sure your virtual environment is still activated. You should see (eb-virt) in your command prompt.
  • Generate the requirements file by running this command from your project root (the ebdjango folder that contains manage.py):
pip freeze > requirements.txt

What does this command do?

pip freeze lists every package installed in your virtual environment, along with its exact version number. The > requirements.txt part redirects that output into a file instead of printing it to the screen.

  • Open requirements.txt in your text editor.
  • You should see three packages listed: Django, asgiref, and sqlparse. The exact version numbers may differ slightly, but Django==5.2.13 should be there.

Is the file empty?

An empty requirements.txt means your virtual environment is not activated. Check that you see (eb-virt) at the start of your command prompt. If not, activate it by running:

%HOMEPATH%\eb-virt\Scripts\activate

Then run the pip freeze command again.

Still stuck? Help me figure out why my requirements.txt is empty after running pip freeze.

Create the Elastic Beanstalk configuration file

Elastic Beanstalk looks for a special folder called .ebextensions in your project. Any configuration files inside it tell EB how to set up and run your app on the server.

  • Create the .ebextensions folder inside your project root (the same folder where manage.py lives) by running this command:
mkdir .ebextensions
  • Inside the .ebextensions folder, create a new file called django.config and add the following content:
option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango.wsgi:application

What is WSGIPath?

WSGI (Web Server Gateway Interface) is the standard protocol that connects a Python web app to a web server. Every Django project comes with a wsgi.py file that serves as this connection point.

The WSGIPath setting tells Elastic Beanstalk exactly where to find that file. ebdjango.wsgi:application means "look inside the ebdjango folder for wsgi.py and use the object called application." Without this, Elastic Beanstalk would not know how to start your app.

  • Save django.config.
  • Confirm the file is in the right place by running:
ls .ebextensions

You should see django.config listed in the output.

Don't see django.config?

Make sure you created the file inside the .ebextensions folder, not next to it. The file path should be .ebextensions/django.config.

Also check the file extension carefully. It must be .config, not .cfg or .yaml.

Still having trouble? Help me verify my .ebextensions/django.config file is set up correctly.

Awesome, I've got everything!

Great. Double check you have saved django.config before moving on.

I'd like to double check the full code

Here is the complete django.config file. Make sure yours matches exactly, including the indentation.

option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: ebdjango.wsgi:application
Configure static files for production

Django needs to know where to collect all your static files (like CSS) into a single folder for production. The STATIC_ROOT setting tells Django where that folder should be.

  • Open ebdjango/settings.py in your text editor.
  • Scroll to the bottom of the file and find this line:
STATIC_URL = '/static/'
  • Add a new line directly below it so both lines look like this:
STATIC_URL = '/static/'
STATIC_ROOT = 'static'

What is the difference between STATIC_URL and STATIC_ROOT?

STATIC_URL is the URL path browsers use to request static files (like /static/style.css). STATIC_ROOT is the folder on the server where Django gathers all static files into one place.

During development, Django serves files from each app individually. In production, Elastic Beanstalk needs them all in a single folder to serve efficiently.

  • Save settings.py.

Awesome, I've got everything!

Great. Double check you have saved settings.py before moving on.

I'd like to double check the full code

Here are all the modifications you have made to settings.py so far across Steps 2 and 3. Make sure these sections match your file.

# 'pages' was added to INSTALLED_APPS in Step 2
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'pages',
]

# ALLOWED_HOSTS is still the default (you'll update this in Step 4)
ALLOWED_HOSTS = []

# STATIC_ROOT was added below STATIC_URL in Step 3
STATIC_URL = '/static/'
STATIC_ROOT = 'static'

Now you need to run Django's collectstatic command to gather static files into the static folder you just configured.

  • Collect all static files by running this command:
python manage.py collectstatic

What should I see?

Django will ask you to confirm by typing yes. Type yes and press Enter. You should then see a message saying static files were copied to your static folder.

  • Confirm the static folder was created by running:
ls static

You should see an admin folder listed. This contains Django's built-in admin panel static files.

Seeing a "No such file or directory" error?

Make sure you added the STATIC_ROOT = 'static' line to settings.py and saved the file before running the command.

Also check that you are running the command from the project root (the folder that contains manage.py).

Still stuck? Help me troubleshoot why collectstatic is failing in my Django project.

Your Django project is now fully configured for Elastic Beanstalk. You have a package list, a server configuration file, and proper static file handling. Next up, you'll deploy all of this to AWS and get a live URL anyone can visit.

Deploy to AWS with the EB CLI

Your Django app is configured and ready for the cloud. You have a requirements.txt, a .ebextensions/django.config, and your static files all set up.

Now it's time to get your site live on the internet. You'll use the EB CLI to register your project with AWS, spin up a server, and deploy your code to a public URL.

In this step, get ready to:
  • Initialize an Elastic Beanstalk application with eb init.
  • Create an environment and deploy your app with eb create.
  • Add your live domain to Django's settings and verify your site is publicly accessible.
Initialize your Elastic Beanstalk application

Before you can deploy, you need to register your project as an Elastic Beanstalk application. The eb init command creates this application on AWS and links your local project folder to it.

This command will prompt you for your AWS credentials if you haven't configured them before. You need an Access Key ID and a Secret Access Key ready before running it.

How do I find my AWS credentials?

Your Access Key ID and Secret Access Key are managed through IAM (Identity and Access Management) in the AWS Console. Here's how to create them:

  • Open the AWS Management Console at https://console.aws.amazon.com/.
  • Click your account name in the top-right corner of the page.
  • Click Security credentials.
  • Scroll to the Access keys section and click Create access key.
  • Select Command Line Interface (CLI) as the use case, check the confirmation box, and click Next.
  • Click Create access key and copy both the Access key and Secret access key. You only see the secret key once, so save it somewhere safe.
  • Make sure you are in the ebdjango project directory (the folder that contains manage.py).
  • Make sure your virtual environment is still activated. You should see (eb-virt) in your command prompt.
  • Initialize your Elastic Beanstalk application by running this command:
eb init -p python-3.12 django-tutorial --region us-east-1

What do these flags mean?

  • -p python-3.12 tells Elastic Beanstalk to use the Python 3.12 platform to run your app.
  • django-tutorial is the name of your Elastic Beanstalk application on AWS.
  • --region us-east-1 deploys your app to the US East (N. Virginia) region.

If the CLI prompts you for credentials, paste your Access Key ID and Secret Access Key when asked. If it also asks "Do you want to set up SSH for your instances?", enter n.

  • You should see a confirmation that the application was created. A new .elasticbeanstalk folder now appears in your project directory.

eb init not working?

  • Double-check that your Access Key ID and Secret Access Key are correct. You can regenerate them in the AWS Console under Security credentials.
  • If you see a "not recognized" error, the EB CLI may not be on your PATH. Revisit Step 1 to check your PATH configuration.
  • Make sure you are running the command from the ebdjango folder that contains manage.py.

Still stuck? Ask for help.

Create your environment and deploy

An Elastic Beanstalk environment is the actual server infrastructure that runs your app. The eb create command provisions an EC2 instance (a virtual server), sets up load balancing, and deploys your code.

  • Create your environment and deploy your app by running this command:
eb create django-env

What happens during eb create?

  • Elastic Beanstalk provisions an EC2 instance to run your Django app.
  • It installs the packages listed in your requirements.txt on the server.
  • It reads your django.config to configure the WSGI path so it knows how to start your app.
  • This process takes about 5 minutes. You'll see status updates in your terminal as resources are created.

Wait for the deployment to finish. You'll see a series of status messages in your terminal.

  • Once it completes, check the status of your environment by running:
eb status
  • Look for the CNAME value in the output. It looks something like django-env.eba-xxxxxxxxxx.us-east-1.elasticbeanstalk.com. This is your app's live domain name.
  • Copy this CNAME value. You'll need it in the next substep.

eb create failing?

  • If you see a "service role required" error, run eb create without the environment name (just eb create by itself). The EB CLI will create the service role for you interactively.
  • If you see errors about your application code, make sure requirements.txt and .ebextensions/django.config are in the same folder as manage.py.
  • Check that your AWS credentials have permissions to create Elastic Beanstalk resources.

Still stuck? Ask for help.

Add your domain to Django's allowed hosts

Django has a security feature called ALLOWED_HOSTS that blocks requests from unrecognized domains. Your EB environment has a new domain, but Django doesn't know about it yet.

  • Open ebdjango/settings.py in your text editor.
  • Find this line:
ALLOWED_HOSTS = []
  • Replace it with your EB domain (the CNAME value you copied from eb status), so the line looks like this:
# Replace the empty ALLOWED_HOSTS with your EB domain
ALLOWED_HOSTS = ['your-eb-domain.elasticbeanstalk.com']

What is ALLOWED_HOSTS?

Django checks every incoming request to make sure it's addressed to a domain you trust. If the request's Host header doesn't match a domain in ALLOWED_HOSTS, Django rejects it with a 400 error. This prevents HTTP Host header attacks.

  • Save settings.py.
  • Deploy the update to your live environment by running:
eb deploy

This pushes your updated code to the server. It takes about a minute to finish.

  • Once the deployment completes, open your live site by running:
eb open

Your default browser opens to your live Django site on AWS. You should see the same homepage you built locally, now accessible to anyone with the URL.

Seeing an error page instead of your site?

  • If you see a Django "Bad Request (400)" error, double-check that the domain in ALLOWED_HOSTS exactly matches the CNAME from eb status. Make sure there are no extra spaces or missing characters.
  • If you see a generic 502 or server error, make sure you saved settings.py and ran eb deploy after making the change.
  • Check that your .ebextensions/django.config file has the correct WSGIPath set to ebdjango.wsgi:application.

Still stuck? Ask for help.

Your app is live on the internet. Next up, you'll make a visible change to your site and push it live to experience the update workflow that real teams use every day.

Update Your App and Redeploy

Your Django app is live on AWS. Anyone with the URL can visit it right now.

Real development doesn't stop at the first deploy. Teams push updates constantly, sometimes dozens of times a day. In this step, you'll make a visible change to your site and redeploy it to experience the update workflow firsthand.

In this step, get ready to:
  • Add a new "What I'm Learning" section to your homepage.
  • Redeploy your updated app to AWS with a single command.
Add a skills section to your homepage

Your homepage currently shows your name and a short bio. You'll add a "What I'm Learning" skills list to make the page more interesting. This gives you a visible change to deploy.

  • Open pages/templates/pages/home.html in your text editor.
  • Find the .bio CSS block inside the <style> section. It looks like this:
.bio {
    background: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
  • Add these new styles right below the .bio block:
/* Styles for the skills list */
.skills {
    margin-top: 20px;
}
.skills li {
    margin-bottom: 5px;
}

What do these styles do?

  • .skills adds a top margin to separate the skills list from the bio paragraph above it.
  • .skills li adds spacing between each list item so they don't look cramped.

Now you'll add the HTML that uses these styles.

  • Scroll down to the <body> section and find the paragraph inside the .bio div. It looks like this:
<div class="bio">
    <p>Welcome to my personal site! I'm learning Django and cloud deployment with AWS.</p>
</div>
  • Add the following skills section between the closing </p> tag and the closing </div> tag:
<!-- Skills list section -->
<div class="skills">
    <h2>What I'm Learning</h2>
    <ul>
        <li>Python and Django</li>
        <li>AWS Cloud Services</li>
        <li>Web Development</li>
    </ul>
</div>

What does this HTML do?

  • The <div class="skills"> wrapper connects this section to the CSS styles you just added.
  • The <ul> creates an unordered (bulleted) list. Each <li> is one item in that list.
  • Feel free to customize the list items with your own skills or interests.
  • Save home.html.
  • Verify the change locally by running your dev server with this command:
python manage.py runserver
  • Visit http://127.0.0.1:8000/ in your browser. You should see a "What I'm Learning" heading with a bulleted list of three skills below your bio paragraph.
  • Press Ctrl+C in the terminal to stop the dev server.

Don't see the skills section?

  • Make sure you saved home.html. Unsaved changes won't show in the browser.
  • Check that the new <div class="skills"> block is inside the <div class="bio"> wrapper. If it's outside, it won't have the white card background.
  • Make sure the CSS class name .skills in your <style> matches class="skills" in your HTML. Class names are case-sensitive.

Help me debug why my skills section isn't showing up in home.html.

Awesome, I've got everything!

Great. Double check you've saved home.html before moving on to deploy.

I'd like to double check the full code

Here is the full home.html file with the skills section included.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About Me</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 60px auto;
            padding: 0 20px;
            background-color: #f5f5f5;
            color: #333;
        }
        h1 {
            color: #2c3e50;
        }
        .bio {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .skills {
            margin-top: 20px;
        }
        .skills li {
            margin-bottom: 5px;
        }
    </style>
</head>
<body>
    <h1>Hi, I'm [Your Name]</h1>
    <div class="bio">
        <p>Welcome to my personal site! I'm learning Django and cloud deployment with AWS.</p>
        <div class="skills">
            <h2>What I'm Learning</h2>
            <ul>
                <li>Python and Django</li>
                <li>AWS Cloud Services</li>
                <li>Web Development</li>
            </ul>
        </div>
    </div>
</body>
</html>
Deploy your update to AWS

Your updated homepage looks good locally. Now push it live so the rest of the world can see it too.

  • Deploy your updated app by running this command:
eb deploy

What does eb deploy do?

The eb deploy command packages up your project files, uploads them to Elastic Beanstalk, and swaps in the new version on your running server. This is the same command you'll run every time you want to push an update.

The deployment takes about a minute. You'll see progress messages in the terminal as Elastic Beanstalk updates your environment.

  • Once the deployment finishes, open your live site by running:
eb open
  • Your browser opens to your live site. You should see the new "What I'm Learning" section with the skills list on your public URL.

Live site doesn't show your changes?

  • Try a hard refresh in your browser with Cmd+Shift+R (macOS) or Ctrl+Shift+R (Windows). Your browser may be caching the old page.
  • Run eb status and check that the status shows Ready. If it says Updating, the deployment is still in progress. Wait a minute and try again.
  • Make sure you saved home.html before running eb deploy. The deploy command packages whatever is on disk at the time you run it.

My updated Django site isn't showing changes after running eb deploy.

This is the real workflow

What you just did (edit code, deploy, verify) is the same cycle that professional teams repeat every day. The only difference is that production teams add automated testing and code review before the deploy step.

Secret mission

Add a Projects Page

Your site only has one page right now. Real websites let visitors browse between multiple pages. Add a Projects page with its own URL route, connect both pages with navigation links, and redeploy to prove you can ship updates on demand.

Before you go

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project created AWS resources that cost money while running, though new accounts with Free Tier credits should be covered.

Cost warning

Your Elastic Beanstalk environment includes an EC2 instance that incurs charges while it is running. Elastic Beanstalk itself is free, but you pay for the underlying EC2 instance. New AWS accounts receive up to $200 in Free Plan credits, which cover these costs. If your credits have expired or you are on an older account, terminate the environment to avoid ongoing charges.

Resources you used:

  • 1 Elastic Beanstalk application (django-tutorial).
  • 1 Elastic Beanstalk environment (django-env) with an EC2 instance.
  • Local virtual environment (eb-virt).
  • Local project folder (ebdjango).

Keep everything running

No action needed. Choose this if you are still actively building or want your site to stay live.

  • Your site remains accessible at its .elasticbeanstalk.com URL.
  • Monitor your usage in the AWS Billing dashboard to make sure Free Tier credits are covering the costs.

Pause - I'll come back to this later

Terminate the environment to stop all charges, but keep your local files so you can redeploy later.

  • Run this command from your project directory to terminate the environment:
eb terminate django-env
  • This deletes the EC2 instance and stops all AWS charges.
  • Your local project files and virtual environment stay intact.
  • When you are ready to come back, activate your virtual environment and run eb create django-env to redeploy.

Delete - I don't want to use this again

Remove all project resources from AWS and clean up your local files.

  • Terminate the Elastic Beanstalk environment:
eb terminate django-env
  • Open the Elastic Beanstalk console in AWS and delete the django-tutorial application.
  • Delete your local project folder (ebdjango).
  • Delete your virtual environment folder (eb-virt).

Mission accomplished

That's a Wrap!

You just went from zero to a live website on AWS. That is a real deployment, not a localhost demo.

You've learned how to:

  • Build a Django web app from scratch with a custom view, URL route, and HTML template.
  • Configure Django for production with Elastic Beanstalk using requirements.txt, .ebextensions, and ALLOWED_HOSTS.
  • Deploy to AWS and get a live, publicly accessible URL. Then update your app and redeploy with eb deploy.
  • Add a second Projects page with its own URL route and navigation links, then redeploy to practice the full update cycle.

Ready to quiz yourself?