Wrapper pour sandboxer pi.dev dans un conteneur
  • Shell 69%
  • Dockerfile 16.1%
  • Just 14.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
solene 159cad571d
All checks were successful
ci / build (push) Successful in 15s
ci / publish (push) Successful in 11s
Merge pull request 'renovate: update cgr.dev/chainguard/wolfi-base:latest Docker digest to 8509ee4' (#3) from renovate/dependances into main
Reviewed-on: #3
2026-11-07 10:42:35 +00:00
.forgejo/workflows fix: image de base wolfi-base, qui embarque apk 2026-11-04 22:56:57 +00:00
AGENTS.md fix: image de base wolfi-base, qui embarque apk 2026-11-04 22:56:57 +00:00
Containerfile renovate: update cgr.dev/chainguard/wolfi-base:latest Docker digest to 8509ee4 2026-11-07 04:00:19 +00:00
Justfile ci: image publique sur le registre Forgejo, renovate sur pi et l'image de base, option --update 2026-11-04 22:48:39 +00:00
pinata ci: image publique sur le registre Forgejo, renovate sur pi et l'image de base, option --update 2026-11-04 22:48:39 +00:00
README.md ci: image publique sur le registre Forgejo, renovate sur pi et l'image de base, option --update 2026-11-04 22:48:39 +00:00
renovate.json5 ci: image publique sur le registre Forgejo, renovate sur pi et l'image de base, option --update 2026-11-04 22:48:39 +00:00

Frappez-la pour que le code en tombe 🎉

pinata

Lance le CLI pi.dev dans un conteneur podman, avec le dossier courant monté comme espace de travail. pi n'a accès qu'à ce dossier, et aux éventuels dossiers que vous ajoutez explicitement, pas au reste de votre machine.

Équivalent de cloche pour pi.dev. Le nom vient de la piñata.

Image publique

Une image à jour est publiée automatiquement sur git.coopix.eu/public/pinata:latest à chaque merge dans main (voir « CI/CD »). Par défaut, pinata la télécharge depuis ce registre plutôt que de construire l'image localement.

Prérequis

  • podman 4.3 ou plus récent, en mode rootless (utilisateur normal, pas root)
  • bash
  • just, facultatif, pour l'installation en une commande

Installation

git clone <url-du-dépôt> ~/pinata
cd ~/pinata
just deploy

just deploy vérifie le script, crée le lien symbolique ~/.local/bin/pinata et récupère l'image (publiée, ou construite si le registre est indisponible). Vérifiez que ~/.local/bin est dans votre PATH ; just vous prévient si ce n'est pas le cas.

Sans just, le lien symbolique suffit, l'image étant alors téléchargée (ou construite si le registre est indisponible) au premier lancement :

ln -s ~/pinata/pinata ~/.local/bin/pinata

Dans les deux cas, le script retrouve le Containerfile à côté de son emplacement réel : ne déplacez pas le dépôt après l'installation, ou relancez just install.

Utilisation

cd ~/mon-projet
pinata

Au premier lancement, si l'image n'est pas déjà présente en local, pinata essaie d'abord de télécharger l'image publiée (git.coopix.eu/public/pinata:latest) ; si le registre est indisponible, l'image est construite localement (quelques minutes). Dans pi, tapez /login pour connecter un abonnement ou une clé d'API d'un fournisseur (Anthropic, OpenAI, etc.), ou définissez une clé d'API sur l'hôte avant de lancer pinata (voir « Variables d'environnement »). La connexion est conservée pour les lancements suivants.

Tout ce qui suit les options de pinata est transmis à pi :

pinata -p "résume ce dépôt"

Options

Option Effet
--rebuild reconstruit l'image (met à jour le CLI pi) avant de lancer
--update télécharge la dernière image publiée avant de lancer
--build-only image seulement : la construit si besoin (de zéro avec --rebuild, la télécharge avec --update) puis quitte
--shell ouvre un shell bash dans le conteneur au lieu de pi
--include CHEMIN monte un dossier de plus sur /work/<nom> (lecture/écriture) ; répétable
--include-ro CHEMIN idem, en lecture seule ; répétable
--pinata-help affiche l'aide

Ces options doivent être placées avant les arguments destinés à pi.

Travailler sur plusieurs projets

Pour donner à pi accès à d'autres dossiers que le projet courant, ajoutez-les avec --include (ou --include-ro si pi doit seulement les lire) :

cd ~/mon-projet
pinata --include ../ma-lib --include-ro ~/docs-api

Chaque dossier est monté à côté du projet, sur /work/<nom-du-dossier> (ici /work/ma-lib et /work/docs-api). Le projet courant reste le dossier de travail du conteneur et de pi. pi n'a pas d'option pour déclarer des dossiers supplémentaires : indiquez-lui ces chemins dans votre demande (par exemple « compare avec /work/ma-lib »).

