← Blogue

Déployer Django sans écrire un Procfile à la main

Railyard

9 octobre 2026

Une application Django connaît déjà presque tout ce qu’un hébergeur a besoin de savoir pour la faire tourner : requirements.txt indique si Celery existe, psycopg indique qu’elle a besoin de Postgres, manage.py indique quoi migrer. La plupart des intégrations PaaS redemandent cette information quand même, sous forme de fichier de config ou de formulaire dans un tableau de bord — un deuxième endroit où elle peut se désynchroniser du vrai code.

Ce qui est détecté, pas configuré

  • Django lui-même est détecté depuis requirements.txt, pyproject.toml, ou un manage.py qui l’importe — aucun indicateur de framework à régler.
  • python manage.py migrate --no-input tourne comme étape de release, avant que la nouvelle version ne reçoive du trafic.
  • python manage.py collectstatic --noinput tourne automatiquement à l’étape de build — la même convention que le buildpack Python de Heroku utilisait, donc WhiteNoise ou n’importe quelle config STATIC_ROOT fonctionne simplement, sans ligne de Dockerfile à ajouter. Une application qui n’utilise pas django.contrib.staticfiles n’est simplement pas affectée.
  • psycopg dans les dépendances provisionne Postgres et injecte DATABASE_URL; un client Redis (redis, django-redis, rq) fait pareil pour REDIS_URL.
  • Celery, Celery Beat, RQ, Huey, Dramatiq et Django-Q sont chacun offerts comme processus de worker automatiquement dès qu’ils sont une dépendance — pas quelque chose à câbler dans un Procfile à partir de zéro.
railyard create my-app https://github.com/me/my-app --addons postgres,redis

ou la même URL collée dans le tableau de bord une fois GitHub connecté.

Les processus, à la manière 12-factor

web, worker et un processus planifié beat sont le même build, chacun démarré avec une commande différente — pas trois applications séparées à garder synchronisées à la main :

web:    gunicorn myproject.wsgi:application --bind 0.0.0.0:$PORT
worker: celery -A myproject worker --loglevel=info
beat:   celery -A myproject beat --loglevel=info

Passez complètement sur le Procfile et la détection offre le worker d’elle-même, selon quelle bibliothèque de tâches est déjà une dépendance. Mettez chacun à l’échelle indépendamment :

railyard scale my-app worker=2

La seule chose qui mérite d’être vérifiée avant le premier déploiement

L’hypothèse par défaut de Gunicorn est un module WSGI à wsgi:application — si l’organisation du projet le place ailleurs, c’est la seule ligne qui mérite d’être réglée explicitement dans la commande de démarrage plutôt que de se fier à la devinette. Tout le reste en aval (migrations, fichiers statiques, workers) suit automatiquement une fois que le processus web démarre réellement.

Config et secrets

DJANGO_SETTINGS_MODULE, SECRET_KEY, et tout indicateur de fonctionnalité vivent sous Variables, ou via railyard env:set my-app KEY=VALUE — des variables d’environnement simples, pas intégrées dans l’image, donc le même build tourne sans changement de staging jusqu’à la production. DATABASE_URL et REDIS_URL se résolvent par environnement automatiquement selon ce qui est attaché sur le canvas.

Référence complète : Documentation Django, Workers et tâches planifiées.

Poussez une application Django maintenant.

requirements.txt est lu automatiquement — gunicorn, migrations et Postgres tous câblés.

Offre gratuite, sans carte, et 14 jours de Pro pour chaque nouvelle équipe. Prix fixe par équipe.