Il m’arrive souvent de faire des petits scripts pour exporter des informations techniques ou système sur plusieurs environnements. Et, assez vite, on retombe sur le même vieux réflexe : un fichier texte, un CSV, un export posé quelque part sur le réseau, puis une compilation manuelle derrière.
Ce n’est plus vraiment une pratique de 2026.
En cherchant une base plus propre, je suis tombé sur PocketBase, un projet écrit en Go qui embarque un backend compact, une base SQLite, une API REST-ish, de l’authentification, une interface d’administration.
SQLite embarqué
Pas besoin de déployer PostgreSQL ou MariaDB pour un petit backend autonome.
Docker Communautaire
Un conteneur, quelques volumes, un port exposé, et on peut déjà tester.
API directe
On peut créer des collections et les alimenter depuis un script sans grosse couche applicative.
Généralement, on utilise PocketBase comme backend pour gérer une petite base de données embarquée. Ici, mon besoin n’est pas de l’interfacer avec une application web ou autre. L’objectif est plutôt de poser une base propre pour collecter des informations simples depuis des scripts : un inventaire léger, un état de serveur, un résultat de supervision maison ou des métriques applicatives, sans passer par la manipulation de fichiers à plat avant d’obtenir le résultat final.
Pas de Docker officiel
Pour ce projet, il n’y a pas d’image Docker officielle à démarrer directement. La documentation de PocketBase conseille plutôt de construire sa propre image. Si vous êtes à l’aise avec ce mécanisme et le docker build, je vous laisse vous inspirer du Dockerfile proposé dans la documentation PocketBase.
Pour rester dans l’esprit UOpsLab et être accessible à tous, je pars donc sur une image maintenue par la communauté : muchobien/pocketbase-docker.
Le contexte de départ
Dans cet article, je veux partir sur un cas très concret de collecte d’informations générées par un script :
- ➡️ installer rapidement PocketBase avec Docker
- ➡️ bien garder les données persistantes
- ➡️ vous proposer le Compose de la communauté avec quelques explications
- ➡️ configurer la base PocketBase
- ➡️ préparer un premier exemple de script qui pousse des informations dans PocketBase via l’API
Dans mon cas, je pars d’un VPS Debian récent, avec Docker déjà installé. Je pars donc du principe que vous avez déjà :
- ✅ une VM ou un VPS Debian x86_64
- ✅ l’environnement Docker + Docker Compose
- ✅ en option : un environnement Traefik
Préparation de la structure
Perso je travaille dans un dossier ~/docker, avec une arborescence par service :
cd ~/docker
sudo mkdir -p pocketbase
sudo chown -R "$USER":"$USER" pocketbase
cd pocketbase
Puis on prépare les dossiers que PocketBase va utiliser :
mkdir -p pb_data pb_public pb_hooks pb_migrations
Et on crée le fichier docker-compose.yml :
sudo nano docker-compose.yml
Docker Compose communauté
Comme mentionné plus haut, vous pouvez partir du Docker Compose proposé par la communauté ci-dessous, en mettant simplement à jour les variables PB_ADMIN_EMAIL et PB_ADMIN_PASSWORD :
services:
pocketbase:
image: ghcr.io/muchobien/pocketbase:latest
container_name: pocketbase
restart: unless-stopped
environment:
# Optional: Configure host and port (defaults: 0.0.0.0:8090)
PB_HOST: 0.0.0.0
PB_PORT: 8090
# Optional: Auto-create superuser (recommended for production)
PB_ADMIN_EMAIL: admin@yourdomain.com
PB_ADMIN_PASSWORD: your-secure-password-here
# Optional: Enable settings encryption (32-character key)
# https://pocketbase.io/docs/going-to-production/#enable-settings-encryption
ENCRYPTION: $(openssl rand -hex 16)
# Optional: Set timezone
TZ: Europe/Berlin
ports:
- "8090:8090" # Change both port and PB_PORT for custom ports: "3000:3000"
volumes:
- ./pb_data:/pb_data
- ./pb_public:/pb_public # optional
- ./pb_hooks:/pb_hooks # optional
# Optional: Add encryption flag if using ENCRYPTION env var
command: ["--encryptionEnv", "ENCRYPTION"]
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:8090/api/health",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
Docker Compose personnalisé
Voici deux ou trois possibilités si vous voulez personnaliser votre docker-compose.yml. Je préfère vous montrer ma version derrière Traefik, avec quelques explications :
image:généralement, on est souvent enlatest, mais sur une base de données je préfère fixer la version.
image: ghcr.io/muchobien/pocketbase:0.38.0
PB_ADMIN_EMAILetPB_ADMIN_PASSWORD: on peut les écrire en dur, les appeler depuis un.env, ou carrément les supprimer, car PocketBase génère un lien pour le premier login.
test@vm-uopslab :~/docker/pocketbase$ sudo docker compose logs -f
pocketbase | (!) Launch the URL below in the browser if it hasn't been open already to create your first superuser account:
pocketbase | http://0.0.0.0:8090/_/#/pbinstall/Sdv6f56asrrg46sdrg4ser4ttwe45eye1egsd1g654hrer1y4er4ywr1h+5s+h1wry4wer4y1w6r7ywery4w6+
pocketbase | (you can also create your first superuser by running: /usr/local/bin/pocketbase superuser upsert EMAIL PASS)
ENCRYPTIONOn peu aussi forcer son secret soit dans le .env ou en dur dans le compose. Voici génère donc une clé de 32 caractères hexadécimaux.
openssl rand -hex 16
À ne pas publier tel quel
Dans vos notes ou dans Git, évitez de conserver un vrai mot de passe admin. Pour l’article, je garde volontairement des valeurs fictives. En production, utilisez un secret solide, puis protégez le fichier .env.
LABELS Traefik: comme les URL sont bien identifiées dans la documentation officielle, je me suis dit que ça valait le coup de les répercuter proprement dans Traefik et de donner accès au superuser uniquement via le VPN :
Routes exposées par PocketBase
- http://127.0.0.1:8090 - if pb_public directory exists, serves the static content from it (html, css, images, etc.)
- http://127.0.0.1:8090/_/ - superusers dashboard
- http://127.0.0.1:8090/api/ - REST-ish API
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy-traefik"
# ===== Router HTTPS PUBLIC : site + API =====
- "traefik.http.routers.pocketbase.rule=Host(`pbtest.uopslab.com`) && !PathPrefix(`/_`)"
- "traefik.http.routers.pocketbase.entrypoints=websecure"
- "traefik.http.routers.pocketbase.tls=true"
- "traefik.http.routers.pocketbase.tls.certresolver=letsencrypt"
- "traefik.http.routers.pocketbase.service=pocketbase"
- "traefik.http.routers.pocketbase.priority=10"
# ===== Router HTTPS ADMIN : /_/ uniquement via VPN =====
- "traefik.http.routers.pocketbase-admin.rule=Host(`pbtest.uopslab.com`) && PathPrefix(`/_`)"
- "traefik.http.routers.pocketbase-admin.entrypoints=websecure"
- "traefik.http.routers.pocketbase-admin.tls=true"
- "traefik.http.routers.pocketbase-admin.tls.certresolver=letsencrypt"
- "traefik.http.routers.pocketbase-admin.service=pocketbase"
- "traefik.http.routers.pocketbase-admin.middlewares=vpn-only"
- "traefik.http.routers.pocketbase-admin.priority=100"
# ===== Service Web =====
- "traefik.http.services.pocketbase.loadbalancer.server.port=8090"
# ===== Router HTTP redirect only =====
- "traefik.http.routers.pocketbase-http.rule=Host(`pbtest.uopslab.com`)"
- "traefik.http.routers.pocketbase-http.entrypoints=web"
- "traefik.http.routers.pocketbase-http.middlewares=redirect-to-https"
- "traefik.http.routers.pocketbase-http.service=pocketbase"
# ===== Middlewares =====
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# À adapter selon ton réseau WireGuard
- "traefik.http.middlewares.vpn-only.ipallowlist.sourcerange=*.*.*.*/24"
Lancement du conteneur
Voilà, maintenant que tout est bien préparé, on lance le Compose et on vérifie les logs avant d’aller plus loin. Si vous avez choisi de créer le superuser via le lien généré par PocketBase, c’est ici qu’il faudra le récupérer :
sudo docker compose up -d
sudo docker compose logs -f
Les logs doivent afficher les routes principales :
Server started at http://0.0.0.0:8090
REST API: http://0.0.0.0:8090/api/
Dashboard: http://0.0.0.0:8090/_/
Adaptez donc l’IP, le port ou l’adresse en fonction de votre configuration.
https://pbtest.uopslab.com/_/#/login ou https://0.0.0.0:8090/_/#/login
Petit tour de PocketBase
Avant de commencer, prenez le temps de faire le tour des onglets et menus de PocketBase pour vous familiariser avec la solution.
Préparer les collections pour les scripts
Je vous laisse maître du choix des collections et des champs à déclarer pour votre collecte d’informations. Je veux simplement vous conseiller de créer une collection standard de ce style pour gérer les comptes utilisateurs qui pourront faire des appels API.
Ensuite, préparez votre collection avec les champs et les types qui correspondent aux informations que vous voulez remonter. N’oubliez surtout pas d’aller autoriser, dans les API rules, la collection utilisateur qui a le droit d’interagir avec votre collection, en fonction des permissions que vous voulez lui donner.

