Lors de mes pérégrinations webesques pour vous trouver des nouveautés et assurer mon flux hebdomadaire de Pépites du Lundi matin, je suis tombé sur un outil de sauvegarde compatible avec de nombreux environnements de bases de données ainsi que d’un truc que je trouve génial personnellement … mais je tease 😉 … laissez moi vous présenter Portabase !
Portabase a de nombreux atouts même si au départ, sa proposition n’est pas a priori hyper sexy. Malgré tout cette fonction est critique et nécessaire dans nos environnements de production: la sauvegarde de bases de données. Maintenant, le coté « boring » de Portabase s’arrête là. Et je vais essayer dans cet article de vous présenter de manière macro son fonctionnement.
D’abord une liste (non exhaustive) de ses forces, jugez plutôt :
- Tout en une seule commande : La CLI est le point d’entrée unique de l’outil (déploiement, gestion, mises à jour, aussi bien pour déployer tout votre dashboard via docker-compose que d’installer l’agent qui s’y connectera, via du docker-compose également)
- Security by design : Pas de ports entrants sur les hosts … seuls les agents se connectent au dashboard
- Multi-destinations : Une sauvegarde = plusieurs cibles simultanées (ex: local + S3 + Google Drive)
- Open Source (Licence Apache 2.0) + self-hosted
- Prise en charge de nombreuses bases de données et environnements : PostgreSQL, MySQL, MariaDB, MongoDB, Redis, SQlite, Firebird, MS SQL et … les Docker Volumes (pour des données critiques, un vault par exemple) !
- Et pour ne rien gâcher, une philosophie de développement et d’intégration qui ferait rendre jaloux un certain Richard (si vous n’avez pas la réf, je ne peux plus rien pour vous …) : développée et maintenue par une association loi 1901 !
Ca se présente pas mal et ce n’est que le début. On est partie pour une découverte illustrée à la vblog 🙂
Installation initiale
L’installation est tellement simple que ça en est presque frustrant. Vous installez un binaire maitre et c’est quasi fini…
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
cidou@merlin:~ curl -sL https://portabase.io/install | bash Portabase installed successfully ! ╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ --version Show the version and exit. │ │ --help Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ System ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ update Update the CLI to the latest version. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Creation ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ agent Create a new Portabase Agent instance. │ │ dashboard Create a new Portabase Dashboard instance. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Lifecycle ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ start Start a Portabase component. │ │ stop Stop a Portabase component. │ │ restart Restart a Portabase component. │ │ logs View logs of a Portabase component. │ │ uninstall Uninstall and delete a Portabase component. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Configuration ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ db Manage databases configuration. │ │ config Manage global CLI configuration. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ cidou@merlin:~ portabase dashboard vBlogDashboard █▀█ █▀█ █▀█ ▀█▀ ▄▀█ █▄▄ ▄▀█ █▀ █▀▀ █▀▀ █▄█ █▀▄ █ █▀█ █▄█ █▀█ ▄█ ██▄ Deploy your infrastructure anywhere. You can add multiple databases to a single agent during setup. ? Database Setup internal: use the database embedded in the Portabase container ╭──────────────── PROPOSED CONFIGURATION ─────────────────╮ │ Dashboard Name vBlogDashboard │ │ Path /home/cidou/vBlogDashboard │ │ Access URL http://localhost:8887 │ │ Database Setup Embedded Database (In-container) │ │ Files to Create • docker-compose.yml │ │ • .env │ ╰─────────────────────────────────────────────────────────╯ The dashboard will be set up with the parameters above. Apply this configuration and generate files? [y/n] (y): y ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ DASHBOARD CREATED: vBlogDashboard │ │ Path: /home/cidou/vBlogDashboard │ │ Embedded Database │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ Start dashboard now? [y/n] (n): n |
Avant de lancer le docker-compose, vu que je suis curieux, j’ai un peu regardé ce que l’outil initial portabase a préparé :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
cidou@merlin:~/vBlogDashboard cat docker-compose.yml name: vblogdashboard services: portabase: container_name: vblogdashboard-app image: portabase/portabase:latest restart: unless-stopped env_file: - .env ports: - "${HOST_PORT}:80" environment: - TZ=${TZ} - LOG_LEVEL=${LOG_LEVEL} - PROJECT_SECRET=${PROJECT_SECRET} - PROJECT_URL=${PROJECT_URL} volumes: - portabase-data:/data healthcheck: test: ["CMD-SHELL", "curl -f http://localhost/api/health"] interval: 30s timeout: 5s retries: 3 start_period: 60s volumes: portabase-data: |
… coté configuration, un seul et unique .env contient toutes les données sensibles :
|
1 2 3 4 5 6 7 |
cidou@merlin:~/vBlogDashboard cat .env HOST_PORT="8887" PROJECT_SECRET="xxxxxxxxxxxxxxxxxxxxxxx" PROJECT_URL="http://localhost:8887" PROJECT_NAME="vblogdashboard" TZ="Europe/Paris" LOG_LEVEL="info" |
Et c’est tout pour le moment. On lance donc le docker-compose ;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
cidou@merlin:~/vBlogDashboard$ docker compose up (..) vblogdashboard-app | [INFO] Application timezone set to Europe/Paris (environment only) vblogdashboard-app | [INFO] No DATABASE_URL provided, starting internal Postgres... vblogdashboard-app | [INFO] PostgreSQL server is up and accepting connections vblogdashboard-app | [SUCCESS] Internal PostgreSQL started successfully vblogdashboard-app | [SUCCESS] Database: portabase_db | User: portabase_user | Host: 127.0.0.1:5432 vblogdashboard-app | ▶ Starting tusd server... vblogdashboard-app | ▶ Starting Next.js server... vblogdashboard-app | ▶ Starting nginx... vblogdashboard-app | 2026/07/14 20:08:40.455681 Using '/data/private/uploads/tmp' as directory storage. vblogdashboard-app | 2026/07/14 20:08:40.455763 Using 20480.00MB as maximum size. vblogdashboard-app | 2026/07/14 20:08:40.455778 Using 'http://127.0.0.1:3000/api/tus/hooks' as the endpoint for hooks vblogdashboard-app | 2026/07/14 20:08:40.456032 Enabled hook events: pre-create, post-create, post-receive, post-terminate, post-finish vblogdashboard-app | 2026/07/14 20:08:40.456038 Supported tus extensions: creation,creation-with-upload,termination,concatenation,creation-defer-length vblogdashboard-app | 2026/07/14 20:08:40.456040 Using 0.0.0.0:1080 as address to listen. vblogdashboard-app | 2026/07/14 20:08:40.456042 Using /tus/files/ as the base path. vblogdashboard-app | 2026/07/14 20:08:40.456150 Using /metrics as the metrics path. vblogdashboard-app | 2026/07/14 20:08:40.456634 You can now upload files to: http://[::]:1080/tus/files/ vblogdashboard-app | ▲ Next.js 16.2.3 vblogdashboard-app | - Local: http://localhost:3000 vblogdashboard-app | - Network: http://0.0.0.0:3000 vblogdashboard-app | ✓ Ready in 0ms vblogdashboard-app | vblogdashboard-app | ____ __ __ vblogdashboard-app | / __ \____ _____/ /_____ _/ /_ ____ _________ vblogdashboard-app | / /_/ / __ \/ ___/ __/ __ / __ \/ __ / ___/ _ \ vblogdashboard-app | / ____/ /_/ / / / /_/ /_/ / /_/ / /_/ (__ ) __/ vblogdashboard-app | /_/ \____/_/ \__/\__,_/_.___/\__,_/____/\___/ vblogdashboard-app | vblogdashboard-app | Community Edition v1.23.3 vblogdashboard-app | vblogdashboard-app | vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"init","msg":"====Init Functions===="} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"rsa-keys","msg":"Master key already exists. Skipping generation."} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"rsa-keys","msg":"RSA keys already exist. Skipping generation."} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"db","msg":"Running migrations..."} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"db","msg":"Migrations applied successfully."} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"init/user","msg":"Default admin creation skipped: missing environment variables."} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"init","msg":"====Initialization completed===="} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"init/cron","msg":"==== Setting up Cron Jobs ===="} vblogdashboard-app | {"level":"INFO","time":"14/07/2026,T20:08:42","module":"init/cron","msg":"==== Cron jobs started ===="} |
À noter : Pour accéder à votre instance à distance depuis votre réseau, vous devez modifier la variable PROJECT_URL dans le fichier .env en indiquant une URL accessible depuis votre réseau (par exemple http://merlin:8887), et non l’URL locale par défaut (http://localhost:8887). Sans cette modification, l’interface Web tentera systématiquement de se connecter à 127.0.0.1, ce qui générera une erreur de connexion (le frontend JavaScript utilise cette URL pour communiquer avec le backend). Petit piège : j’ai moi-même perdu une trentaine de minutes avant de comprendre que le problème venait de cette configuration par défaut.
Maintenant, la suite va se passer, via la GUI initiale du Dashboard de Portabase. Voici les principales étapes










Vous noterez que j’ai passé très rapidement certaines options car on va repasser dessus plus en détail à partir de maintenant. Votre dashboard est relativement vide pour le moment, avec juste 2 organisations, en quelques sortes deux tenants, le tenant par défaut et votre organisation/projet créé via la ligne de commande initiale. Désormais il va falloir organiser la liste des bases de données et volumes docker à sauvegarder, ainsi que le support de sauvegarde lui-même.
On commence par le support de sauvegarde qu’on appelle un Storage Channel. On va choisir S3 :




Ensuite, on va configurer un agent. C’est cet agent qui va s’occuper de la sauvegarde, donc il va falloir le créer sur le host dont vous désirer sauvegarder des données (bdd ou volume docker). Pour mon exemple, on va se connecter sur la machine « sandbox » et sauvegarder le volume docker « proxcenter_data ». Voici la partie dashboard :




… et maintenant, la partie ligne de commande de portabase coté host sandbox :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
cidou@sandbox:~ sudo portabase agent "agent-sandbox" --key eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbWVybGluOjg4ODciLCJhZ2VudElkIjoiOGQxMjAwNzUtOTA1Yi00ZTJlLTliMjEtZGU2NWNmNjcyMmYzIiwibWFzdGVyS2V5QjY0IjoiOWdpOCsyMHlLT214cWVuUFdmc2t1Y3U2UUlIQStHUk1KNnBVVkpBS1hFYz0ifQ== [sudo] password for cidou: █▀█ █▀█ █▀█ ▀█▀ ▄▀█ █▄▄ ▄▀█ █▀ █▀▀ █▀▀ █▄█ █▀▄ █ █▀█ █▄█ █▀█ ▄█ ██▄ Deploy your infrastructure anywhere. Custom environment variables can be added to the generated .env file. Timezone (UTC): Europe/Paris Polling frequency (seconds) (5): 5 Add extra_hosts mapping (localhost -> host-gateway)? [y/n] (n): ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ Database Setup │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ? What do you want to configure? docker-volume ⚠ Requires the Docker socket. It will be mounted on the agent (/var/run/docker.sock). Display Name (Docker Volume): proxcenter_data Volume Name (e.g. databases_sqlite-data): proxcenter_data Container Name (optional, enables auto-restart after restore) (): y ✔ Added to config ? What do you want to configure? done ╭───────────────────────── PROPOSED CONFIGURATION ──────────────────────────╮ │ Agent Name agent-sandbox │ │ Path /home/cidou/agent-sandbox │ │ Edge Key eyJzZXJ2ZX...hFYz0ifQ== │ │ Timezone Europe/Paris │ │ Polling 5s │ │ Host Gateway No │ │ Databases • proxcenter_data (docker-volume: proxcenter_data) │ │ Files to Create • docker-compose.yml │ │ • .env │ │ • databases.json │ ╰───────────────────────────────────────────────────────────────────────────╯ The agent will be configured in the directory above and ready for deployment. Apply this configuration and generate files? [y/n] (y): ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ AGENT READY: agent-sandbox │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ Start agent now? [y/n] (n): y |
Une fois démarré, vous allez constater que la page de l’agent sur le dashboard indique désormais l’état de celui-ci, la liste des bases (ou volumes 🙂 ) dont il doit s’occuper.


Enfin, on va construire notre « projet » de sauvegarde :





… et on lance le premier backup !

Après cette première présentation de Portabase, il reste encore beaucoup à découvrir, mais je vous laisse explorer plus loin si le cœur vous en dit.
Portabase, on le voit, est extrêmement bien structuré : tout est intégré au bon endroit, sans complexité superflue, à mon avis. La liste des bases de données supportées (à l’exception d’Oracle… mais bon, qui en a encore besoin aujourd’hui ?😉) est très complète, et la plupart des implémentations sont déjà marquées comme Stables, alors que le projet reste jeune. Pourtant, il mûrit rapidement – le premier commit de la version 1.0 date d’ailleurs du début de l’année.
J’adore son interface dashboard, à la fois minimaliste et élégante. Elle me rappelle beaucoup celle de Pangolin, mon bastion Open Source préféré, que j’utilise depuis presque un an (d’ailleurs, si vous ne le connaissez pas, je vous invite à lire mon article de présentation – c’est une vraie pépite à utiliser tous les Lundis !).
L’approche et la philosophie du projet me semblent parfaitement adaptées, car elles couvrent de nombreux cas d’usage… surtout depuis la prise en charge des Docker Volumes !
À suivre : on y reviendra peut-être dans quelques jours ou semaines (je vous mets l’eau à la bouche, mais… patience, chut ! ). Et puis, le fait que Portabase soit 100 % Open Source et soutenu par une association loi 1901, c’est plutôt rare et inspirant dans le paysage actuel…
Bref : ne serait-ce que pour le découvrir, jetez-vous sur Portabase et longue vie à ce produit si bien né et Français !
Références :
– Site Portabase : https://portabase.io
– Portabase sur GitHub : https://github.com/portabase/portabase
– L’association derrière Portabase : https://portabase.io/legal-notices
– Mon article sur Pangolin : https://vblog.io/pangolin/
