Quitter Heroku Postgres sans perdre de données
Suivez ça sur votre propre serveur. Commencer gratuitement, sans carte
Heroku a retiré son offre Postgres gratuite il y a un moment, et le forfait payant le moins cher qui reste, Essential-0, vous plafonne quand même à 1 Go de stockage, 20 connexions et une limite de 4 000 tables pour 5 $ par mois. C’est correct pour une application jouet. Ce n’est pas correct pour quoi que ce soit qui a vraiment grandi, et ce n’est pas correct pour le prix, une fois qu’on le compare à faire tourner la même base de données ailleurs. Ce qui freine la plupart des gens, ce n’est pas la décision, c’est la peur d’abîmer les données en chemin : perdre des lignes, restaurer avec le mauvais encodage, ou basculer avant que la nouvelle base de données soit vraiment prête. À la fin de ce guide, vous aurez une copie complète et vérifiée de vos données Heroku Postgres qui tourne sur une nouvelle base, votre application pointée vers celle-ci, et l’ancienne encore en place comme filet de sécurité le temps d’en être certain.
Ce qu’il vous faut
- Le CLI Heroku installé et connecté (
heroku login), avec accès à l’application dont vous migrez la base de données. - Un serveur Postgres de destination. Ce guide utilise un Basic Droplet DigitalOcean à 6 $/mois (1 vCPU, 1 Gio de RAM, 25 Go SSD) qui fait tourner Postgres dans Docker, ce qui convient largement à une base de données qui vivait dans un forfait Heroku Essential-0 de 1 Go. Utilisez une machine plus grosse si vos données sont plus volumineuses.
pg_dumpetpg_restoresur votre machine, correspondant (ou plus récents que) la version Postgres de votre base de données Heroku. Postgres.app ou le paquetpostgresql-clientde votre système d’exploitation vous donne les deux.- Une fenêtre de maintenance n’est pas strictement nécessaire, mais il est utile de choisir un moment calme, puisque vous allez repointer
DATABASE_URLà mi-parcours. - Environ 10 à 15 minutes, plus si votre base de données est volumineuse ou votre connexion lente.
Étape 1 : Capturer une sauvegarde fraîche sur Heroku
Ne restaurez pas à partir de la sauvegarde automatique qu’Heroku a peut-être déjà sous la main. Prenez-en une maintenant, pour savoir exactement à quel instant vous migrez.
heroku pg:backups:capture --app your-app-name
Cette commande déclenche une nouvelle sauvegarde du côté d’Heroku, dans le format de dump compressé personnalisé de Postgres. Ça peut prendre de quelques secondes à plusieurs minutes selon la taille de votre base de données. Vérifiez l’avancement avec :
heroku pg:backups --app your-app-name
Vous devriez voir une ligne pour la sauvegarde que vous venez de capturer, avec un statut Completed et une taille correspondant à peu près à ce que vous attendez pour votre base de données. Si ça indique encore Pending ou Running, attendez et revérifiez avant de continuer : une sauvegarde encore en cours de capture échouera au téléchargement.
Étape 2 : Télécharger la sauvegarde
Une fois la capture terminée, récupérez-la sur votre machine :
heroku pg:backups:download --app your-app-name
Ça enregistre un fichier nommé latest.dump (ou l’identifiant de la sauvegarde précise si vous en avez passé un) dans votre répertoire courant. Si vous préférez remettre le fichier à autre chose plutôt que de le télécharger vous-même, heroku pg:backups:url --app your-app-name vous donne une URL publique temporaire vers le même dump, valide environ une heure.
Vous devriez voir un fichier latest.dump sur le disque, avec une taille dans les mêmes eaux que celle rapportée par heroku pg:backups.
Étape 3 : Mettre en place la base de données Postgres de destination
Si vous déménagez vers une instance Postgres auto-hébergée plutôt que vers un autre fournisseur géré, un petit fichier Docker Compose vous donne rapidement une base de données en marche :
services:
postgres:
image: postgres:16.4-alpine
restart: unless-stopped
environment:
POSTGRES_USER: appuser
POSTGRES_PASSWORD: change-me
POSTGRES_DB: appdb
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
pgdata:
Démarrez-le avec :
docker compose up -d
Vous devriez voir le conteneur en marche (docker compose ps) et pouvoir vous connecter avec psql -h your-server-ip -U appuser -d appdb. Si vous pointez plutôt vers un Postgres géré d’un autre fournisseur, assurez-vous simplement d’avoir sa chaîne de connexion et qu’il accepte les connexions depuis votre IP avant de continuer.
Étape 4 : Restaurer le dump dans la nouvelle base de données
pg_restore lit le même format personnalisé dans lequel la sauvegarde Heroku se trouve déjà, donc il n’y a pas d’étape de conversion :
pg_restore --verbose --clean --no-acl --no-owner \
-h your-server-ip -U appuser -d appdb latest.dump
--clean supprime tout objet en conflit avant de le recréer, ce qui compte si vous avez déjà fait tourner des migrations sur une base de données vide et qu’elle a des tables qui entreraient autrement en collision avec la restauration. --no-acl et --no-owner sautent les références de rôles et permissions propres à Heroku qui n’existent pas sur votre nouveau serveur et qui déclencheraient sinon des erreurs que vous pouvez ignorer sans problème.
Vous devriez voir défiler un long flux de lignes CREATE TABLE, CREATE INDEX et COPY sans erreur fatale à la fin. Quelques avertissements already exists ou does not exist, skipping sont normaux et ne sont pas le signe que quelque chose a mal tourné.
Étape 5 : Vérifier que les données correspondent vraiment
Avant de toucher à DATABASE_URL, vérifiez que ce qui a été transféré est complet. Comparez le nombre de lignes table par table entre Heroku et la nouvelle base de données :
SELECT schemaname, relname, n_live_tup
FROM pg_stat_user_tables
ORDER BY relname;
Lancez ceci sur les deux bases de données (connectez-vous à Heroku avec heroku pg:psql --app your-app-name) et comparez les résultats. Pour tout ce que votre application traite comme important sur le plan financier ou légal, vérifiez ponctuellement quelques lignes précises par clé primaire plutôt que de vous fier uniquement aux comptes.
Vous devriez voir des nombres de lignes qui correspondent pour chaque table, sans aucune table présente d’un côté et absente de l’autre.
Étape 6 : Pointer votre application vers la nouvelle base de données
Une fois que vous êtes certain que les données correspondent, mettez à jour partout où se trouve votre DATABASE_URL, votre fichier .env, les variables de config de votre nouvel hébergeur, votre gestionnaire de secrets, vers la nouvelle chaîne de connexion, puis redéployez. Si votre destination exige sslmode=require ou un paramètre similaire, réglez-le maintenant dans la chaîne de connexion plutôt que de le découvrir en production.
Vous devriez voir le prochain déploiement de votre application réussir et lire/écrire sur la nouvelle base de données. Surveillez vos journaux d’erreurs pendant quelques minutes après le déploiement pour tout ce qui concerne la connexion.
Étape 7 : Garder Heroku en place un moment, puis le retirer
Ne supprimez pas l’application Heroku et ne réduisez pas sa base de données dès que le basculement semble correct. Laissez-la tourner, intacte, pendant un jour ou deux comme filet de sécurité vers lequel revenir si quelque chose apparaît que votre vérification de nombre de lignes aurait manqué. Une fois que vous êtes certain, réduisez le dyno et la base de données Heroku, puis retirez-les.
Le raccourci : le faire avec Railyard
Tout ce qui précède est le chemin manuel, utile à connaître parce que c’est ce qui se passe réellement sous le capot de n’importe quel outil qui prétend faire ça pour vous. Railyard offre deux façons de sauter la plupart de ces étapes.
Si vous déplacez l’application au complet, pas seulement la base de données, Applications → Import lit directement votre application depuis Heroku à l’aide d’un jeton API : les variables de config, la formation (vos types de processus et leurs comptes), et tout add-on Postgres, Redis, MySQL ou Memcached sont transférés automatiquement, avec les domaines personnalisés. Vous ajoutez vous-même l’URL Git, puisque l’API d’Heroku ne partage pas votre dépôt. L’import Heroku est actuellement en version bêta, c’est-à-dire qu’il n’a pas encore été testé sur assez de comptes réels pour le dire pleinement éprouvé, donc Railyard vous montre le plan pour votre application précise avant quoi que ce soit, et vous le vérifiez avant de confirmer. La base de données elle-même est transférée en diffusant un dump directement depuis votre DATABASE_URL Heroku vers la nouvelle base de données gérée, et l’ancienne application Heroku continue de servir le trafic jusqu’à ce que la nouvelle URL réponde et que vous ayez vous-même déplacé le DNS.
Si vous voulez seulement déplacer la base de données et que vous gardez votre application et votre pipeline de déploiement où ils sont, le flux autonome Import data fait à lui seul cette moitié-là du travail : collez votre URL de connexion Heroku Postgres (la même que heroku config:get DATABASE_URL vous donne), et Railyard tire les données directement de celle-ci. La plateforme sauvegarde d’abord ce qui se trouve actuellement dans la base de données de destination, donc si l’import échoue ou que vous l’annulez en cours de route, vos données existantes sont restaurées automatiquement plutôt que laissées à moitié écrasées. Si vous choisissez de déployer après la fin de l’import, elle fait tourner les migrations de votre application comme dernière étape.
Dans les deux cas, la sortie de heroku config -s se colle directement dans Variables → Bulk import de Railyard, donc vos variables d’environnement n’ont pas besoin d’être retapées à la main.
Les détails complets des deux flux : Importer depuis une autre plateforme et Bases de données et sauvegardes. Si vous hésitez encore à migrer du tout, le parcours complet se trouve sur Migrer depuis Heroku, et notre vérificateur de facture Heroku vous dira à peu près ce que vous payez aujourd’hui par rapport à ailleurs.
Dépannage
heroku: command not found ou erreurs d’authentification. Assurez-vous que le CLI est installé et relancez heroku login; une session périmée ou expirée se manifeste par une erreur de permission sur des commandes qui semblent par ailleurs correctes.
Le téléchargement de la sauvegarde échoue ou retourne un fichier vide. Ça signifie presque toujours que la capture de l’étape 1 n’était pas vraiment terminée. Revérifiez heroku pg:backups --app your-app-name et attendez Completed avant de télécharger ou de demander une URL.
pg_restore donne des erreurs sur des objets déjà existants. Ça arrive quand vous restaurez dans une base de données qui a déjà des tables en conflit, habituellement une où des migrations ont déjà tourné. Utilisez --clean comme montré plus haut, ou restaurez dans une base de données vraiment vide et faites tourner vos propres migrations plutôt que le schéma du dump.
Erreurs de connexion SSL ou sslmode. Heroku Postgres exige une connexion SSL pour l’accès direct via pg_dump/psql; si vous faites un dump directement depuis Heroku plutôt qu’à partir d’un fichier de sauvegarde téléchargé, ajoutez ?sslmode=require à la chaîne de connexion. Votre base de données de destination peut avoir le problème inverse, refusant complètement le SSL sur une installation locale fraîche, auquel cas enlevez le paramètre pour ce côté-là.
Votre application écrit encore dans l’ancienne base de données après le basculement. C’est presque toujours un DATABASE_URL mis en cache, une valeur de gestionnaire de secrets qui n’a pas vraiment redéployé, ou un worker en arrière-plan qui n’a pas redémarré en même temps que le processus web. Vérifiez chaque type de processus séparément, pas seulement celui qui sert le trafic HTTP.
Foire aux questions
Est-ce que ça cause de l’interruption de service? Pas si vous suivez l’ordre ci-dessus. L’application Heroku continue de servir le trafic pendant la sauvegarde, la restauration et la vérification; le seul moment qui compte vraiment est celui où vous basculez DATABASE_URL, typiquement un seul redéploiement.
Qu’arrive-t-il à mon application Heroku pendant la migration? Rien, elle continue de tourner exactement comme avant. La capture de sauvegarde lit à partir d’un processus de type instantané qui ressemble à une réplique et ne verrouille pas vos tables de production.
Puis-je migrer sans le CLI Heroku? Seulement en partie. Vous pouvez récupérer une chaîne de connexion depuis les Config Vars de votre application dans le tableau de bord Heroku et lancer pg_dump directement contre celle-ci, mais capturer et télécharger une sauvegarde précise exige le CLI (ou Railyard tirant directement depuis l’URL en direct, ce qui ne demande aucun CLI du tout).
Dois-je faire correspondre exactement les versions de Postgres? Non, mais votre destination devrait être de la même version majeure ou plus récente. Restaurer un dump Heroku Postgres plus récent dans une destination plus ancienne peut échouer sur des fonctionnalités qui n’existaient pas encore dans la version plus ancienne.
Et si ma base de données est trop volumineuse pour un cycle rapide de sauvegarde et restauration? Le processus reste le même, ça prend simplement plus de temps. Prévoyez plus de temps pour les étapes 1 et 4 en particulier, et envisagez de faire tourner la restauration sur une machine avec plus de RAM temporairement si pg_restore est lent.
Peu importe le chemin choisi, manuel ou via Railyard, la discipline qui protège vraiment vos données reste la même : capturez avant de toucher à quoi que ce soit, vérifiez avant de basculer, et ne supprimez l’ancienne copie qu’une fois que vous avez eu le temps d’en être certain.
Pourquoi les gens choisissent Railyard pour ça
- Votre propre compte infonuagique. Déployez sur DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou n'importe quel serveur Linux par SSH, facturé directement par votre fournisseur, sans majoration.
- Un prix fixe par équipe. L'offre gratuite est gratuite pour toujours : un serveur plus un serveur de base de données, trois applications, sans carte. Pro coûte 19 $ par mois pour jusqu'à cinq serveurs et un nombre illimité d'applications. Team coûte 49 $ par mois avec des serveurs illimités. Aucuns frais par application, par déploiement, par siège ou par gigaoctet.
- Des gabarits en un clic. Déployez des applications open source, comme des bases de données, des outils d'analyse et des outils de développement, sur votre propre serveur en un clic.
- Des bases de données gérées. Postgres, MySQL et Redis, avec des sauvegardes planifiées, vérifiées par restauration, et la récupération à un point dans le temps.
- Déploiement par push. Déployez depuis GitHub, GitLab ou la CLI, avec HTTPS automatique et des mises en production sans interruption.