Dans tous les écrans de l’onglet Collection, vous aurez toujours le bouton indispensable pour consulter les appels API :

Superuser et scripts internes
Un superuser PocketBase peut tout faire. C’est pratique pour un script serveur-à-serveur, mais il faut le traiter comme un vrai secret d’infrastructure : pas dans un dépôt Git, pas dans un historique shell partagé, pas dans un fichier lisible par tout le monde. Pour vos scripts, utilisez plutôt des tokens limités à 30 jours ou un compte dédié que vous pourrez désactiver.
Exemple de script API
Voici un petit exemple PowerShell. On s’authentifie auprès de PocketBase, on récupère quelques informations locales, puis on crée un enregistrement dans server_reports.
$PocketBaseUrl = "https://pbtest.uopslab.com"
$AuthCollection = "User_API"
$TargetCollection = "TEST_Collection_DATA"
$ApiEmail = "audit@example.local"
$ApiPassword = "CHANGE_ME"
# ---------------------------------------------------------------------
# Authentification PocketBase
# ---------------------------------------------------------------------
$AuthUri = "$PocketBaseUrl/api/collections/$AuthCollection/auth-with-password"
$AuthBody = @{
identity = $ApiEmail
password = $ApiPassword
} | ConvertTo-Json
try {
$AuthResponse = Invoke-RestMethod `
-Uri $AuthUri `
-Method POST `
-ContentType "application/json" `
-Body $AuthBody
$Token = $AuthResponse.token
Write-Host "Authentification PocketBase OK"
}
catch {
Write-Host "Erreur authentification PocketBase"
Write-Host $_.Exception.Message
exit 1
}
$Headers = @{
Authorization = "Bearer $Token"
"Content-Type" = "application/json"
}
# ---------------------------------------------------------------------
# Informations machine
# ---------------------------------------------------------------------
$ComputerSystem = Get-CimInstance Win32_ComputerSystem
$OS = Get-CimInstance Win32_OperatingSystem
$ComputerName = $env:COMPUTERNAME
$Domain = $ComputerSystem.Domain
$OsCaption = $OS.Caption
$AuditKey = "$ComputerName|$Domain"
$BodyObject = @{
auditKey = $AuditKey
computerName = $ComputerName
domain = $Domain
osCaption = $OsCaption
}
$Body = $BodyObject | ConvertTo-Json -Depth 5
# ---------------------------------------------------------------------
# Envoi vers PocketBase
# ---------------------------------------------------------------------
$CreateUri = "$PocketBaseUrl/api/collections/$TargetCollection/records"
try {
$Response = Invoke-RestMethod `
-Uri $CreateUri `
-Method POST `
-Headers $Headers `
-Body $Body
Write-Host "Création PocketBase OK : $($Response.id)"
}
catch {
Write-Host "Erreur PocketBase"
Write-Host $_.Exception.Message
}
Voilà
C’est quand même plus propre, plus fiable et plus facilement exploitable sur le long terme qu’un export XLS posé quelque part. Même si, à la fin, on génère encore un fichier Excel complet pour finaliser un rapport, la donnée source reste structurée, centralisée et accessible via API.
L’autre avantage, c’est que cette base peut évoluer sans tout refaire : on peut enrichir les collections, ajouter des règles plus propres, créer des comptes dédiés par usage, ou brancher un outil comme Metabase pour obtenir un tableau de bord plus lisible. Pour des scripts d’inventaire, d’audit ou de supervision légère, PocketBase devient alors une petite brique très pratique entre le script brut et une vraie application métier.
Références utiles
Cet article vous a-t-il été utile ?
Votre retour aide à mieux choisir les prochains sujets.