docker-compose.test.yml
Rama main · réplica de lectura del repositorio original.
# ─────────────────────────────────────────────────────────────
# Test gate: run the API test suite against a throwaway Postgres, in a container
# built from the same image as production. Integration tests need a live database,
# so they cannot run during `docker build` (no DB there) — they run here instead.
#
# Build the images, then run the suite (non-zero exit on any failing test). `run`
# starts api-test's dependencies, runs the suite, and exits with its code:
# docker compose -f docker-compose.test.yml build
# docker compose -f docker-compose.test.yml run --rm api-test
#
# The test database is created automatically by the postgres-test service
# (POSTGRES_DB=itsaplan_test); its data is tmpfs, so nothing persists between runs.
# Use as a Coolify pre-deployment step now, or drop the same command into a
# GitHub Actions job later.
# ─────────────────────────────────────────────────────────────
# Its own project: without a name compose derives one from the directory and the test
# containers join the self-hosting stack, which `docker compose down` then takes with it.
name: itsaplan-test
services:
postgres-test:
image: postgres:17-alpine
# Frequent TRUNCATEs retain relation files until a checkpoint; keep the
# disposable database below the small tmpfs limit of CI runners.
command:
[
'postgres',
'-c',
'checkpoint_timeout=30s',
'-c',
'max_wal_size=128MB',
'-c',
'min_wal_size=32MB',
]
environment:
POSTGRES_USER: itsaplan
POSTGRES_PASSWORD: itsaplan
# Name contains "test" — the resetDb() guard requires it.
POSTGRES_DB: itsaplan_test
# Ephemeral: the data directory lives in memory, wiped when the run ends.
tmpfs:
- /var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U itsaplan -d itsaplan_test']
interval: 3s
timeout: 3s
retries: 20
# Throwaway RustFS for the attachments feature test (object bytes). Ephemeral:
# /data is tmpfs, wiped when the run ends.
rustfs-test:
image: rustfs/rustfs:1.0.0
environment:
RUSTFS_ACCESS_KEY: minioadmin
RUSTFS_SECRET_KEY: minioadmin
tmpfs:
- /data:uid=10001,gid=10001
healthcheck:
test: ['CMD', 'curl', '-fsS', '-o', '/dev/null', 'http://127.0.0.1:9000/health']
interval: 3s
timeout: 3s
retries: 20
# One-shot: creates the attachments bucket, then exits.
rustfs-test-init:
image: rustfs/rustfs:1.0.0
depends_on:
rustfs-test:
condition: service_healthy
entrypoint: >
sh -c "
curl -fsS -X PUT --aws-sigv4 aws:amz:us-east-1:s3 --user minioadmin:minioadmin http://rustfs-test:9000/planner-attachments &&
echo 'bucket ready'
"
api-test:
build:
context: .
dockerfile: apps/api/Dockerfile
# Empty install flags so the image keeps devDeps the test suite needs
# (@elysiajs/eden); production builds default to --production. The bot and
# worker suites run out of this image too, so their workspaces are installed
# as well — the production image keeps only api's closure.
args:
INSTALL_FILTER: '--filter api --filter bot --filter worker'
INSTALL_FLAGS: ''
depends_on:
postgres-test:
condition: service_healthy
rustfs-test-init:
condition: service_completed_successfully
environment:
NODE_ENV: test
DATABASE_URL: postgres://itsaplan:itsaplan@postgres-test:5432/itsaplan_test
# Any fixed secret works for a throwaway test DB.
BETTER_AUTH_SECRET: test-secret-not-for-production-use-only
# Fixed 32-byte base64 key for the provider-credential encryption tests.
APP_ENCRYPTION_KEY: dGVzdC1lbmNyeXB0aW9uLWtleS0zMmJ5dGVzLWxlbiE=
API_URL: http://localhost:3000
APP_URL: http://localhost:3001
# Object store for the attachments test (throwaway RustFS above).
S3_ENDPOINT: http://rustfs-test:9000
S3_REGION: us-east-1
S3_BUCKET: planner-attachments
S3_ACCESS_KEY_ID: minioadmin
S3_SECRET_ACCESS_KEY: minioadmin
# Migrate the throwaway DB, then run the api, bot and worker suites. The api's
# test script runs it in parallel workers, as locally; env above satisfies the
# resetDb() guard.
command: sh -c "bun run packages/db/src/migrate.ts && cd apps/api && bun run test && cd ../bot && bun test && cd ../worker && bun test"
# Webhook delivery worker, built from the same image as production, so the test
# gate also verifies the worker image builds and boots. It idles here (no events
# are emitted during the api suite) and is torn down when api-test exits. A tick
# before api-test migrates just logs and retries — it does not fail the gate.
worker-test:
build:
context: .
dockerfile: apps/worker/Dockerfile
depends_on:
postgres-test:
condition: service_healthy
environment:
NODE_ENV: test
DATABASE_URL: postgres://itsaplan:itsaplan@postgres-test:5432/itsaplan_test