Passer à PostgreSQL
Un Astrolabe démarré en une commande (une licence d'essai, par exemple) garde ses données dans des fichiers
SQLite, dans le volume Docker astrolabe-data. Ça suffit pour une personne. Pour une équipe, ou avant de
continuer avec une licence payante, passe-le sur PostgreSQL. Cette page est la procédure de migration : ce
qu'elle fait, ce qu'il te faut, les étapes, comment vérifier le résultat et comment revenir en arrière.
Tes comptes, ton mot de passe, ton catalogue, tes tableaux de bord, tes réglages et les jetons saisis dans l'administration suivent. Les fichiers SQLite ne sont jamais modifiés : ils restent ton chemin de retour.
⚙️ Comment marche la migration
La migration est une commande de l'image Astrolabe, migrate-to-postgres. Elle ne tourne que si tu la
tapes : un Astrolabe démarré normalement ne migre jamais, et un Astrolabe qui reste en SQLite n'est jamais
concerné.
Tu la lances une fois, conteneur arrêté, par docker compose run. Le conteneur fait alors cette tâche au
lieu de démarrer le serveur :
- Il vérifie la cible. Il refuse un PostgreSQL qui contient déjà des données d'Astrolabe, et nomme la première base et la première table trouvées. Il n'écrase jamais rien. Seule exception : une migration qu'il a lui-même laissée en cours, qu'il reprend.
- Il crée le schéma. Il démarre une fois le backend d'Astrolabe sur PostgreSQL, pour que chaque plugin
crée sa propre base (
backstage_plugin_<plugin>) avec ses propres migrations : le même schéma qu'un Astrolabe installé sur PostgreSQL dès le premier jour. Puis il arrête ce backend. - Il copie les données, plugin par plugin, une transaction par plugin. Il vide ce que le premier démarrage a écrit, puis copie chaque table de chaque fichier SQLite, en convertissant chaque valeur au type de sa colonne PostgreSQL (booléens, dates, JSON, entiers gardés exacts).
- Il vérifie chaque table. Une table ou une colonne qui existe avec des données dans SQLite mais pas dans PostgreSQL, ou un nombre de lignes différent entre les deux, annule le plugin et arrête la migration en nommant le plugin et la table.
- Il recale les séquences après les identifiants copiés, pour que les nouvelles lignes aient de nouveaux identifiants.
Les fichiers SQLite sont ouverts en lecture seule pendant toute la migration.
Les jetons et mots de passe saisis dans l'administration sont copiés tels quels, toujours chiffrés. Ils
restent lisibles parce que la clé qui les ouvre, backend-secret, est dans le même volume astrolabe-data,
qu'Astrolabe continue d'utiliser sur PostgreSQL.
✅ Ce qu'il te faut
- La machine où tourne Astrolabe, avec Docker et Docker Compose.
- Le nom du volume de ton Astrolabe :
astrolabe-dataavec la commande du mail d'essai. Pour le lire :docker inspect astrolabe --format '{{range .Mounts}}{{.Name}} {{end}}'. - Ta clé de licence.
- Une version d'Astrolabe qui contient la migration : 3.2.0 ou plus. La migration te met aussi à jour vers cette version si tu étais sur une plus ancienne.
- Quelques minutes d'interruption : Astrolabe est arrêté pendant la copie. Sur une instance d'essai, la copie elle-même prend moins d'une minute.
- De la place sur le disque pour PostgreSQL, à peu près la taille du volume
astrolabe-data.
💾 Étape 1 — Sauvegarder le volume
-
Ouvre un terminal dans un dossier vide de ton répertoire personnel.
-
Copie le volume dans une archive.
docker run --rm -v astrolabe-data:/data -v "$PWD":/backup alpine tar czf /backup/astrolabe-data.tar.gz -C /data .Le dossier contient maintenant
astrolabe-data.tar.gz, avec les fichiers SQLite (db/) etbackend-secret.
📄 Étape 2 — Préparer les deux fichiers
-
Dans le même dossier, enregistre ce fichier sous le nom
docker-compose.postgres.yml.name: astrolabe
services:
postgres:
image: postgres:14-alpine
command: postgres -c max_connections=300
environment:
POSTGRES_USER: ${POSTGRES_USER:-backstage}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-backstage}
volumes:
- astrolabe-postgres:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-backstage}']
interval: 5s
timeout: 5s
retries: 10
astrolabe:
image: forgeitnc/astrolabe:${ASTROLABE_VERSION:?set ASTROLABE_VERSION}
depends_on:
postgres:
condition: service_healthy
ports:
- '${ASTROLABE_PORT:-7007}:7007'
environment:
ENVIRONMENT: production
FRONTEND_BASE_URL: http://127.0.0.1:${ASTROLABE_PORT:-7007}
BACKEND_BASE_URL: http://127.0.0.1:${ASTROLABE_PORT:-7007}
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: ${POSTGRES_USER:-backstage}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-backstage}
ADMIN_USERNAME: ${ADMIN_USERNAME:-administrator}
ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@astrolabe.local}
ORGANIZATION_NAME: ${ORGANIZATION_NAME:-Astrolabe}
ASTROLABE_LICENCE: ${ASTROLABE_LICENCE:-}
volumes:
- astrolabe-data:/app/data
volumes:
astrolabe-postgres:
astrolabe-data:
name: astrolabe-data
external: truepostgresest un PostgreSQL 14 neuf, avec ses données dans le nouveau volumeastrolabe-postgres.astrolabeutilise ton volumeastrolabe-dataexistant (external: true: Compose ne le crée pas, il prend celui de ton essai). Si ton volume a un autre nom, mets-le dans les deux lignesastrolabe-datade la fin. -
À côté, crée un fichier nommé
.env.ASTROLABE_LICENCE=<ta clé de licence>
ASTROLABE_VERSION=3.2.0
POSTGRES_PASSWORD=<un mot de passe pour PostgreSQL>Compose le lit tout seul. Garde ce fichier : il sert à chaque démarrage.
🐘 Étape 3 — Migrer
-
Arrête Astrolabe.
docker stop astrolabe -
Lance la migration.
docker compose -f docker-compose.postgres.yml run --rm astrolabe migrate-to-postgresCompose démarre PostgreSQL, puis lance la migration dans un conteneur Astrolabe ponctuel, supprimé à la fin (
--rm). La sortie donne une ligne par plugin, puis :🗄️ Creating the PostgreSQL schema (one start of the backend)…
✓ schema created
📦 Copying … SQLite databases to PostgreSQL postgres:5432
✓ account: … tables, … rows
…
✅ Migration done. Start Astrolabe on PostgreSQL: docker compose -f docker-compose.postgres.yml up -d
The SQLite files are untouched in the volume: they are your way back. -
Démarre Astrolabe sur PostgreSQL.
docker compose -f docker-compose.postgres.yml up -d
🔍 Étape 4 — Vérifier
-
Attends qu'Astrolabe soit prêt. Cette commande répond
200quand il l'est.curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:7007/.backstage/health/v1/readiness -
Vérifie qu'il tourne sur PostgreSQL. Cette commande affiche une ligne qui dit
Database is PostgreSQL.docker compose -f docker-compose.postgres.yml logs astrolabe | grep "Database is PostgreSQL" -
Ouvre
http://127.0.0.1:7007. Dans Nom d'utilisateur, saisisadministrator, dans Mot de passe le mot de passe que tu utilises déjà, puis clique sur SE CONNECTER. Astrolabe ne demande pas de nouveau mot de passe : c'est le même compte. -
Clique sur Administration en bas de la barre latérale, puis sur Licences : ta licence affiche Active et la même date de fin.
-
Ouvre le Catalogue et tes tableaux de bord : ils contiennent ce que tu avais en SQLite.
✅ La migration est faite.
🧹 Étape 5 — Supprimer l'ancien conteneur
Une fois vérifié, supprime l'ancien conteneur. Son volume reste : il contient toujours les fichiers SQLite,
et backend-secret, qu'Astrolabe sur PostgreSQL continue d'utiliser.
docker rm astrolabe
Désormais, démarre et arrête Astrolabe depuis le dossier des deux fichiers :
docker compose -f docker-compose.postgres.yml up -d
docker compose -f docker-compose.postgres.yml down
astrolabe-postgres contient les données. astrolabe-data contient backend-secret, la clé qui ouvre les
jetons saisis dans l'administration : sans elle, ces jetons sont perdus. Sauvegarde PostgreSQL avec
docker compose -f docker-compose.postgres.yml exec postgres pg_dumpall -U backstage | gzip > astrolabe-postgres.sql.gz,
et astrolabe-data avec la commande de l'étape 1.
↩️ Revenir à SQLite
Tant que tu n'as pas supprimé l'ancien conteneur :
-
Arrête Astrolabe sur PostgreSQL.
docker compose -f docker-compose.postgres.yml down -
Redémarre l'ancien conteneur.
docker start astrolabe
Astrolabe s'ouvre sur ses fichiers SQLite, tel qu'il était avant la migration. Ce que tu as changé sur PostgreSQL entre-temps n'y est pas.
Si tu as déjà supprimé l'ancien conteneur, relance la commande de ton mail d'essai : elle démarre un nouveau
conteneur sur le même volume astrolabe-data, avec les mêmes données.
Pour migrer de nouveau plus tard, repars d'un PostgreSQL vide :
docker compose -f docker-compose.postgres.yml down -v supprime le volume astrolabe-postgres (et lui
seul, astrolabe-data est externe), puis reprends à l'étape 3.
🏢 Utiliser un PostgreSQL que tu as déjà
La migration marche avec tout PostgreSQL 14 ou plus, tant qu'Astrolabe n'y a encore aucune base.
-
Dans
docker-compose.postgres.yml, retire le servicepostgres, le blocdepends_ond'astrolabeet le volumeastrolabe-postgres:. -
Règle les quatre variables du service
astrolabesur ton serveur :POSTGRES_HOST,POSTGRES_PORT,POSTGRES_USER,POSTGRES_PASSWORD. -
Donne à cet utilisateur le droit de créer des bases (
CREATEDB) : Astrolabe crée une base par plugin, nomméebackstage_plugin_<plugin>. -
Monte
max_connectionsà 300 ou plus : chaque plugin ouvre son propre lot de connexions.
Puis suis les étapes 3 à 5.
📚 Référence
| Élément | Valeur |
|---|---|
| Commande | migrate-to-postgres, argument de l'image Astrolabe (3.2.0 ou plus) |
| Variables lues | POSTGRES_HOST, POSTGRES_USER, POSTGRES_PASSWORD (obligatoires), POSTGRES_PORT (5432 par défaut) |
| Source | les fichiers .sqlite de /app/data/db, ouverts en lecture seule |
| Cible | une base PostgreSQL par plugin, backstage_plugin_<plugin> ; les règles RBAC (rbac.sqlite en SQLite) vont dans backstage_plugin_permission |
| Non copié | les tables de migration de chaque moteur (knex_migrations, …__knex_migrations) : PostgreSQL garde les siennes |
| Fichier de suivi | /app/data/migration-to-postgres.json, qui permet à une migration interrompue de reprendre sur le même PostgreSQL |
| Délai | le backend doit être prêt sur PostgreSQL en 10 minutes |
| Fin | ✅ Migration done. et le code 0 ; sinon une ligne qui commence par ❌ et un code non nul |
🛠️ Dépannage
| Ce que tu vois | Cause et quoi faire |
|---|---|
❌ PostgreSQL … already holds Astrolabe data (database …, table …). The migration only fills an empty PostgreSQL: give it a new, empty one. | Le PostgreSQL n'est pas vide : une migration a déjà tourné, ou Astrolabe y a déjà démarré. Pour recommencer, lance docker compose -f docker-compose.postgres.yml down -v, puis de nouveau l'étape 3. |
❌ No SQLite database in /app/data/db: mount the volume of the instance to migrate (-v astrolabe-data:/app/data). | Le volume n'est pas celui de ton Astrolabe. Lis son nom (voir « Ce qu'il te faut ») et mets-le dans les deux lignes astrolabe-data du fichier. |
external volume "astrolabe-data" not found | Même cause : ton Astrolabe utilise un autre nom de volume. |
required variable ASTROLABE_VERSION is missing a value: set ASTROLABE_VERSION | Le fichier .env manque, ou il n'est pas dans le dossier d'où tu lances la commande. |
Bind for 0.0.0.0:7007 failed: port is already allocated | L'ancien conteneur tourne encore. Lance docker stop astrolabe, puis la commande de nouveau. |
❌ <plugin>: table <table> has … rows in SQLite and … in PostgreSQL. ou … does not exist in PostgreSQL. | La copie de ce plugin ne correspondait pas et a été annulée. Ton Astrolabe en SQLite est intact : docker start astrolabe le ramène. Envoie toute la sortie à support@forgeit.fr. |
❌ The backend was not ready on PostgreSQL after 10 minutes. suivi des dernières lignes du backend | Astrolabe n'a pas pu démarrer sur ce PostgreSQL. Les lignes en dessous disent pourquoi (connexion refusée, mauvais mot de passe, trop peu de connexions). Corrige, lance docker compose -f docker-compose.postgres.yml down -v, puis de nouveau l'étape 3. |
| Après la migration, SE CONNECTER répond Échec de l'authentification | ADMIN_USERNAME vaut un autre nom dans ton terminal ou dans .env, et Compose le transmet. Retire-le (unset ADMIN_USERNAME), puis docker compose -f docker-compose.postgres.yml up -d --force-recreate. |
Écris à support@forgeit.fr avec toute la sortie de la commande.