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
34 changes: 13 additions & 21 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
# Optional:
# VPS_SSH_PORT defaults to 22
#
# The six images are published as:
# codeheist/spidder-{http-api,ws-server,judge-worker,web,admin,db-init}
# The five images are published as:
# codeheist/spidder-{http-api,ws-server,judge-worker,web,admin}
#
# DOCKERHUB_USERNAME supplies that namespace when PUSHING here; the compose
# file on the server writes `codeheist` literally when PULLING. Change one and
# you must change the other, or CI pushes somewhere the server never looks.
#
# Docker Hub's free tier gives ONE private repository. Six private images
# means a paid plan; otherwise create the six repos as public. They contain
# Docker Hub's free tier gives ONE private repository. Five private images
# means a paid plan; otherwise create the five repos as public. They contain
# only compiled application code — no secrets, since every credential is
# injected at runtime from the server's .env. The exceptions are `web` and
# `admin`: NEXT_PUBLIC_* are compiled into their browser bundles, and those are
Expand Down Expand Up @@ -119,9 +119,9 @@ jobs:
run: pnpm --filter @repo/game test

# ---------------------------------------------------------------------------
# Build the six images in parallel and push them to Docker Hub.
# Build the five images in parallel and push them to Docker Hub.
#
# A matrix rather than six copies of the same block: the only thing that
# A matrix rather than five copies of the same block: the only thing that
# differs is the Dockerfile path and the image name.
# ---------------------------------------------------------------------------
build:
Expand All @@ -135,7 +135,7 @@ jobs:
# GITHUB_TOKEN push to GHCR — would be an unused grant.
contents: read
strategy:
# One image failing should not cancel the other five — seeing every
# One image failing should not cancel the other four — seeing every
# failure in one run beats fixing them one deploy at a time.
fail-fast: false
matrix:
Expand All @@ -150,8 +150,6 @@ jobs:
dockerfile: apps/web/Dockerfile.prod
- name: admin
dockerfile: apps/admin/Dockerfile.prod
- name: db-init
dockerfile: docker/db-init/Dockerfile
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -290,19 +288,13 @@ jobs:

# NO SCHEMA STEP HERE, deliberately.
#
# A deploy pulls images and restarts containers. It must not alter the
# database as a side effect: the old step ran db-init on every push to
# main, and db-init re-runs a seed that DELETES every problem and test
# case before re-inserting three samples.
# A deploy pulls images and restarts containers; nothing in this
# pipeline can reach the database. Schema changes are applied by hand
# on the server — see DEPLOYMENT.md section 5.
#
# Apply a schema change yourself, on the server, when a release
# actually carries one:
#
# docker compose -f docker-compose.prod.yml run --rm db-init
#
# The tradeoff is explicit: forget it and the apps run against the old
# schema until you remember. A visible failure beats a deploy that can
# quietly rewrite data.
# The tradeoff is explicit: ship a release that needs a migration and
# forget to run it, and the apps fail against the old schema until you
# do. A visible failure beats a deploy that can rewrite data.

echo "::group::Restarting services"
docker compose -f docker-compose.prod.yml up -d --remove-orphans
Expand Down
21 changes: 0 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,6 @@ only a passed-count — and the hidden tests never reach a client.

---

## Quick start

You need **Docker** and nothing else.

```bash
git clone https://github.com/TheCodeHeist-Coder/Spidder.git spidder
cd spidder
docker compose up --build
```

Open **<http://localhost:3001>**.

On first boot the stack applies the database schema, seeds the problems, and
installs the Python 3.12 runtime into the code sandbox — automatically. The app
services wait for all of it, so the first request can never hit an unmigrated
database or an empty sandbox.

Your source is bind-mounted, so this is already the hot-reload stack: edit a
file on your host and the containers pick it up in about a second.

Full instructions, including running without Docker, are in **[SETUP.md](SETUP.md)**.

### Documentation

Expand Down
58 changes: 38 additions & 20 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ services:
depends_on:
- http-api
- ws-server
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

admin:
build:
Expand All @@ -55,6 +60,11 @@ services:
- spidder-network
depends_on:
- http-api
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

http-api:
build:
Expand All @@ -79,6 +89,11 @@ services:
# address them; there is no db service to depend_on.
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

ws-server:
build:
Expand All @@ -95,6 +110,11 @@ services:
- spidder-network
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

judge-worker:
build:
Expand All @@ -112,6 +132,11 @@ services:
depends_on:
piston:
condition: service_healthy
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

piston:
image: ghcr.io/engineer-man/piston
Expand All @@ -131,6 +156,11 @@ services:
timeout: 5s
retries: 20
start_period: 30s
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

# Installs the Python runtime into piston, then exits. Idempotent.
piston-init:
Expand All @@ -147,27 +177,15 @@ services:
depends_on:
piston:
condition: service_healthy
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

# Applies Prisma migrations to the host PostgreSQL, then exits.
#
# NOT a database — it is a one-shot client carrying the Prisma CLI, which
# the slim app images do not include. Run it by hand when a release carries
# a schema change; nothing starts it automatically:
#
# docker compose -f docker-compose.prod.yml run --rm db-init
db-init:
build:
context: .
dockerfile: docker/db-init/Dockerfile
image: codeheist/spidder-db-init:${IMAGE_TAG:-latest}
container_name: spidder-db-init-prod
restart: "no"
env_file:
- .env.prod
networks:
- spidder-network
extra_hosts:
- "host.docker.internal:host-gateway"
# No db-init service: the schema is applied by hand, from a checkout on the
# server, not by anything in this file. Nothing here can touch the database.
# See DEPLOYMENT.md section 5.

# No db or redis services: PostgreSQL and Redis are installed on the host
# via apt and reached through host.docker.internal. The host must let them
Expand Down
Loading
Loading