Rewired all 4 services: - lib/errors.ts → re-exports from @bytelyst/errors - lib/cosmos.ts → re-exports from @bytelyst/cosmos - lib/product-config.ts → uses loadProductIdentity()/getProductId() from @bytelyst/config - lib/config.ts → kept self-contained (zod v3/v4 type mismatch with loadConfig) Added workspace deps (@bytelyst/errors, @bytelyst/cosmos, @bytelyst/config) to all 4 services. Added docker-compose.yml with Loki, Grafana, Traefik, and all 4 services. Added .env.example with required env vars. Added passWithNoTests to vitest.config.ts. Pinned root zod to ^3.24.0 to match service zod versions. All 12 projects build. 175 tests passing.
170 lines
5.8 KiB
YAML
170 lines
5.8 KiB
YAML
services:
|
|
# ── Loki (Log Aggregation) ────────────────────────────────────
|
|
loki:
|
|
image: grafana/loki:3.3.2
|
|
ports:
|
|
- "3100:3100"
|
|
volumes:
|
|
- ./services/monitoring/loki/loki-config.yml:/etc/loki/local-config.yaml
|
|
- loki-data:/loki
|
|
command: -config.file=/etc/loki/local-config.yaml
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3100/ready"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ── Grafana (Log Viewer + Dashboards) ─────────────────────────
|
|
grafana:
|
|
image: grafana/grafana:11.4.0
|
|
ports:
|
|
- "3000:3000"
|
|
environment:
|
|
- GF_SECURITY_ADMIN_USER=admin
|
|
- GF_SECURITY_ADMIN_PASSWORD=lysnrai
|
|
- GF_USERS_ALLOW_SIGN_UP=false
|
|
volumes:
|
|
- ./services/monitoring/grafana/provisioning:/etc/grafana/provisioning
|
|
- ./services/monitoring/grafana/dashboards:/var/lib/grafana/dashboards
|
|
- grafana-data:/var/lib/grafana
|
|
depends_on:
|
|
loki:
|
|
condition: service_started
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
|
|
interval: 15s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ── API Gateway (Traefik) ───────────────────────────────────
|
|
gateway:
|
|
image: traefik:v3.3
|
|
command:
|
|
- "--api.insecure=true"
|
|
- "--providers.docker=true"
|
|
- "--providers.docker.exposedbydefault=false"
|
|
- "--entrypoints.web.address=:80"
|
|
- "--accesslog=true"
|
|
- "--accesslog.format=json"
|
|
ports:
|
|
- "80:80"
|
|
- "8080:8080" # Traefik dashboard
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
depends_on:
|
|
loki:
|
|
condition: service_started
|
|
logging:
|
|
driver: loki
|
|
options:
|
|
loki-url: "http://host.docker.internal:3100/loki/api/v1/push"
|
|
loki-retries: "3"
|
|
restart: unless-stopped
|
|
|
|
# ── Growth Service (Fastify + TypeScript) ───────────────────
|
|
growth-service:
|
|
build: ./services/growth-service
|
|
ports:
|
|
- "4001:4001"
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
- PORT=4001
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.growth.rule=PathPrefix(`/api/invitations`) || PathPrefix(`/api/referrals`) || PathPrefix(`/api/promos`)"
|
|
- "traefik.http.services.growth.loadbalancer.server.port=4001"
|
|
logging:
|
|
driver: loki
|
|
options:
|
|
loki-url: "http://host.docker.internal:3100/loki/api/v1/push"
|
|
loki-retries: "3"
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4001/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ── Billing Service (Fastify + TypeScript) ──────────────────
|
|
billing-service:
|
|
build: ./services/billing-service
|
|
ports:
|
|
- "4002:4002"
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
- PORT=4002
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.billing.rule=PathPrefix(`/api/subscriptions`) || PathPrefix(`/api/payments`) || PathPrefix(`/api/usage`) || PathPrefix(`/api/plans`) || PathPrefix(`/api/licenses`) || PathPrefix(`/api/stripe`)"
|
|
- "traefik.http.services.billing.loadbalancer.server.port=4002"
|
|
logging:
|
|
driver: loki
|
|
options:
|
|
loki-url: "http://host.docker.internal:3100/loki/api/v1/push"
|
|
loki-retries: "3"
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4002/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ── Platform Service (Fastify + TypeScript) ─────────────────
|
|
platform-service:
|
|
build: ./services/platform-service
|
|
ports:
|
|
- "4003:4003"
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
- PORT=4003
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.platform.rule=PathPrefix(`/api/auth`) || PathPrefix(`/api/audit`) || PathPrefix(`/api/notifications`) || PathPrefix(`/api/flags`) || PathPrefix(`/api/ratelimit`) || PathPrefix(`/api/blob`)"
|
|
- "traefik.http.services.platform.loadbalancer.server.port=4003"
|
|
logging:
|
|
driver: loki
|
|
options:
|
|
loki-url: "http://host.docker.internal:3100/loki/api/v1/push"
|
|
loki-retries: "3"
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4003/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ── Tracker Service (Fastify + TypeScript) ──────────────────
|
|
tracker-service:
|
|
build: ./services/tracker-service
|
|
ports:
|
|
- "4004:4004"
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
- PORT=4004
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.tracker.rule=PathPrefix(`/api/items`) || PathPrefix(`/api/tracker`) || PathPrefix(`/public`)"
|
|
- "traefik.http.services.tracker.loadbalancer.server.port=4004"
|
|
logging:
|
|
driver: loki
|
|
options:
|
|
loki-url: "http://host.docker.internal:3100/loki/api/v1/push"
|
|
loki-retries: "3"
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4004/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
|
|
# ── Volumes ───────────────────────────────────────────────────────
|
|
volumes:
|
|
loki-data:
|
|
grafana-data:
|