Portail permettant de brancher et router des containers OCI/Docker via des handlers pour être lancés en SSH - Exemple : ssh -p 2222 cemantix@ssh.lclr.dev pour jouer à Cémantix dans son terminal
  • Go 99.5%
  • Dockerfile 0.5%
Find a file
2026-08-18 16:03:52 +02:00
cmd/ssh-portal feat: pull pending images in runner 2026-08-12 11:04:47 +02:00
docs/superpowers fix: show SSH key help once 2026-08-12 11:40:06 +02:00
internal fix: show SSH key help once 2026-08-12 11:40:06 +02:00
tests test: cover pulled image ssh launch 2026-08-12 11:10:16 +02:00
.dockerignore feat: add coolify ssh portal deployment 2026-08-12 09:09:29 +02:00
.env.example feat: add coolify ssh portal deployment 2026-08-12 09:09:29 +02:00
compose.yaml feat: add healthchecks for Coolify service monitoring 2026-08-18 16:03:52 +02:00
Dockerfile feat: add coolify ssh portal deployment 2026-08-12 09:09:29 +02:00
go.mod feat: add coolify ssh portal deployment 2026-08-12 09:09:29 +02:00
go.sum feat: add coolify ssh portal deployment 2026-08-12 09:09:29 +02:00
README.md test: cover pulled image ssh launch 2026-08-12 11:10:16 +02:00

SSH Portal

Portail SSH pour publier des applications terminal hébergées dans des images OCI. Le joueur ninstalle ni Docker, ni Python, ni le dépôt du jeu.

ssh -p 2222 cemantix@ssh.lclr.dev

Une clé SSH est obligatoire, mais elle na pas besoin dêtre inscrite au préalable. Son empreinte identifie la session persistante du joueur.

Fonctionnement

  • gateway accepte seulement les sessions SSH interactives avec clé publique ;
  • admin propose une interface HTTP protégée par Basic Auth ;
  • runner est le seul service avec accès Docker. Il télécharge les images demandées par ladmin, puis résout le handle demandé vers le digest OCI et lance le jeu dans un conteneur limité.

Un mapping contient un handle, tel que cemantix, et une image complète épinglée par digest :

forge.lclr.dev/thibaud-lclr/cemantix-tui@sha256:<digest>

Les tags tels que latest sont refusés : ils ne permettent pas de savoir quelle version est exécutée.

Téléchargement des images

La création dun mapping lance un téléchargement asynchrone sur le serveur :

  • pastille orange : téléchargement en cours, le handle nest pas lançable ;
  • pastille verte : image téléchargée et handle activé ;
  • pastille grise : image téléchargée mais handle désactivé ;
  • pastille rouge : téléchargement en erreur ; le log Docker complet est consultable depuis linterface.

Un mapping en erreur doit être supprimé puis recréé avec le digest à utiliser.

Déploiement Coolify

  1. Créer un nouveau service Docker Compose depuis ce dépôt, avec compose.yaml.
  2. Déclarer au moins RUNNER_TOKEN, ADMIN_USERNAME et ADMIN_PASSWORD à partir de .env.example. Utiliser deux secrets longs et distincts.
  3. Configurer un domaine HTTPS Coolify uniquement sur le service admin, port 8080, par exemple admin.ssh.lclr.dev.
  4. Ouvrir le port TCP 2222 vers Internet pour le service gateway.
  5. Déployer, ouvrir ladmin avec les identifiants configurés et créer le mapping cemantix avec limage issue de sa CI.

Coolify héberge le portail et les conteneurs de jeu tournent sur ce serveur. Le joueur utilise seulement son client SSH local.

Stockage et limites

Les propositions dun jeu sont conservées dans un volume Docker nommé, associé à lempreinte de la clé et au handle. Changer de clé crée une session distincte.

Chaque lancement reçoit un système de fichiers en lecture seule, un volume de données dédié, 0,5 CPU, 256 Mio de mémoire, au plus 128 processus et une durée maximale configurable par MAX_SESSION_DURATION (4 heures par défaut). Les images de jeu ne reçoivent jamais le socket Docker ni les secrets du portail.

Développement

go test ./...
docker compose --env-file .env.example config
docker build -t ssh-portal:local .
go test -tags=integration ./tests -run TestPublicKeySSHStartsMappedTerminalImage -v

Le dernier test nécessite un daemon Docker accessible et télécharge limage publique hello-world pour vérifier le chemin SSH complet.