test(tier1): docker compose stack (gitea seed + backend + web + mailpit)
Wires the four-service Tier-1 integration stack and brings it up green. Fixes found during live bring-up: - gitea-admin-init: run as user 'git'; the gitea CLI refuses to run as root and our custom entrypoint bypasses the image's s6 init that normally drops privileges. - backend.Dockerfile: COPY VERSION to /VERSION; health.py reads the canonical VERSION file from the repo root (parents[2]) at import, so it must exist in the image or the backend crashes on startup. env_file cold-start: generated/.env.tier1.generated is created as an empty placeholder (gitignored) so the backend env_file path always exists; the seeder overwrites it before backend starts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
tier1-up:
|
||||||
|
docker compose -f testing/docker-compose.yml up --build -d
|
||||||
|
|
||||||
|
tier1-down:
|
||||||
|
docker compose -f testing/docker-compose.yml down -v
|
||||||
|
|
||||||
|
tier1-logs:
|
||||||
|
docker compose -f testing/docker-compose.yml logs -f
|
||||||
|
|
||||||
|
fe-unit:
|
||||||
|
cd frontend && npm run test:run
|
||||||
|
|
||||||
|
e2e:
|
||||||
|
cd e2e && BASE_URL=$${BASE_URL:-http://localhost:8080} MAILSINK_URL=$${MAILSINK_URL:-http://localhost:8025} npm run e2e
|
||||||
@@ -7,6 +7,10 @@ COPY backend/requirements.txt /app/requirements.txt
|
|||||||
RUN pip install --no-cache-dir -r requirements.txt uvicorn
|
RUN pip install --no-cache-dir -r requirements.txt uvicorn
|
||||||
|
|
||||||
COPY backend/ /app/
|
COPY backend/ /app/
|
||||||
|
# §20.1: health.py reads the canonical VERSION file from the repo root
|
||||||
|
# (parents[2] of backend/app/health.py). In the image that resolves to
|
||||||
|
# /VERSION, so the file must be copied there or backend import crashes.
|
||||||
|
COPY VERSION /VERSION
|
||||||
|
|
||||||
RUN mkdir -p /data
|
RUN mkdir -p /data
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
name: rfc-tier1
|
||||||
|
|
||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:1.22
|
||||||
|
environment:
|
||||||
|
GITEA__security__INSTALL_LOCK: "true"
|
||||||
|
GITEA__server__ROOT_URL: "http://gitea:3000/"
|
||||||
|
GITEA__server__HTTP_PORT: "3000"
|
||||||
|
GITEA__database__DB_TYPE: "sqlite3"
|
||||||
|
GITEA__webhook__ALLOWED_HOST_LIST: "*"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-sf", "http://localhost:3000/api/healthz"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 30
|
||||||
|
ports:
|
||||||
|
- "3001:3000"
|
||||||
|
|
||||||
|
gitea-admin-init:
|
||||||
|
image: gitea/gitea:1.22
|
||||||
|
# The gitea CLI refuses to run as root (loadRunModeFrom [F] "not
|
||||||
|
# supposed to be run as root"). Our custom entrypoint bypasses the
|
||||||
|
# image's s6 init that normally drops to the git user, so set it here.
|
||||||
|
user: git
|
||||||
|
depends_on:
|
||||||
|
gitea:
|
||||||
|
condition: service_healthy
|
||||||
|
volumes_from:
|
||||||
|
- gitea
|
||||||
|
entrypoint: ["/bin/sh", "-c"]
|
||||||
|
command:
|
||||||
|
- >
|
||||||
|
gitea admin user create --admin --username giteaadmin
|
||||||
|
--password giteaadmin-pass --email admin@example.test
|
||||||
|
--must-change-password=false || true
|
||||||
|
restart: "no"
|
||||||
|
|
||||||
|
gitea-seed:
|
||||||
|
image: alpine:3.20
|
||||||
|
depends_on:
|
||||||
|
gitea-admin-init:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
env_file:
|
||||||
|
- .env.tier1
|
||||||
|
environment:
|
||||||
|
GITEA_ADMIN_USER: giteaadmin
|
||||||
|
GITEA_ADMIN_PASSWORD: giteaadmin-pass
|
||||||
|
GITEA_BOT_PASSWORD: rfc-bot-pass
|
||||||
|
SEED_OUT: /seed/.env.tier1.generated
|
||||||
|
volumes:
|
||||||
|
- ./seed-gitea.sh:/seed-gitea.sh:ro
|
||||||
|
- ./generated:/seed
|
||||||
|
entrypoint: ["/bin/sh", "-c"]
|
||||||
|
command:
|
||||||
|
- apk add --no-cache curl >/dev/null && sh /seed-gitea.sh
|
||||||
|
restart: "no"
|
||||||
|
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: testing/backend.Dockerfile
|
||||||
|
depends_on:
|
||||||
|
gitea-seed:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
env_file:
|
||||||
|
- .env.tier1
|
||||||
|
- ./generated/.env.tier1.generated
|
||||||
|
volumes:
|
||||||
|
- backend-data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/api/health').status==200 else 1)"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 30
|
||||||
|
|
||||||
|
web:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: testing/web.Dockerfile
|
||||||
|
depends_on:
|
||||||
|
backend:
|
||||||
|
condition: service_healthy
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
|
||||||
|
mailpit:
|
||||||
|
image: axllent/mailpit:latest
|
||||||
|
ports:
|
||||||
|
- "8025:8025"
|
||||||
|
- "1025:1025"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
backend-data:
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
.env.tier1.generated
|
||||||
Reference in New Issue
Block a user