feat(docker): replace stale Sail compose with self-contained stack

The previous compose.yaml referenced ./vendor/laravel/sail/runtimes/8.5
which was never wired up (sail isn't installed and the runtime path
doesn't exist), so docker compose up failed out of the box. It also
lacked Reverb, queue workers, and the scheduler.

The new compose.yaml:

  - Builds the dev target of docker/Dockerfile so a single
    `docker compose up --build` brings up the entire stack with no host
    PHP or Node prerequisites.
  - Bind-mounts the project root for hot-reload, with named volumes for
    vendor/ and node_modules/ so image-baked deps survive the bind.
  - Pins Postgres to 16-alpine (matches CI) and Redis to 7-alpine.
  - Healthchecks gate `app` startup until pgsql and redis are ready.
  - Sets DB_HOST=pgsql, DB_USERNAME=postgres, REDIS_HOST=redis as
    process env so .env.testing's pre-existing CI defaults
    (DB_HOST=127.0.0.1, DB_USERNAME=root) don't break tests run from
    inside the container.

compose.override.yaml.example documents per-developer customizations
(UID/GID alignment on Linux, port conflicts, Xdebug, Selenium) without
forcing a specific workflow. .env.testing.local is added to .gitignore
as a safety net for any future per-developer testing override.
This commit is contained in:
André Dantas 2026-05-08 23:00:24 -03:00
parent 4ce5c9173f
commit d15981b8fd
3 changed files with 118 additions and 73 deletions

1
.gitignore vendored
View file

@ -14,6 +14,7 @@
.env
.env.backup
.env.production
.env.testing.local
.phpactor.json
.phpunit.result.cache
Homestead.json

View file

@ -0,0 +1,52 @@
# TryPost — Compose override example.
#
# Compose automatically merges `compose.override.yaml` (gitignored, per-developer)
# on top of `compose.yaml`. Copy this file to start customizing:
#
# cp compose.override.yaml.example compose.override.yaml
#
# Common overrides are commented below. Uncomment what you need.
services:
app:
# Match container UID/GID to your host user (Linux contributors on
# systems where your UID isn't 1000).
# build:
# args:
# UID: 1001
# GID: 1001
# Enable Xdebug (requires installing the extension via a Dockerfile
# tweak; left commented as a hint).
# environment:
# XDEBUG_MODE: debug
# XDEBUG_CONFIG: 'client_host=host.docker.internal'
# Forward additional ports if 8000/5173/8080 conflict with another
# service on your host.
# ports:
# - '9000:80'
pgsql:
# Free up host port 5432 (e.g. when running another Postgres locally).
# ports:
# - '54320:5432'
redis:
# ports:
# - '63790:6379'
mailpit:
# Move the Mailpit UI off port 8025.
# ports:
# - '8025:8025'
# - '1025:1025'
# Add additional services here — e.g. a Selenium container for Dusk tests:
#
# selenium:
# image: selenium/standalone-chromium
# extra_hosts:
# - 'host.docker.internal:host-gateway'
# volumes:
# - '/dev/shm:/dev/shm'

View file

@ -1,91 +1,83 @@
services:
laravel.test:
app:
build:
context: './vendor/laravel/sail/runtimes/8.5'
dockerfile: Dockerfile
context: .
dockerfile: docker/Dockerfile
target: dev
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.5/app'
UID: ${UID:-1000}
GID: ${GID:-1000}
image: trypost-app:dev
ports:
- '${APP_PORT:-8000}:80'
- '${REVERB_PORT:-8080}:8080'
- '${VITE_PORT:-5173}:5173'
environment:
TRYPOST_DOCKER_BOOTSTRAP: '1'
UID: ${UID:-1000}
GID: ${GID:-1000}
# Real env vars take precedence over .env.testing (which pins
# DB_HOST=127.0.0.1, DB_USERNAME=root). Without these, the test
# suite can't see Postgres / Redis from inside the container.
DB_HOST: pgsql
DB_USERNAME: postgres
REDIS_HOST: redis
volumes:
- .:/var/www/html
- app-vendor:/var/www/html/vendor
- app-node-modules:/var/www/html/node_modules
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
IGNITION_LOCAL_SITES_PATH: '${PWD}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- pgsql
- redis
- mailpit
- selenium
pgsql:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ['CMD', 'curl', '-fsS', 'http://127.0.0.1/up']
interval: 30s
timeout: 5s
retries: 5
start_period: 90s
pgsql:
image: 'postgres:18-alpine'
image: postgres:16-alpine
environment:
POSTGRES_DB: ${DB_DATABASE:-trypost}
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
volumes:
- pgdata:/var/lib/postgresql/data
- ./docker/postgres-init.sh:/docker-entrypoint-initdb.d/10-create-test-db.sh:ro
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
PGPASSWORD: '${DB_PASSWORD:-secret}'
POSTGRES_DB: '${DB_DATABASE}'
POSTGRES_USER: '${DB_USERNAME}'
POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
volumes:
- 'sail-pgsql:/var/lib/postgresql'
- './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
networks:
- sail
healthcheck:
test:
- CMD
- pg_isready
- '-q'
- '-d'
- '${DB_DATABASE}'
- '-U'
- '${DB_USERNAME}'
retries: 3
test: ['CMD-SHELL', 'pg_isready -U ${DB_USERNAME:-postgres} -d ${DB_DATABASE:-trypost}']
interval: 10s
timeout: 5s
retries: 5
redis:
image: 'redis:alpine'
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redisdata:/data
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sail-redis:/data'
networks:
- sail
healthcheck:
test:
- CMD
- redis-cli
- ping
retries: 3
timeout: 5s
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 3s
retries: 5
mailpit:
image: 'axllent/mailpit:latest'
image: axllent/mailpit:latest
ports:
- '${FORWARD_MAILPIT_PORT:-1025}:1025'
- '${FORWARD_MAILPIT_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
selenium:
image: selenium/standalone-chromium
extra_hosts:
- 'host.docker.internal:host-gateway'
volumes:
- '/dev/shm:/dev/shm'
networks:
- sail
networks:
sail:
driver: bridge
- '${FORWARD_MAILPIT_SMTP_PORT:-1025}:1025'
- '${FORWARD_MAILPIT_UI_PORT:-8025}:8025'
volumes:
sail-pgsql:
driver: local
sail-redis:
driver: local
pgdata:
redisdata:
app-vendor:
app-node-modules: