Skip to main content

Deployment

V1 — Docker Compose + Traefik

The repository root already ships a docker-compose.yml with:

  • server — PHP-FPM running Laravel.
  • queue — runs php artisan queue:work.
  • scheduler — runs php artisan schedule:work.
  • nginx-server — front door for the Laravel API.
  • ui — production React build served by Nginx.
  • mysql — MySQL 8 data store.
  • phpmyadmin — ops console.
  • traefik (external network web) — TLS termination via Let's Encrypt.

Environment Variables

Top-level .env (already present) feeds Compose:

PROJECT_NAME=attendance
DOMAIN=example.com

HOST_NAME_SERVER=${PROJECT_NAME}-api.${DOMAIN}
HOST_NAME_UI=${PROJECT_NAME}.${DOMAIN}
HOST_NAME_PMA=${PROJECT_NAME}-pma.${DOMAIN}

MYSQL_ROOT_PASSWORD=change-me
MYSQL_DATABASE=${PROJECT_NAME}_db
MYSQL_USER=${PROJECT_NAME}_user
MYSQL_PASSWORD=change-me

Laravel-specific variables live in server/.env (created from .env.example on first setup).

Bring-Up

# 1. Shared external network for Traefik
docker network create web

# 2. Build and start
docker compose up -d --build

# 3. First-time Laravel setup (run once)
docker compose exec server php artisan key:generate
docker compose exec server php artisan migrate --seed
docker compose exec server php artisan horizon:install

Horizon

Horizon is the queue supervisor. In V1 Compose, point the queue service at Horizon:

queue:
build: { context: ., dockerfile: docker/server/Dockerfile }
command: php artisan horizon

Migration Path to Kubernetes

  • Each container is stateless; swap Compose for a Helm chart.
  • MySQL and Redis move to managed services (RDS, ElastiCache).
  • Exports write to S3 instead of a local volume.
  • Horizon runs as a Deployment scaled on queue depth.
  • Use an ingress-nginx or ALB instead of Traefik.