Django

Host Djnago Project on PythonAnywhere

Luv Baniya

Host Djnago Project on PythonAnywhere

You've built your Django project locally. It runs fine on localhost:8000. Now you want the world to see it. PythonAnywhere is the easiest place to host a Django app for free — no server setup, no Linux knowledge required, just a browser and your code.

What Is PythonAnywhere?

PythonAnywhere is a cloud platform built specifically for Python. Unlike AWS or DigitalOcean, you don't configure servers, install packages globally, or worry about firewalls. They handle the infrastructure. You just upload your code and point a few config files at it.

The free tier gives you one web app at a yourusername.pythonanywhere.com subdomain, a MySQL database, and a Linux console you can use from the browser. That's enough to deploy a real Django project.

The Big Picture Before You Start

Here's the full journey from your laptop to a live URL — so nothing surprises you mid-way:

  1. Create a free PythonAnywhere account
  2. Open a Bash console and clone your project from GitHub (or upload files manually)
  3. Create a virtual environment and install your dependencies
  4. Set up the web app via the PythonAnywhere dashboard
  5. Configure the WSGI file to point at your Django project
  6. Set environment variables (SECRET_KEY, DEBUG, DATABASE_URL)
  7. Run migrations and collect static files
  8. Reload the app — done
PythonAnywhere runs your Django app through a WSGI server. When someone visits your URL, their server calls your Django app the same way runserver does locally — just without the development warnings.

Step 1 — Create Your Account

Go to pythonanywhere.com and sign up for a free Beginner account. Your username becomes part of your live URL — yourusername.pythonanywhere.com — so pick something you're comfortable sharing.

After signup you land on the Dashboard. The important tabs are: Consoles, Web, and Files. You'll use all three.

Step 2 — Open a Bash Console

Click ConsolesBash. This opens a real Linux terminal in your browser. Your files live at /home/yourusername/.

The fastest way to get your code onto PythonAnywhere is from GitHub. If your project is in a repo, clone it now:

git clone https://github.com/yourusername/yourproject.git

If you don't have a GitHub repo yet, you can upload files manually through the Files tab, or use the console to create files directly. GitHub is strongly recommended — it makes future updates a one-command operation.

Step 3 — Create a Virtual Environment

Always use a virtual environment. It keeps your project's packages isolated from PythonAnywhere's system Python and from other projects on the same account.

# Navigate into your project folder
cd yourproject

# Create a virtualenv — match the Python version you used locally
python3.12 -m venv venv

# Activate it
source venv/bin/activate

# Your prompt now shows (venv) — all pip installs go here
pip install -r requirements.txt

If you don't have a requirements.txt, generate one locally first with pip freeze > requirements.txt and push it to GitHub.

After installing, verify Django is available:

python -c "import django; print(django.__version__)"

Step 4 — Create the Web App

Go to the Web tab in the PythonAnywhere dashboard and click Add a new web app. Walk through the wizard:

  1. Domain — on the free plan it's fixed as yourusername.pythonanywhere.com
  2. Framework — select Manual configuration (not the "Django" option — that creates a new blank project)
  3. Python version — match what you used locally (3.12 recommended)

After clicking through, PythonAnywhere creates a default WSGI file and shows you the web app configuration page. Keep this page open — you'll edit several fields here.

Step 5 — Configure the WSGI File

The WSGI file is the bridge between PythonAnywhere's server and your Django app. On the Web tab, click the link next to WSGI configuration file — it will be something like /var/www/yourusername_pythonanywhere_com_wsgi.py.

Delete everything in that file and replace it with this:

import sys
import os

# Add your project directory to the Python path
path = '/home/yourusername/yourproject'
if path not in sys.path:
    sys.path.insert(0, path)

# Tell Django which settings file to use
os.environ['DJANGO_SETTINGS_MODULE'] = 'yourproject.settings'

