Vous êtes ici:Exécution dist/
Ce qui tourne en production
PourquoiSavoir ce que fait le binaire, et ce qu’il laisse à d’autres, décide du reste de l’installation.
cybertrain build compile le framework, vos contrôleurs et modèles et l’interpréteur de gabarits dans dist/blog, avec toutes les vues intégrées, et copie public/ à côté. Rien d’autre n’est installé là où il tourne : ni Ruby, ni gems.
browser ──HTTPS──▶ reverse proxy (kamal-proxy or Caddy)
└─ HTTP/1.1 ──▶ dist/blog (port 3000)
├─ public/ static files, 404.html, 500.html
└─ storage/production.sqlite3
- Il est lié à la SQLite et à la libc du système : construisez-le donc sur le même OS et le même CPU que la machine qui l’exécute. Le construire dans une image Docker, comme le fait la configuration Kamal, règle la question.
- Il ne parle que le HTTP/1.1 simple. TLS et HTTP/2 sont l’affaire du proxy inverse. En production, le cookie de session est
Secure: le site doit être servi en HTTPS, sinon les formulaires échouent avecInvalid authenticity token. - La base de données est un seul fichier SQLite. Faites tourner un seul processus sur un seul serveur, et gardez le fichier sur un stockage qui survit à un déploiement.
- Il est en production par défaut et refuse de démarrer sans
CYBERTRAIN_SECRET_KEY_BASE../blog migrateapplique les migrations compilées dedans.
Deux façons de déployer
PourquoiLes deux mettent du HTTPS devant le même binaire ; elles diffèrent par l’endroit où il est construit et la façon dont un déploiement le remplace.
| Kamal | systemd et Caddy | |
|---|---|---|
| Construction | Dans une image Docker, sur votre machine ou un builder distant | Sur le serveur, depuis un clone git |
| En façade | kamal-proxy, avec un certificat Let’s Encrypt | Caddy, avec un certificat Let’s Encrypt |
| Fichiers statiques | L’application sert public/ | Caddy sert lui-même dist/public/ |
| Un déploiement | Le nouveau conteneur reçoit le trafic une fois son contrôle de santé réussi : aucune connexion n’est refusée | Un redémarrage : quelques secondes de 500.html servi par Caddy |
| Revenir en arrière | kamal rollback VERSION | Pointer current vers une version antérieure et redémarrer |
| Le serveur a besoin de | SSH et Docker (installé par kamal setup), plus un registre d’images | Ruby, une chaîne de compilation C, les en-têtes SQLite, la CLI cybertrain et Spinel |
Dans les deux cas, l’application est un processus et son fichier SQLite sur un seul serveur.
Déployer avec Kamal
Pourquoicybertrain new a déjà écrit les fichiers ; il vous reste à indiquer un serveur, un domaine et un registre.
Dockerfileune étape de build Ubuntu exécutecybertrain setupetcybertrain build; une étape allégée de la même version ne reçoit quedist/et les bibliothèques auxquelles il est liéconfig/deploy.ymlle serveur, le domaine, kamal-proxy avec TLS vers le port 3000, le contrôle de santé et le volume de la base.kamal/secretslitKAMAL_REGISTRY_PASSWORDetCYBERTRAIN_SECRET_KEY_BASEdans votre environnement, jamais les valeurs elles-mêmespublic/up.htmlla page que kamal-proxy interroge avant d’envoyer du trafic à un nouveau conteneur
Renseignez les valeurs marquées CHANGE ME dans config/deploy.yml, committez, puis :
export KAMAL_REGISTRY_PASSWORD=...
export CYBERTRAIN_SECRET_KEY_BASE="$(openssl rand -hex 32)" # une seule fois ; conservez-la
kamal setup # la première fois : Docker et kamal-proxy sur le serveur, build, push, démarrage
kamal deploy # chaque déploiement suivant
- Chaque déploiement construit l’image (Spinel reste dans le cache de couches de Docker après la première fois), la pousse et démarre un conteneur qui exécute
./blog migratepuisexec ./blogsur0.0.0.0:3000. - kamal-proxy attend que
/up.htmlréponde 200, bascule le trafic vers le nouveau conteneur, puis arrête l’ancien, qui termine ses requêtes en cours surSIGTERM. - La base de données se trouve sur le volume
blog_storage, monté en/app/storage: elle survit à chaque déploiement. - Réglez
builder.archsur le CPU du serveur. Spinel se compile dans l’image, donc construire pour une autre architecture sous émulation est lent ; construisez plutôt sur le serveur avecbuilder.remote.
Le guide pas à pas, sauvegardes du volume comprises, est docs/deploy-kamal.md. examples/blog embarque la même configuration, et la CI construit et teste son image.
Derrière Caddy, sous systemd
PourquoiSans Docker : le serveur construit l’application depuis git, systemd la maintient en marche, Caddy fait face à Internet.
- L’application n’écoute que sur
127.0.0.1:3000: rien ne l’atteint sans passer par Caddy.public/etstorage/se résolvent depuis le répertoire de travail, donc systemd la démarre avecdist/comme répertoire de travail et lit son secret dans un fichier d’environnement hors du dépôt. - Un script de déploiement clone chaque version dans son propre répertoire, vérifie que
gen/est à jour, exécutecybertrain buildetdist/blog migrate, puis fait pointer le liencurrentdessus, redémarre le service et attend queup.htmlréponde ; sinon, le script revient à la version précédente. Une erreur avant la bascule laisse la version en service intacte. Revenir en arrière n’annule pas les migrations : elles doivent rester compatibles avec la version précédente ; un premier déploiement raté n’a rien vers quoi revenir et se termine simplement en erreur. - Caddy obtient le certificat, redirige HTTP vers HTTPS, sert lui-même les fichiers de
dist/public/et relaie tout le reste vers l’application. Pendant que l’application redémarre, il répond avec500.html.
blog.example.com {
encode zstd gzip
root * /srv/blog/current/dist/public
@static file
handle @static {
file_server
}
handle {
reverse_proxy 127.0.0.1:3000
}
handle_errors {
rewrite * /500.html
file_server
}
}
L’application ajoute X-Content-Type-Options et X-Frame-Options à ce qu’elle sert ; les fichiers que Caddy sert depuis dist/public/ ne passent pas par elle, ajoutez-les donc dans le bloc du site si vous les voulez là aussi. nginx fonctionne de la même façon : terminer TLS, servir dist/public/, relayer le reste.
La procédure complète, d’un serveur Ubuntu neuf aux sauvegardes et retours en arrière, est docs/deploy.en.md (l’original japonais est docs/deploy.md).
Configurer
PourquoiLes réglages de production viennent de l’environnement : le même binaire tourne partout.
| Variable | En production |
|---|---|
CYBERTRAIN_SECRET_KEY_BASE | Obligatoire. Signe le cookie de session ; la changer déconnecte tout le monde. Générez-la une fois avec openssl rand -hex 32 |
CYBERTRAIN_DATABASE | Le fichier SQLite ; par défaut storage/production.sqlite3 sous le répertoire de travail. Gardez-le hors de la version déployée |
CYBERTRAIN_HOST | 127.0.0.1 par défaut, ce qui convient derrière un proxy sur la même machine ; 0.0.0.0 dans un conteneur |
PORT | 3000 par défaut ; là où le proxy transmet |
CYBERTRAIN_ENV | Déjà production dans un binaire construit ; development lancerait la surveillance des fichiers et les reconstructions |
L’étape Compiler pour le déploiement du tutoriel liste toutes les variables et l’attribut config/app.rb correspondant.
L’exploitation au quotidien
- Chaque modification est un déploiement. Les vues sont intégrées à la compilation, donc même une modification de vue seule demande une reconstruction et un redémarrage. Committez
gen/avec la modification : le script de déploiement s’arrête sur ungen/périmé. - Les migrations passent avant que le nouveau code ne serve : dans le script de déploiement, ou au démarrage du conteneur. Supprimez une colonne lors d’un déploiement ultérieur, quand plus aucun code en service ne la lit.
- Sauvegardez avec
.backupde SQLite, pas en copiant le fichier : la copie est cohérente même pendant que l’application écrit. - Revenir en arrière par-delà une migration implique de ramener aussi la base, avec
db rollbackdepuis la version la plus récente, avant de basculer. - L’arrêt est en douceur : sur
SIGTERM, le serveur cesse d’accepter, termine les requêtes en cours et quitte, au bout de 10 secondes au plus.