Guide · SaaS & dev

Déployer Flask sur Railway, ordre de la doc

Guide Flask Railway relu le 2026-10-18 : venv, gunicorn, CLI, GitHub, Dockerfile. Le module ne colle pas au fichier. Non rejoué, sans montant.

Le guide Deploy a Flask App, relu le 2026-10-18, enchaîne quatre déploiements : modèle, CLI, dépôt GitHub, Dockerfile. Il commence par créer une petite app si vous n’en avez pas. Les commandes ci-dessous sont celles de la page. Elles n’ont pas été rejouées le 2026-10-18. Aucun compte n’a été ouvert, aucune capture n’est montrée.

Une autre page Railway, Deploy a Vibe-Coded App, écrite le même jour dans l’extrait, ne donne pas la même commande de démarrage Flask. Ce guide suit la page Flask et signale le désaccord, sans fusionner les deux de mémoire.

Créer l’app, si vous partez de zéro

La page dit de sauter cette partie si l’app existe déjà en local ou sur GitHub. Sinon, Python et Flask doivent être installés avant. L’ordre écrit est :

mkdir flaskproject
cd flaskproject
python -m venv env
source env/bin/activate
python -m pip install flask

Sous Windows, la page remplace l’activation par env\Scripts\activate.

Le fichier créé s’appelle helloworld.py. Il importe os et Flask, instancie app, et expose / avec un texte fixe. L’import os n’est pas utilisé dans l’extrait relu. Nous ne l’avons pas retiré : ce n’est pas notre fichier.

Résultat attendu, d’après la page : un dossier flaskproject avec un environnement et ce fichier. Nous n’avons pas créé le dossier.

Lancer le serveur de développement

flask --app helloworld run

La page envoie le navigateur sur http://127.0.0.1:5000.

Résultat attendu : le texte de la route /. Non vérifié ici.

Préparer gunicorn, et le nom qui ne colle pas

La page installe gunicorn, puis écrit :

pip install gunicorn
gunicorn main:app

Elle dit d’ouvrir http://127.0.0.1:8000, puis :

pip freeze > requirements.txt

Elle prévient que pip freeze n’est sûr que dans l’environnement virtuel. Hors venv, la commande fige les paquets de la machine.

Ensuite, la commande de démarrage du service Railway doit être gunicorn main:app. La page renvoie vers Set a Start Command.

Le fichier créé juste avant s’appelle helloworld.py, pas main.py. La commande gunicorn main:app vise un module main. La page relue ne renomme pas le fichier et ne change pas la commande. Si vous laissez helloworld.py, cette commande ne pointe pas vers le module que vous venez d’écrire. Nous ne l’avons pas lancée, donc nous ne publions pas le message d’erreur.

La page vibe-coding, relue le même jour, met Flask dans un tableau d’exemples : gunicorn app:app --bind 0.0.0.0:$PORT. Autre module, et un bind explicite. Elle dit aussi que Railway injecte PORT, et qu’une app liée à 127.0.0.1 n’est pas joignable depuis l’extérieur du conteneur. La page Flask, elle, ne mentionne ni PORT ni 0.0.0.0 dans la commande de démarrage.

Ne collez pas une troisième variante inventée. Ouvrez les deux pages le jour du déploiement et alignez le module gunicorn sur le fichier qui définit app. La page start command dit qu’une commande Railpack tourne dans un shell, donc les variables s’expansent, et qu’une commande sur image Docker en forme exec ne les expanse pas sauf si vous l’enveloppez dans un shell. Ça n’indique pas laquelle des deux commandes Flask est la bonne.

Quatre façons de déployer, dans l’ordre de la page

La page liste d’abord le modèle, la CLI, GitHub, puis le Dockerfile. Le sommaire du milieu omet le Dockerfile, puis une section le reprend. Suivez les quatre sections, pas le sommaire tronqué.

Modèle en un clic

La page propose un bouton vers un modèle Flask, et conseille d’éjecter le modèle ensuite pour copier le dépôt sur votre compte GitHub. Elle pointe aussi vers d’autres modèles communautaires.

