Skip to main content

Overview

This guide will help you set up a local development environment for ESP Website. We’ll use Docker to ensure a consistent setup that works on all platforms without requiring manual installation of Python, PostgreSQL, or other dependencies.
Docker-based setup is recommended for all developers. It requires only Docker and Docker Compose to be installed on your machine.

Prerequisites

Install Docker Desktop for Windows.Requirements:
  • Windows 10 64-bit: Pro, Enterprise, or Education (Build 19041 or higher)
  • WSL 2 feature enabled
  • At least 4GB of RAM
Verify Docker is installed correctly:
docker --version
docker compose version

Quick Start with Docker

Get a development server running in under 5 minutes.
1

Clone the repository

git clone https://github.com/learning-unlimited/ESP-Website.git devsite
cd devsite
2

Build and start the services

docker compose up --build
This command will:
  • Build the Docker images (takes several minutes on first run)
  • Start three containers: web (Django), db (PostgreSQL), and memcached
  • Automatically run database migrations
  • Collect static files
  • Start the development server
The first build takes 5-10 minutes. Subsequent starts are much faster due to Docker layer caching.
3

Access the site

Once you see Starting development server at http://0.0.0.0:8000/, open your browser to:
http://localhost:8000
You should see the ESP Website homepage!
4

Create an admin account

Open a new terminal window (keep the server running) and execute:
docker compose exec web python esp/manage.py createsuperuser
Follow the prompts to create your admin account.
Your development environment is ready! Log in at http://localhost:8000/admin with your superuser credentials.

Docker Architecture

The Docker setup runs three interconnected containers:

web

Django Application
  • Python 3.7
  • Django web framework
  • Runs on port 8000
  • Code is mounted from host

db

PostgreSQL 14
  • Database server
  • Data persisted in volume
  • Accessible on port 5432

memcached

Memcached Cache
  • Caching layer
  • Improves performance
  • Runs on port 11211

What Happens on First Run?

The docker-entrypoint.sh script automatically:
  1. Creates local_settings.py from the Docker template (if missing)
  2. Creates media symlinks (images, styles)
  3. Waits for PostgreSQL to be ready
  4. Runs database migrations
  5. Collects static files
  6. Starts the Django development server
Your working copy is mounted into the container, so code changes on your host machine are reflected immediately. No rebuild needed for most changes!

Common Docker Commands

Stop containers:
docker compose down
Stop and delete database (fresh start):
docker compose down -v
Start containers (no rebuild):
docker compose up
Rebuild containers:
docker compose down
docker compose up --build
Force setup to re-run migrations:
FORCE_SETUP=1 docker compose up
Run any Django management command:
docker compose exec web python esp/manage.py <command>
Common examples:
# Open Django shell with auto-imported models
docker compose exec web python esp/manage.py shell_plus

# Run database migrations
docker compose exec web python esp/manage.py migrate

# Run tests
docker compose exec web python esp/manage.py test

# Create a superuser
docker compose exec web python esp/manage.py createsuperuser

# Collect static files
docker compose exec web python esp/manage.py collectstatic
Access PostgreSQL shell:
docker compose exec db psql -U esp devsite_django
View database tables:
\dt
Backup database:
docker compose exec db pg_dump -U esp devsite_django > backup.sql
Restore database:
docker compose down -v
docker compose up -d db
sleep 5
docker cp backup.sql $(docker compose ps -q db):/tmp/backup.sql
docker compose exec db psql -U esp devsite_django -f /tmp/backup.sql
Open bash shell in web container:
docker compose exec web bash
View container logs:
docker compose logs web
docker compose logs db
docker compose logs memcached
Follow logs in real-time:
docker compose logs -f web

Loading an Existing Database

If you have a database dump from a production site or previous development setup, you can load it into your Docker environment.
1

Start with a clean database

docker compose down -v
docker compose up -d
Wait a few seconds for PostgreSQL to initialize.
2

Copy dump into container

docker cp /path/to/dump.sql $(docker compose ps -q db):/tmp/dump.sql
3

Load the dump

docker compose exec db psql -U esp devsite_django -f /tmp/dump.sql
4

Run migrations