Deux dossiers de même nom sont refusés, tout comme les chemins contenant « : ».

Variables d'environnement

Variable Rôle
PINATA_IMAGE nom de l'image (défaut : localhost/pinata:latest)
PINATA_PUBLIC_IMAGE image publiée téléchargée par --update, et à défaut à la place d'une construction locale (défaut : git.coopix.eu/public/pinata:latest)
PINATA_CONFIG_DIR dossier hôte de la config pi (défaut : ~/.local/share/pinata)
PINATA_PROXY proxy HTTP(S) sortant, tel que vu depuis le conteneur

Les clés d'API suivantes sont transmises au conteneur si elles sont définies sur l'hôte : ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, XAI_API_KEY. Pour les autres fournisseurs, utilisez /login dans pi.

Sont aussi transmises : TERM, COLORTERM, NO_PROXY, no_proxy et les variables de proxy (voir ci-dessous).

Ce qui est monté dans le conteneur

Sur l'hôte Dans le conteneur Accès
dossier courant /work/<nom-du-dossier> lecture/écriture
dossiers --include / --include-ro /work/<nom-du-dossier> selon l'option
PINATA_CONFIG_DIR /home/pi/.pi/agent lecture/écriture
~/.gitconfig, s'il existe /home/pi/.gitconfig lecture seule

PINATA_CONFIG_DIR contient la configuration de pi : connexion (auth.json), réglages, extensions et historique des sessions. La configuration ~/.pi/agent de l'hôte n'est pas utilisée.

Proxy

Les variables HTTP_PROXY, HTTPS_PROXY (et leurs versions en minuscules) de l'hôte sont transmises à la construction de l'image et au conteneur. Si le proxy écoute sur la machine locale (localhost, 127.0.0.1), il est injoignable depuis le conteneur : définissez alors PINATA_PROXY avec l'adresse du proxy telle que vue depuis le conteneur ; le proxy doit alors écouter sur une interface joignable depuis celui-ci. PINATA_PROXY remplace alors ces variables, à la construction (étapes apk et npm) comme au lancement ; podman garde le proxy de l'hôte pour télécharger l'image de base et l'image publiée.

Migrer depuis pi.dev installé sur l'hôte

Quand vous utilisez pi.dev directement sur votre machine, sa configuration (clés API, réglages, sessions, extensions, MCP, modèles, keybindings…) vit dans ~/.pi/agent. Pinata n'utilise pas ce dossier : il monte un autre répertoire hôte (PINATA_CONFIG_DIR, défaut ~/.local/share/pinata) sur /home/pi/.pi/agent dans le conteneur.

Pour conserver votre configuration pi.dev existante, copiez-la vers le dossier de config de pinata :

