Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Docker Compose Environment Variables
# Copy this file to .env and customize as needed

# Override ports for parallel development (optional)
# Useful when running multiple branches simultaneously
# WEB_PORT=8001
# PG_PORT=5433

# Override git branch detection (optional - normally auto-detected)
# GIT_BRANCH=my-custom-branch

# Override Docker image name (optional)
# DOCKER_IMAGE=python.ie/website:custom-tag

# Override database name (optional)
# PGDATABASE=pythonie_custom
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ project.db

# Environment files with sensitive credentials
.envrc
.env
development.env
production.env

# Database dumps and local databases
*.dump
*.duckdb
*.sqlite3

# Local settings
pythonie/pythonie/settings/pgdev.py
Expand Down
224 changes: 224 additions & 0 deletions DOCKER-BRANCHES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
# Docker Multi-Branch Development

This setup allows you to run isolated Docker environments for each git branch, preventing conflicts when switching branches or working on multiple features simultaneously.

## How It Works

### Automatic Branch Detection

The system automatically:
- Detects your current git branch (`git rev-parse --abbrev-ref HEAD`)
- Normalizes the branch name (e.g., `feature/add-auth` β†’ `feature-add-auth`)
- Uses this normalized name for:
- Docker image tags: `python.ie/website:feature-add-auth`
- Database names: `pythonie_feature-add-auth`
- Container names: `pythonie-web-feature-add-auth`
- Docker volumes: `postgres-data-feature-add-auth`

### Branch Isolation

Each branch gets:
- βœ… Its own Docker image
- βœ… Its own PostgreSQL database (isolated data)
- βœ… Its own SQLite database for local dev: `pythonie/db-{branch}.sqlite3`
- βœ… Its own Redis instance (isolated cache)
- βœ… Its own Docker volumes (persistent storage)
- βœ… Unique container names (no conflicts)

## Usage

### Basic Commands

```bash
# Check your current branch environment
task branch:info

# Build image for current branch
task docker:build

# Run development server (uses current branch)
task run

# Run tests (uses current branch database)
task tests

# Django shell for current branch
task django:shell-plus
```

### Working on Multiple Branches

**Scenario**: You want to work on `feature/auth` while keeping `main` running.

```bash
# Terminal 1: Main branch
git checkout main
task run
# β†’ Uses: python.ie/website:main, pythonie_main database, port 8000

# Terminal 2: Feature branch (in another terminal)
git checkout feature/auth
task run
# β†’ ERROR: Port 8000 already in use!
```

**Solution**: Use custom ports for parallel instances:

```bash
# Terminal 1: Main branch
git checkout main
task run

# Terminal 2: Feature branch with custom port
git checkout feature/auth
WEB_PORT=8001 PG_PORT=5433 task run
# β†’ Uses: port 8001, separate database
```

### Managing Volumes

```bash
# List all volumes (all branches)
task branch:volumes

# Example output:
# pythonie-postgres-data-master
# pythonie-postgres-data-feature-add-auth
# pythonie-redis-data-master
# pythonie-redis-data-feature-add-auth

# Clean volumes for current branch (DESTRUCTIVE!)
task branch:clean
# β†’ Deletes all data for current branch
```

### Switching Branches

When you switch branches, the system automatically uses the correct environment:

```bash
# On main branch
git checkout main
task run # Uses main database

# Switch to feature branch
git checkout feature/add-auth
task run # Automatically uses feature-add-auth database
```

**Important**: You must rebuild the image after switching branches if dependencies changed:

```bash
git checkout feature/new-dependencies
task docker:build # Rebuild image with new dependencies
task run
```

## Advanced: Custom Ports for Parallel Development

Create a `.env` file (git-ignored) to override default ports:

```bash
# .env
WEB_PORT=8001
PG_PORT=5433
```

Or pass them inline:

```bash
WEB_PORT=8001 PG_PORT=5433 task run
```

## Troubleshooting

### Port Already in Use

```
Error: port 8000 already in use
```

**Solution**: Stop other instances or use custom ports:
```bash
task down # Stop all containers for current branch
# OR
WEB_PORT=8001 PG_PORT=5433 task run
```

### Database Not Found

```
FATAL: database "pythonie_feature-xyz" does not exist
```

**Solution**: Run migrations to create the database:
```bash
task django:migrate
```

### Wrong Database Being Used

```bash
# Check which environment is active
task branch:info

# Ensure you're on the correct git branch
git branch

# Rebuild if needed
task docker:build
```

### Cleaning Up Old Branches

After deleting a git branch, clean up its Docker resources:

```bash
# Remove unused images
docker image prune -a

# Remove volumes for deleted branches
# (replace 'old-branch-name' with actual normalized branch name)
docker volume rm pythonie-postgres-data-old-branch-name
docker volume rm pythonie-redis-data-old-branch-name

# Or use the helper (must be on that branch)
git checkout old-branch-name
task branch:clean
```

## Environment Variables Reference

| Variable | Default | Description |
|----------|---------|-------------|
| `GIT_BRANCH` | Auto-detected | Current git branch (normalized) |
| `DOCKER_IMAGE` | `python.ie/website:{branch}` | Docker image name |
| `PGDATABASE` | `pythonie_{branch}` | PostgreSQL database name |
| `WEB_PORT` | `8000` | Web server port |
| `PG_PORT` | `5432` | PostgreSQL port |

