253 lines
4.4 KiB
Markdown
253 lines
4.4 KiB
Markdown
# Mintel Alpha Platform — Developer Cheat Sheet
|
||
|
||
This platform runs real customer websites on their own domains
|
||
(e.g. klz-cables.com, shop.customer.de, example.org).
|
||
|
||
You do not manage servers.
|
||
You ship Docker containers.
|
||
Mintel runs the platform.
|
||
|
||
---
|
||
|
||
## Control Plane (Infra)
|
||
|
||
These are for developers only (not customers):
|
||
|
||
Git (Gitea)
|
||
https://git.infra.mintel.me
|
||
|
||
CI (Woodpecker)
|
||
https://ci.infra.mintel.me
|
||
|
||
Container Registry
|
||
https://registry.infra.mintel.me
|
||
|
||
Errors (GlitchTip)
|
||
https://errors.infra.mintel.me
|
||
|
||
Analytics (Umami)
|
||
https://analytics.infra.mintel.me
|
||
|
||
Uptime
|
||
https://status.infra.mintel.me
|
||
|
||
Logs
|
||
https://logs.infra.mintel.me
|
||
|
||
---
|
||
|
||
## Production Platform (Alpha)
|
||
|
||
Alpha runs all customer websites and listens on ports 80 and 443 for the entire internet.
|
||
|
||
Customer domains point their DNS A records to the Alpha server IP.
|
||
|
||
Traefik on Alpha routes domains to the correct containers.
|
||
|
||
---
|
||
|
||
## How routing works
|
||
|
||
Each web service declares which domains it owns via Traefik labels.
|
||
|
||
Example domains:
|
||
- klz-cables.com
|
||
- www.klz-cables.com
|
||
|
||
Traefik routes traffic by Host header.
|
||
|
||
---
|
||
|
||
## Directory layout on Alpha
|
||
|
||
Each app lives in:
|
||
|
||
/opt/alpha/sites/APP_NAME
|
||
|
||
This directory contains:
|
||
- docker-compose.yml
|
||
- .env (optional)
|
||
- persistent volumes
|
||
|
||
---
|
||
|
||
## Container Images
|
||
|
||
All production images must be built by CI and pushed to the Mintel Registry.
|
||
|
||
Registry:
|
||
registry.infra.mintel.me
|
||
|
||
Image naming:
|
||
registry.infra.mintel.me/ORG/APP_NAME:TAG
|
||
|
||
Example:
|
||
registry.infra.mintel.me/mintel/mb-grid-solutions:latest
|
||
|
||
---
|
||
|
||
## Databases
|
||
|
||
### Postgres (shared)
|
||
|
||
All apps share one Postgres server but use separate databases.
|
||
|
||
Connection format:
|
||
|
||
postgres://infra:infra@postgres:5432/APP_DB
|
||
|
||
Example:
|
||
|
||
postgres://infra:infra@postgres:5432/klz_site
|
||
|
||
Each app must use its own database.
|
||
|
||
---
|
||
|
||
### Redis (shared)
|
||
|
||
All apps share one Redis server but use separate DB indexes.
|
||
|
||
Connection format:
|
||
|
||
redis://redis:6379/N
|
||
|
||
Example:
|
||
|
||
redis://redis:6379/1
|
||
redis://redis:6379/2
|
||
|
||
Each app must use its own Redis DB number.
|
||
|
||
---
|
||
|
||
## Traefik labels (required)
|
||
|
||
Every public web service must define these labels:
|
||
|
||
traefik.enable=true
|
||
traefik.http.routers.app.rule=Host(klz-cables.com,www.klz-cables.com)
|
||
traefik.http.routers.app.entrypoints=websecure
|
||
traefik.http.routers.app.tls.certresolver=le
|
||
traefik.http.services.app.loadbalancer.server.port=YOUR_INTERNAL_PORT
|
||
|
||
Traefik automatically provides HTTPS.
|
||
|
||
---
|
||
|
||
## Zero-downtime deployments
|
||
|
||
All web services must support health checks.
|
||
|
||
Your app must expose:
|
||
|
||
GET /health
|
||
returns HTTP 200 when ready.
|
||
|
||
Docker Compose example:
|
||
|
||
healthcheck:
|
||
test: wget -q -O - http://localhost:3000/health
|
||
interval: 5s
|
||
timeout: 2s
|
||
retries: 10
|
||
|
||
Run multiple replicas:
|
||
|
||
deploy:
|
||
replicas: 2
|
||
|
||
During deploy:
|
||
- New containers start
|
||
- They become healthy
|
||
- Traefik switches traffic
|
||
- Old containers are removed
|
||
|
||
No downtime.
|
||
|
||
---
|
||
|
||
## Error tracking (GlitchTip)
|
||
|
||
Each project gets a DSN (like Sentry).
|
||
|
||
Example:
|
||
|
||
https://PUBLIC_KEY@errors.infra.mintel.me/PROJECT_ID
|
||
|
||
Use as SENTRY_DSN in your app.
|
||
|
||
---
|
||
|
||
## Analytics (Umami)
|
||
|
||
Each site gets a website ID.
|
||
|
||
Include this script:
|
||
|
||
https://analytics.infra.mintel.me/script.js
|
||
data-website-id=YOUR_ID
|
||
|
||
---
|
||
|
||
## Deployment via Woodpecker
|
||
|
||
Woodpecker builds images and pushes them to the Mintel Registry, then deploys to Alpha via SSH.
|
||
|
||
Target:
|
||
deploy@alpha.mintel.me
|
||
|
||
---
|
||
|
||
## Woodpecker pipeline example
|
||
steps:
|
||
build:
|
||
image: woodpeckerci/plugin-docker
|
||
settings:
|
||
registry: registry.infra.mintel.me
|
||
repo: registry.infra.mintel.me/mintel/mb-grid-solutions
|
||
username:
|
||
from_secret: REGISTRY_USER
|
||
password:
|
||
from_secret: REGISTRY_PASS
|
||
tags:
|
||
- latest
|
||
- ${CI_COMMIT_SHA}
|
||
|
||
deploy:
|
||
image: alpine
|
||
environment:
|
||
ALPHA_SSH_KEY:
|
||
from_secret: ALPHA_SSH_KEY
|
||
commands:
|
||
- apk add –no-cache openssh
|
||
- mkdir -p ~/.ssh
|
||
- echo “$ALPHA_SSH_KEY” > ~/.ssh/id_ed25519
|
||
- chmod 600 ~/.ssh/id_ed25519
|
||
- ssh -o StrictHostKeyChecking=no deploy@alpha.mintel.me “cd /opt/alpha/sites/mb-grid-solutions && docker compose pull && docker compose up -d”
|
||
|
||
---
|
||
|
||
## Monitoring
|
||
|
||
Errors → GlitchTip
|
||
Traffic → Umami
|
||
Uptime → Uptime-Kuma
|
||
Logs → Dozzle
|
||
|
||
Infra monitors all services.
|
||
|
||
---
|
||
|
||
## Summary
|
||
|
||
You push code.
|
||
CI builds images.
|
||
Images go to the Mintel Registry.
|
||
Alpha pulls and runs them.
|
||
Traefik routes real domains.
|
||
Postgres and Redis are shared but isolated.
|
||
Deploys are zero-downtime.
|
||
Everything is monitored.
|
||
|
||
This is a real production platform. |