Ensure the schema matches the current code:
docker compose exec web python esp/manage.py migrate
If you see ownership or permission errors, the --no-owner --no-acl flags will help. For plain SQL dumps, you can safely ignore ALTER OWNER errors.

Configuration

The Docker setup uses esp/esp/local_settings.py.docker as the template for local settings.

Default Docker Configuration

Key settings automatically configured for Docker:
esp/esp/local_settings.py
# Database connects to 'db' service
DATABASES['default']['HOST'] = 'db'

# Memcached connects to 'memcached' service  
CACHES['default']['LOCATION'] = 'memcached:11211'

# Allow all hosts (development only)
ALLOWED_HOSTS = ['*']

Customizing Settings

1

Edit local_settings.py

After the first run, you can edit esp/esp/local_settings.py directly.This file is gitignored, so your changes won’t be committed.
2

Or modify the template

To change defaults for all Docker users, edit:esp/esp/local_settings.py.docker
3

Restart to apply changes

docker compose restart web

Troubleshooting

Error: Bind for 0.0.0.0:8000 failed: port is already allocatedSolution: Either stop the conflicting service or change the port in docker-compose.yml:
docker-compose.yml
services:
  web:
    ports:
      - "9000:8000"  # Access at localhost:9000
Error: could not connect to server: Connection refusedSolution: The entrypoint waits for PostgreSQL, but if you still see errors:
docker compose restart web
Error: Files created inside container are owned by rootSolution: Fix ownership on your host:
sudo chown -R $USER:$USER .
Error: Site seems broken after pulling new codeSolution: Clean rebuild:
docker compose down -v
FORCE_SETUP=1 docker compose up --build
Error: invalid file request esp/public/media/imagesSolution: Remove symlinks before rebuilding:
docker compose down
docker compose up --build
Windows error: open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specifiedmacOS error: Cannot connect to the Docker daemonSolution:
  1. Open Docker Desktop
  2. Wait for the icon to show it’s ready
  3. Verify with: docker info
  4. Retry: docker compose up --build
Windows only: Ensure “Use the WSL 2 based engine” is checked in Docker Desktop Settings → General.

Development Workflow

Once your environment is set up, follow this workflow for making changes:
1

Create a feature branch

git checkout main
git pull
git checkout -b new-feature-name
2

Make your changes

Edit code in your preferred editor on your host machine. Changes are immediately reflected in the running container.
3

Run tests

docker compose exec web python esp/manage.py test
All tests must pass before submitting a pull request!
4

Commit and push

git add .
git commit -m "Description of changes"
git push --set-upstream origin new-feature-name
5

Create a pull request

Go to GitHub and create a pull request from your branch.

Running Tests

Testing is a critical part of the development workflow.
docker compose exec web python esp/manage.py test
Tests run faster on subsequent runs because the test database is cached.

Alternative: Native Installation

While Docker is recommended, you can also run ESP Website natively on your machine.
Native installation is more complex and requires managing Python versions, PostgreSQL, and other dependencies manually. Use Docker unless you have a specific reason not to.
Requirements:
  • Python 3.7
  • PostgreSQL 12+
  • Memcached
  • Git
Steps:
  1. Clone the repository:
    git clone https://github.com/learning-unlimited/ESP-Website.git devsite
    cd devsite
    
  2. Create a virtual environment:
    cd esp
    ./make_virtualenv.sh
    source env/bin/activate
    
  3. Install dependencies:
    pip install -r requirements.txt
    ./packages_base_manual_install.sh
    
  4. Set up PostgreSQL:
    createdb devsite_django
    createuser esp
    
  5. Configure local settings:
    cp esp/local_settings.py.example esp/local_settings.py
    # Edit with your database credentials
    
  6. Run migrations:
    ./manage.py migrate
    
  7. Start the server:
    ./manage.py runserver
    

Next Steps

Quickstart Guide

Create your first program and learn the basics

Contributing Guide

Learn how to contribute code to the project

Directory Structure

Explore the codebase organization

Program Modules

Understand the module system

Quickstart Guide

Create your first program

Directory Structure

Understand how the codebase is organized

Program Modules

Learn about the modular architecture

Getting Help

If you encounter issues during installation:

Build docs developers (and LLMs) love