Ce n’est pas un bouton de ce site. Ouvrez la page Flask et utilisez le sien si vous choisissez cette voie. Nous n’avons pas déployé le modèle.

CLI

  1. Installer la CLI et l’authentifier, via les ancres que la page Flask cite.
  2. Dans le dossier de l’app : railway init, puis nommer le projet.
  3. railway up. La page dit que la commande scanne, compresse et envoie les fichiers, avec les logs dans le terminal.
  4. Ouvrir les logs du déploiement. L’ancre citée est le panneau build / deploy de Logs.
  5. Settings, section Networking, Generate Domain.

railway up n’est pas l’étape qui publie l’URL. Sur la page Flask, le domaine est l’étape suivante, dans Networking. Suivez cet ordre.

Dépôt GitHub

  1. Créer un projet sur railway.com/new.
  2. Deploy from GitHub repo, puis choisir le dépôt. La page dit que le lien GitHub est demandé s’il manque.
  3. Deploy sur le canevas.
  4. La détection Python passe par Railpack. Puis les logs.
  5. Même Networking, Generate Domain.

Le service n’est pas public tant que le domaine n’est pas généré. Même phrase que pour la CLI.

Dockerfile

La page place un Dockerfile à la racine. L’image de base écrite est python:3, avec PYTHONUNBUFFERED=1, WORKDIR /app, une copie du contexte, pip install --no-cache-dir -r requirements.txt, et CMD ["gunicorn", "main:app"]. Railway détecte le fichier et s’en sert pour le build. Le déploiement se fait ensuite par CLI ou GitHub.

Le CMD reprend main:app. Même décalage que plus haut si votre module n’est pas main.

La page dit aussi que Railway peut déployer une image publique ou privée. Ce n’est pas le chemin du Dockerfile local. Ne mélangez pas les deux.

Essai et plan gratuit, sans les montants

Free Trial et Pricing Plans, relus le 2026-10-18, décrivent un essai, puis un plan Free, puis Hobby, Pro et Enterprise. Les deux pages affichent des crédits et des prix. Cet article ne les recopie pas : ils bougent, et une capture de tarif n’est pas une source durable.

Ce qui reste utile sans chiffre :

  • L’essai peut être complet ou limité. La page lie la vérification à un compte GitHub, âge et activité compris. Railway dit ne pas traiter les demandes manuelles de vérification.
  • L’essai limité peut déployer du code, des bases et des buckets, avec un réseau sortant restreint et un jeu de ports limité. L’essai complet a l’accès réseau entier.
  • Quand la fenêtre d’essai se termine, ou quand le crédit d’essai est épuisé, le compte revient au plan Free. Le crédit Free ne se reporte pas d’un mois sur l’autre, d’après la page essai.
  • La page des plans répond non à « le plan Hobby est-il gratuit ? ». Le montant est sur la page, pas ici.
  • Les volumes créés sur un compte Trial sont supprimés 30 jours après l’expiration des crédits, si vous ne passez pas à un plan payant. La page le dit. Nous n’avons pas de volume à montrer.

Le build est décrit comme non facturé sur la page des plans (CPU de build, mémoire de build, téléchargement d’image de base, export et stockage d’image). L’usage CPU, RAM, egress et volumes, lui, est facturé. Les tarifs unitaires sont sur la page. Ne les recopiez pas dans un devis.

Ce que ce guide ne refait pas

Repères des plateformes d’API Python parle du guide FastAPI Railway, pas de Flask. Claude Code pour Flask parle d’écriture de tests et d’erreurs, pas d’un déploiement Railway. Héberger n8n sur un VPS sépare installation et exposition publique pour n8n. Ce n’est pas une app Flask, et ce n’est pas Railway.

Ajouter Postgres n’est pas dans le guide Flask. La page renvoie vers un guide de base. Pour Next.js et Postgres sur Railway, voir Next.js et PostgreSQL sur Railway. Les logs du déploiement sont ceux du panneau cité plus haut. Le guide Logs d’une application SaaS reprend la page Logs, sans refaire ce déploiement.

Sources

Sources recontrôlées le 2026-10-19. Commandes non rejouées. Si la page Flask aligne un jour le nom du fichier et le module gunicorn, c’est sa version qui compte.