## Tips

1. **Branch Naming**: Use descriptive branch names. They'll appear in container names and logs.

2. **Disk Space**: Each branch creates separate volumes. Monitor disk usage:
```bash
docker system df
```

3. **Production**: This system is for **development only**. Production uses fixed names and ports.

4. **Database Migrations**: Each branch has independent migrations. Remember to run `task django:migrate` after switching branches with schema changes.

5. **Shared Data**: If you need to copy data between branches:
```bash
# Export from main
git checkout main
task run:postgres # Start just postgres
pg_dump -U postgres pythonie_main > /tmp/main.sql

# Import to feature branch
git checkout feature/xyz
task run:postgres
psql -U postgres pythonie_feature-xyz < /tmp/main.sql
```
85 changes: 84 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Website for Python Ireland (python.ie / pycon.ie) community, built with Django 6

## Quick Start (Docker - Recommended)

**Note**: Each git branch automatically gets its own isolated database and Docker environment. See [Docker Branch Isolation](#docker-branch-isolation) below.

1. Build the Docker image:
```bash
task docker:build
Expand All @@ -20,7 +22,7 @@ Website for Python Ireland (python.ie / pycon.ie) community, built with Django 6

2. Start supporting services:
```bash
docker compose up -d postgres redis minio
docker compose up -d postgres redis
```

3. Run database migrations:
Expand Down Expand Up @@ -48,10 +50,79 @@ Website for Python Ireland (python.ie / pycon.ie) community, built with Django 6
7. Visit http://127.0.0.1:8000/ to see the site with sample content
8. Access Wagtail admin at http://127.0.0.1:8000/admin/

## Docker Branch Isolation

The project automatically isolates Docker environments by git branch, allowing you to work on multiple branches simultaneously without conflicts.

### How It Works

Each git branch gets:
- **Separate Docker image**: `python.ie/website:{branch-name}`
- **Isolated PostgreSQL database**: `pythonie_{branch-name}` (for docker-compose with pgdev settings)
- **Isolated SQLite database**: `pythonie/db-{branch-name}.sqlite3` (for local dev)
- **Dedicated volumes**: `pythonie-postgres-data-{branch}`, `pythonie-redis-data-{branch}`
- **Unique containers**: `pythonie-web-{branch}`, `pythonie-postgres-{branch}`, `pythonie-redis-{branch}`

### Branch Commands

```bash
# Check your current branch environment
task branch:info

# Verify database configuration
task branch:verify

# List all Docker volumes (all branches)
task branch:volumes

# Clean up volumes for current branch (DESTRUCTIVE!)
task branch:clean
```

### Working on Multiple Branches

**Scenario**: Work on `main` and `feature/new-auth` simultaneously.

```bash
# Terminal 1: Main branch on default ports
git checkout main
task run # Uses pythonie_main database on port 8000

# Terminal 2: Feature branch on custom ports
git checkout feature/new-auth
WEB_PORT=8001 PG_PORT=5433 task run # Uses pythonie_feature-new-auth on port 8001
```

### Switching Branches

When you switch branches, the system automatically uses the correct environment:

```bash
git checkout main
task run # Automatically uses main database

git checkout feature/xyz
task run # Automatically uses feature-xyz database (isolated from main)
```

**Note**: Rebuild the Docker image after switching branches if dependencies changed:
```bash
git checkout feature/new-dependencies
task docker:build
task run
```

For detailed documentation, see [DOCKER-BRANCHES.md](DOCKER-BRANCHES.md).

## Local Setup (Without Docker)

If you prefer to develop without Docker:

**Note**: When developing locally, each git branch automatically uses its own SQLite database (`db-{branch}.sqlite3`). Export `GIT_BRANCH` for automatic isolation:
```bash
export GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD | sed 's/[^a-zA-Z0-9._-]/-/g' | tr '[:upper:]' '[:lower:]')
```

1. Fork the repository into your own personal GitHub account
2. Clone your fork: `git clone git@github.com:YourGitHubName/website.git`
3. Ensure you are running Python 3.13: `python -V` should output `Python 3.13.x`
Expand Down Expand Up @@ -134,6 +205,12 @@ task heroku:releases # Show deployment history
task heroku:rollback # Rollback to previous release
task heroku:maintenance:on # Enable maintenance mode
task heroku:maintenance:off # Disable maintenance mode

# Branch Isolation (Docker)
task branch:info # Show current branch and environment info
task branch:verify # Verify database configuration
task branch:volumes # List all Docker volumes (all branches)
task branch:clean # Remove volumes for current branch (CAUTION!)
```

### Direct Django Commands
Expand Down Expand Up @@ -257,6 +334,12 @@ This project uses several tools to streamline development:
- Rebuild Docker image: `task docker:build`
- Reinstall dependencies: `pip install -r requirements.txt`

### Wrong Database Being Used
- Check current branch: `git branch`
- Verify environment: `task branch:info`
- Check database configuration: `task branch:verify`
- Ensure .env file is up to date: `task env:write`

## Contributing

1. Fork the repository into your own GitHub account
Expand Down
Loading