Déploiement (pixel.beben0.com)
Pixel Plaza tourne en un seul conteneur (Node sert le client statique + /api + le
WebSocket Colyseus) devant Traefik v3 sur le Swarm du VPS, avec un Postgres
interne. L'image est un bundle esbuild du serveur (le client Vite et les worlds JSON
sont embarqués), lancé par node — aucun outil de build dans l'image finale.
- Image :
~455 MB,node:22-alpine,USER node. - Contrat réseau : le service écoute
:2567(HTTP + upgrade WS sur la même origine). - Healthcheck applicatif :
GET /healthz→200 {"ok":true}.
1. Build & push de l'image
Tag versionné obligatoire (jamais :latest en prod). Utilise le SHA court ou un tag git.
# Depuis la racine du repo (là où est le Dockerfile)
export TAG="v$(node -p "require('./package.json').version")-$(git rev-parse --short HEAD)"
export PLAZA_IMAGE="registry.beben0.com/pixel-plaza:${TAG}"
docker build -t "$PLAZA_IMAGE" .
# Registry privé (user cc, htpasswd)
docker login registry.beben0.com
docker push "$PLAZA_IMAGE"
Build sur Mac (arm64) → pense à cibler l'arch du VPS (amd64) :
docker buildx build --platform linux/amd64 -t "$PLAZA_IMAGE" --push .
2. Déploiement du stack (sur le VPS)
Swarm ne lit pas les fichiers .env : exporte les variables avant docker stack deploy.
export PLAZA_IMAGE="registry.beben0.com/pixel-plaza:v0.0.0-abc1234" # même tag qu'au push
export POSTGRES_PASSWORD="<mot de passe fort>"
export PLAZA_ADMINS="ben" # CSV des usernames admin (optionnel)
export TRAEFIK_NETWORK="traefik-public" # nom réel de l'overlay public Traefik
docker stack deploy -c deploy/stack.yml --with-registry-auth pixel
--with-registry-auth: propage l'auth du registre privé aux nœuds du Swarm.TRAEFIK_NETWORK: mets-y le nom exact de l'overlay attaché à Traefik ; lestack.ymlle référence en réseauexternalet mettraefik-publicpar défaut.- Le routeur Traefik est
Host(pixel.beben0.com)sur l'entrypointwebsecure, TLS viacertresolver=letsencrypt. Adapte le nom de l'entrypoint (websecure) et du certresolver (letsencrypt) à ceux réellement configurés danstraefik.yml.
WebSockets & Traefik
Traefik v3 relaie les upgrades WS nativement (rien à configurer). Attention :
le readTimeout de l'entrypoint Traefik coupe les connexions longues — pour des WS
persistants il doit être à 0s (déjà le cas sur ce VPS, cf. mémoire infra). À vérifier
si des joueurs sont déconnectés périodiquement.
3. Vérifications post-déploiement
docker service ls | grep pixel
docker service logs -f pixel_app # doit afficher "[plaza] listening ..."
# Santé applicative (depuis le VPS, réseau interne du conteneur)
curl -fsS https://pixel.beben0.com/healthz # -> {"ok":true}
curl -fsS -o /dev/null -w '%{http_code}\n' https://pixel.beben0.com/ # -> 200 (SPA)
# WebSocket : ouvre la page, le HUD doit se connecter et afficher l'avatar dans le lobby.
Le healthcheck du service app (dans stack.yml) tape /healthz avec le client HTTP
de Node (busybox wget est banni pour les healthchecks Alpine).
Variables d'environnement
| Variable | Où | Rôle |
|---|---|---|
PLAZA_IMAGE | deploy | Image versionnée à déployer (obligatoire). |
POSTGRES_PASSWORD | deploy | Mot de passe Postgres (obligatoire). |
PLAZA_ADMINS | deploy | CSV des usernames admin (optionnel). |
TRAEFIK_NETWORK | deploy | Nom de l'overlay Traefik public (défaut traefik-public). |
PLAZA_DATABASE_URL | conteneur | Fixé par le stack : postgres://plaza:…@postgres:5432/plaza. |
NODE_ENV | conteneur | production (active le service des statiques client). |
CLIENT_DIST | conteneur | Chemin du build client, défaut /app/client/dist. |
PORT | conteneur | Port d'écoute, défaut 2567. |