# Load the Django WSGI application
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Replace yourusername with your actual PythonAnywhere username, yourproject with your project folder name, and yourproject.settings with the Python path to your settings module (the same value you'd use in DJANGO_SETTINGS_MODULE locally).

Step 6 — Set the Virtualenv Path

Back on the Web tab, scroll to the Virtualenv section. Enter the full path to your virtual environment:

/home/yourusername/yourproject/venv

PythonAnywhere will validate the path and show a green checkmark if it finds it. This tells the WSGI server to use your project's packages, not the system ones.

Step 7 — Fix Your settings.py for Production

A settings file that works locally will break in production if you don't update a few values. Open your settings.py in the PythonAnywhere file editor or via the console:

# settings.py — production changes

# 1. Turn DEBUG off — never run with DEBUG=True in production
DEBUG = False

# 2. Add your PythonAnywhere domain
ALLOWED_HOSTS = ['yourusername.pythonanywhere.com']

# 3. Tell Django where static files are served from
STATIC_URL = '/static/'
STATIC_ROOT = '/home/yourusername/yourproject/staticfiles'

# 4. For media uploads (if you use ImageField / FileField)
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/yourusername/yourproject/media'

Keep your SECRET_KEY secret. Don't commit it to GitHub. The safest approach is to read it from an environment variable:

import os
SECRET_KEY = os.environ.get('SECRET_KEY', 'fallback-for-local-dev-only')

You set the actual value in the Environment variables section on the Web tab.

Step 8 — Static Files

Django's runserver serves static files automatically in development. In production it doesn't — a proper web server does that. You need to collect all your static files into one folder and tell PythonAnywhere where to serve them from.

In the Bash console (with your virtualenv active):

cd /home/yourusername/yourproject
python manage.py collectstatic

This copies everything from your app's static/ folders into STATIC_ROOT (/home/yourusername/yourproject/staticfiles).

Now go to the Web tab, scroll to Static files, and add a mapping:

URL:       /static/
Directory: /home/yourusername/yourproject/staticfiles

If you use media uploads, add a second mapping:

URL:       /media/
Directory: /home/yourusername/yourproject/media

Step 9 — Database Setup

If you're using SQLite (the default for new Django projects), it works on PythonAnywhere with no extra configuration — the .sqlite3 file just lives in your project folder. Run your migrations:

python manage.py migrate

If you want a more robust setup, PythonAnywhere's free tier includes a MySQL database. Go to the Databases tab, create one, and update your settings.py DATABASES block to use it.

After migrating, create a superuser so you can access the admin panel:

python manage.py createsuperuser

Step 10 — Reload and Visit Your Site

Go back to the Web tab and click the big green Reload button. PythonAnywhere restarts your app with all the new configuration.

Open a new browser tab and go to:

https://yourusername.pythonanywhere.com

If you see your Django homepage — you're live. If you see an error, the next section explains exactly where to look.

Debugging Common Errors

When something goes wrong, the error log tells you exactly what. On the Web tab, click Error log — it's a live log of every exception Django has thrown. Read the last few lines first.

ErrorMost likely causeFix
ModuleNotFoundError Package not installed in virtualenv, or wrong virtualenv path Check virtualenv path on Web tab; run pip install again
DisallowedHost Your domain isn't in ALLOWED_HOSTS Add yourusername.pythonanywhere.com to ALLOWED_HOSTS
Static files returning 404 Static file URL/directory mapping missing or wrong path Re-run collectstatic; check the mapping on the Web tab
OperationalError: no such table Migrations haven't been run Run python manage.py migrate in the console
500 error with blank page DEBUG = False hides the error details Check the error log — the traceback is always there even with DEBUG off
Old code still showing App not reloaded after code change Click Reload on the Web tab every time you change Python files

Updating Your Site After Changes

Every time you push new code to GitHub and want it live, the workflow is:

# In PythonAnywhere Bash console
cd /home/yourusername/yourproject

# Pull the latest code
git pull origin main

# If you added new packages
source venv/bin/activate
pip install -r requirements.txt

# If you changed models
python manage.py migrate

# If you changed static files
python manage.py collectstatic --noinput

Then go to the Web tab and hit Reload. That's the entire deployment process for every future update.

Pre-Launch Checklist

  • DEBUG = False in settings
  • Your domain in ALLOWED_HOSTS
  • SECRET_KEY not committed to GitHub — loaded from environment
  • Virtualenv path set correctly on Web tab
  • WSGI file updated with correct project path and settings module
  • Static files URL/directory mapping added on Web tab
  • collectstatic has been run
  • migrate has been run
  • Superuser created — admin panel accessible at /admin/
  • Reload clicked after all changes

PythonAnywhere's free tier has one limitation worth knowing: your app goes to sleep after 3 months of inactivity unless you log in and click a "keep alive" button on the Web tab. Set a monthly reminder and you'll never lose your deployment.

Next in the series: connecting a custom domain to PythonAnywhere and switching from SQLite to a production MySQL database.

Related notes