mkdir -p ~/.local/share/pinata
cp -r ~/.pi/agent/* ~/.local/share/pinata/

Vous pouvez aussi choisir un autre emplacement et le définir avec PINATA_CONFIG_DIR :

export PINATA_CONFIG_DIR=~/.pi/agent

Attention : si vous pointez PINATA_CONFIG_DIR vers ~/.pi/agent, les fichiers de ce dossier seront accessibles en lecture/écriture depuis le conteneur. Les clés API stockées dans auth.json seront lisibles par tout ce qui s'exécute à l'intérieur. Si ce n'est pas ce que vous souhaitez, utilisez un dossier séparé.

Ce qui est migré

Le dossier ~/.pi/agent contient :

Fichier / dossier Contenu
settings.json Réglages utilisateur (préférences, outils par défaut…)
auth.json Clés API et identifiants OAuth
mcp.json Serveurs MCP
models.json Points de terminaison et modèles
keybindings.json Raccourcis clavier personnalisés
extensions/ Extensions utilisateur
skills/ Skills et fichiers associés
prompts/ Templates de prompts (slash commands)
themes/ Thèmes UI
AGENTS.md, SYSTEM.md, APPEND_SYSTEM.md Instructions utilisateur globales
sessions/ Historique des sessions

Les sessions sont sauvegardées par dossier de travail. Si vous lancez pinata dans les mêmes répertoires que sur l'hôte, les sessions seront retrouvées automatiquement.

Mise à jour

Pour mettre à jour l'image avec la dernière version publiée (nouveau CLI pi, nouvelle image de base) : pinata --update ou just update. Pour reconstruire l'image localement de zéro (met à jour le CLI pi) : pinata --rebuild ou just rebuild. La commande pi update ne peut pas mettre pi à jour dans le conteneur ; elle indique de passer par pinata --rebuild. Pour mettre à jour pinata lui-même, faites git pull dans le dépôt.

Recettes just

Recette Effet
just liste les recettes
just deploy vérifie le script, crée le lien symbolique et récupère l'image (publiée, ou construite si besoin)
just install crée le lien symbolique ~/.local/bin/pinata (dossier modifiable avec PINATA_BINDIR)
just build récupère l'image si elle n'existe pas encore (publiée, ou construite si besoin)
just rebuild reconstruit l'image de zéro (met à jour le CLI pi)
just update télécharge la dernière image publiée sur le registre
just check vérifie la syntaxe du script
just uninstall supprime le lien symbolique et l'image ; la configuration de pi est conservée

Limites connues

  • pinata refuse de se lancer depuis votre dossier personnel ou depuis /, pour ne pas les exposer en entier.
  • Les clés d'API transmises et le contenu de PINATA_CONFIG_DIR sont lisibles par tout ce qui tourne dans le conteneur, y compris les commandes lancées par pi.
  • Le conteneur a accès au réseau sans restriction.
  • Les outils disponibles pour pi sont ceux de l'image (Node.js, git, ripgrep, jq, curl…) ; ce qu'il installe en cours de session disparaît à la fin (--rm), sauf dans le dossier monté.

CI/CD

La construction et la publication de l'image sont automatisées via Forgejo Actions :

  • Sur pull request (celles de Renovate comprises) : construction de l'image et vérification que pi répond (pi --version), sans envoi au registre
  • Au merge dans main : construction et publication sur le registre public de Forgejo git.coopix.eu/public/pinata:latest (et :sha du commit)

Avant chaque construction, la CI vérifie avec cosign la signature Sigstore des images de base Chainguard épinglées par digest dans le Containerfile ; une image hors cgr.dev/chainguard ou non épinglée par digest est refusée.

Token CI (CI_TOKEN)

Les workflows (.forgejo/workflows/) utilisent le secret CI_TOKEN du dépôt : un personal access token (PAT) du compte dédié ci-pinata sur git.coopix.eu, à renseigner dans Settings → Actions → Secrets du dépôt public/pinata.

Création du token

  1. Se connecter à git.coopix.eu avec le compte ci-pinata, puis Settings → Applications → Generate New Token.
  2. Choisir l'accès « All (public, private, and limited) » ou « Public only » — jamais « Specific repositories » : Forgejo n'y autorise que read:repository, write:repository, read:issue et write:issue, ce qui rend read:user et read:organization impossibles.
  3. Cocher les scopes du tableau ci-dessous (dans l'interface Forgejo, choisir le droit read ou write pour chaque groupe de scopes).
  4. Copier le token affiché une seule fois, puis mettre à jour le secret CI_TOKEN du dépôt.

Scopes requis

Sur Forgejo, le droit write inclut read : un scope en write donne aussi la lecture.

Scope Droit Utilisé par Pourquoi
user read Renovate GET /api/v1/user à l'initialisation ; sans ce scope, Renovate échoue avec « Authentication failure »
repository write CI + Renovate lecture du dépôt et création des pull requests de mise à jour (write inclut read)
issue write Renovate issues, labels et commentaires (exigé depuis Forgejo >= 1.20 ; write inclut read)
organization read Renovate lecture de l'organisation public et de ses labels (exigé depuis Forgejo >= 1.20)
package write CI connexion au registre et envoi de l'image (docker login / docker push)

Références : scopes des tokens Forgejo et Renovate sur Forgejo.

Vérifier le token

curl -H "Authorization: token $CI_TOKEN" https://git.coopix.eu/api/v1/user
curl -H "Authorization: token $CI_TOKEN" https://git.coopix.eu/api/v1/orgs/public

La première commande doit renvoyer le compte ci-pinata, la seconde l'organisation public.

Dépannage

  • Renovate échoue avec « Authentication failure » : le token manque un scope (souvent user en read, issue en write ou organization en read) ou le secret CI_TOKEN est vide ; passer LOG_LEVEL: debug dans .forgejo/workflows/renovate.yml donne le détail, puis relancer le workflow renovate (workflow_dispatch).
  • La CI échoue au docker login : le scope package en write manque ou a expiré.

Dépôt et CI

Élément Emplacement
Code source git.coopix.eu/public/pinata
Image publique git.coopix.eu/public/pinata:latest
Workflows CI .forgejo/workflows/
Configuration Renovate renovate.json5

Gestion des dépendances

Les dépendances du Containerfile (digest de l'image de base Chainguard, version épinglée du paquet npm pi) sont suivies automatiquement par Renovate : le tag de l'image via le gestionnaire dockerfile, et la version de pi épinglée dans le npm install via un gestionnaire regex (datasource npm). Les pull requests de mise à jour sont créées automatiquement selon la configuration dans renovate.json5 ; la CI construit et teste l'image de chaque pull request avant fusion.