Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/backend-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

services:
postgres:
image: postgres:16-alpine
image: ghcr.io/marcodejongh/boardsesh-postgres-postgis:latest
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: boardsesh_backend_test
Expand Down
191 changes: 191 additions & 0 deletions .github/workflows/dev-db-docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: Build and Publish Dev Database Docker Images

on:
push:
branches: [main]
paths:
- 'packages/db/docker/**'
- '.github/workflows/dev-db-docker.yml'
pull_request:
paths:
- 'packages/db/docker/**'
- '.github/workflows/dev-db-docker.yml'
workflow_dispatch:

env:
REGISTRY: ghcr.io

jobs:
build-postgres-postgis:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write

env:
IMAGE_NAME: boardsesh-postgres-postgis

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: ./packages/db/docker
file: ./packages/db/docker/Dockerfile.postgres
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=postgres-postgis
cache-to: type=gha,mode=max,scope=postgres-postgis

- name: Generate artifact attestation
if: ${{ github.event_name != 'pull_request' }}
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true

build-dev-db:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write

env:
IMAGE_NAME: boardsesh-dev-db

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: ./packages/db
file: ./packages/db/docker/Dockerfile.dev-db
# arm64 excluded: QEMU emulation can't bind TCP sockets, which pgloader
# needs during build. Apple Silicon users can pull the amd64 image
# (Docker Desktop runs it via Rosetta 2) or build locally (native, no QEMU).
platforms: linux/amd64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=dev-db
cache-to: type=gha,mode=max,scope=dev-db

- name: Generate artifact attestation
if: ${{ github.event_name != 'pull_request' }}
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true

build-db-setup:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write

env:
IMAGE_NAME: boardsesh-db-setup

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./packages/db/docker/Dockerfile
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=db-setup
cache-to: type=gha,mode=max,scope=db-setup

- name: Generate artifact attestation
if: ${{ github.event_name != 'pull_request' }}
uses: actions/attest-build-provenance@v1
with:
subject-name: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.build.outputs.digest }}
push-to-registry: true
2 changes: 1 addition & 1 deletion .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:

services:
postgres:
image: postgres:16
image: ghcr.io/marcodejongh/boardsesh-postgres-postgis:latest
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
Expand Down
16 changes: 15 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ Before working on a specific part of the codebase, check the `docs/` directory f

### Development Setup

The development database uses a **pre-built Docker image** (`ghcr.io/marcodejongh/boardsesh-dev-db`) that already contains all Kilter and Tension board data with migrations applied. This means `npm run db:up` is fast — it just pulls the image, starts containers, runs any newer migrations, and imports MoonBoard data.

```bash
# Start development databases (PostgreSQL, Neon proxy, Redis)
# First run pulls the pre-built image (~1GB) with all board data included.
# Subsequent runs start in seconds.
npm run db:up

# Environment files are in packages/web/:
Expand All @@ -56,6 +60,16 @@ npm run dev
npm run backend:dev
```

#### Pre-built database image

The `boardsesh-dev-db` image is published to GHCR and contains PostgreSQL 17 + PostGIS with all Kilter/Tension board data pre-loaded via pgloader and all drizzle migrations applied. It is rebuilt automatically when files in `packages/db/docker/` change on main.

- **Pull directly**: `docker pull ghcr.io/marcodejongh/boardsesh-dev-db:latest`
- **Reset your local database**: `docker compose down -v && npm run db:up`
- **Build locally** (e.g. to test Dockerfile changes): `docker compose up -d --build postgres`

MoonBoard data is not included in the image (it requires the Neon HTTP proxy for import). It is automatically downloaded and imported by `npm run db:up` on first run.

### Common Commands (from root)

- `npm run dev` - Start web development server with Turbopack
Expand All @@ -70,7 +84,7 @@ npm run backend:dev
- `npm run typecheck:shared` - Type check shared-schema package only
- `npm run backend:dev` - Start backend in development mode
- `npm run backend:start` - Start backend in production mode
- `npm run db:up` - Start development databases (PostgreSQL, Neon proxy, Redis)
- `npm run db:up` - Start development databases, run migrations, and import MoonBoard data (uses pre-built image with Kilter/Tension data)

### Database Commands (run from root or packages/db/)

Expand Down
30 changes: 4 additions & 26 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
services:
postgres:
image: ghcr.io/marcodejongh/boardsesh-dev-db:latest
build:
context: ./packages/db/docker
dockerfile: Dockerfile.postgres
context: ./packages/db
dockerfile: docker/Dockerfile.dev-db
shm_size: '256mb'
command: postgres -c max_connections=300 -c log_min_messages=warning
volumes:
- db_data:/var/lib/postgresql/data
- db_data:/var/lib/postgresql/pgdata
ports:
- '5432:5432'
environment:
Expand Down Expand Up @@ -40,28 +41,5 @@ services:
timeout: 3s
retries: 5

db_setup:
build:
context: .
dockerfile: ./packages/db/docker/Dockerfile
volumes:
- ./packages/db/docker:/db
- ./packages/db/drizzle:/app/drizzle
- ./packages/db/drizzle.config.ts:/app/drizzle.config.ts
- ./packages/db/src/schema:/app/src/schema
- ./packages/db/package.json:/app/package.json
environment:
- POSTGRES_URL=postgres://postgres:password@postgres:5432/main
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_DATABASE=main
- POSTGRES_URL_NON_POOLING=postgres://postgres:password@postgres:5432/main
depends_on:
postgres:
condition: service_healthy
command: /db/setup-development-db.sh

volumes:
db_data:
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
"test:help-screenshots": "TEST_USER_EMAIL=$(op read 'op://Boardsesh/Boardsesh local/username') TEST_USER_PASSWORD=$(op read 'op://Boardsesh/Boardsesh local/password') npx playwright test --project=chromium e2e/help-screenshots.spec.ts --config=packages/web/playwright.config.ts",
"backend:dev": "npm run dev --workspace=boardsesh-backend",
"backend:start": "npm run start --workspace=boardsesh-backend",
"db:up": "[ -f packages/db/docker/tmp/db-setup-complete.flag ] || (echo '❌ Database not initialized. Run `npm run db:setup` first.' && exit 1) && docker-compose up -d postgres neon-proxy redis && sleep 3 && npm run db:migrate && npm run db:import-moonboard -- docker/tmp/problems_2023_01_30",
"db:setup": "docker-compose up db_setup",
"db:up": "sh scripts/dev-db-up.sh",
"db:migrate": "npm run db:migrate --workspace=@boardsesh/db",
"db:studio": "npm run db:studio --workspace=@boardsesh/db",
"db:import-moonboard": "npm run db:import-moonboard --workspace=@boardsesh/db",
Expand Down
Loading
Loading