Aller au contenu principal

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 :

  1. 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.
  2. 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.
  3. 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).
  4. 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.
  5. 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-data avec 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​

  1. Ouvre un terminal dans un dossier vide de ton répertoire personnel.

  2. 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/) et backend-secret.

📄 Étape 2 — Préparer les deux fichiers​

  1. 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: true

    postgres est un PostgreSQL 14 neuf, avec ses données dans le nouveau volume astrolabe-postgres. astrolabe utilise ton volume astrolabe-data existant (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 lignes astrolabe-data de la fin.

  2. À 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​

  1. Arrête Astrolabe.

    docker stop astrolabe
  2. Lance la migration.

    docker compose -f docker-compose.postgres.yml run --rm astrolabe migrate-to-postgres

    Compose 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.
  3. Démarre Astrolabe sur PostgreSQL.

    docker compose -f docker-compose.postgres.yml up -d

🔍 Étape 4 — Vérifier​

  1. Attends qu'Astrolabe soit prêt. Cette commande répond 200 quand il l'est.

    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:7007/.backstage/health/v1/readiness
  2. 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"
  3. Ouvre http://127.0.0.1:7007. Dans Nom d'utilisateur, saisis administrator, 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.

  4. Clique sur Administration en bas de la barre latérale, puis sur Licences : ta licence affiche Active et la même date de fin.

  5. 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
Sauvegarde désormais les deux volumes

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 :

  1. Arrête Astrolabe sur PostgreSQL.

    docker compose -f docker-compose.postgres.yml down
  2. 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.

  1. Dans docker-compose.postgres.yml, retire le service postgres, le bloc depends_on d'astrolabe et le volume astrolabe-postgres:.

  2. Règle les quatre variables du service astrolabe sur ton serveur : POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD.

  3. Donne à cet utilisateur le droit de créer des bases (CREATEDB) : Astrolabe crée une base par plugin, nommée backstage_plugin_<plugin>.

  4. Monte max_connections à 300 ou plus : chaque plugin ouvre son propre lot de connexions.

Puis suis les étapes 3 à 5.

📚 Référence​

ÉlémentValeur
Commandemigrate-to-postgres, argument de l'image Astrolabe (3.2.0 ou plus)
Variables luesPOSTGRES_HOST, POSTGRES_USER, POSTGRES_PASSWORD (obligatoires), POSTGRES_PORT (5432 par défaut)
Sourceles fichiers .sqlite de /app/data/db, ouverts en lecture seule
Cibleune 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élaile 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 voisCause 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 foundMême cause : ton Astrolabe utilise un autre nom de volume.
required variable ASTROLABE_VERSION is missing a value: set ASTROLABE_VERSIONLe 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 allocatedL'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 backendAstrolabe 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'authentificationADMIN_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.
Toujours bloqué ?

Écris à support@forgeit.fr avec toute la sortie de la commande.