Claude Code et Docker

Isolation de Claude Code

Le danger

Commençons par le point de vigilance. Tous les programmes possèdent des bugs. Il n’est pas nécessaire de voir une intention malveillante pour souhaiter se protéger contre des actions qui pourraient, par exemple, détruire ou endommager des fichiers. Dans le cas de Claude Code, c’est un outil qui permet, entre autre, de modifier, créer, supprimer des fichiers dans un objectif de programmation. Je n’aime pas trop laisser accès au contenu de mon disque à un programme “créatif”. Car les bugs existent. Claude Code n’est pas sensé sortir du répertoire qu’on lui donne, mais la confiance n’empêche pas le contrôle.

Et si on bloquait Claude Code dans un répertoire ?

Pour limiter l’impact d’un bug critique dans Claude Code, on peut toujours utiliser une technologie externe à Claude Code pour l’empêcher de “sortir” de l’espace de travail qu’on lui donne. J’ai choisi de passer par un conteneur Docker, car c’est simple à mettre en œuvre, rapide et facilement adaptable.

Workflow avec Docker

Création de l’image

La première chose à faire est de construire une image qu’on pourra plus tard utiliser pour faire un conteneur. Il y aura des limitations quant à l’utilisation de Claude Code, mais elles restent mineures, en tous cas pour l’usage que j’en fais. Pour constuire une image, je vais créer un Dockerfile:

FROM debian:stable
RUN useradd -m -s /bin/bash yves
RUN apt update && apt install -y git curl python3 hugo
RUN apt install -y python3.11-venv
USER yves
SHELL ["/bin/bash", "-c"]
WORKDIR /home/yves
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
RUN mkdir -p ~/.npm-global
RUN source "$HOME/.nvm/nvm.sh" &&  nvm install 22 #&& npm config set prefix ~/.npm-global
RUN echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
RUN source "$HOME/.nvm/nvm.sh" &&  npm install -g @anthropic-ai/claude-code

Pour ceux qui débutent avec Docker, une petite explication sur ce contenu:

  • FROM debian:stable : On part d’une image Debian Stable. On aura alors les outils qui sont dans le conteneur officiel Debian de base
  • RUN useradd -m -s /bin/bash yves : Le mot clé RUN permet d’exécuter des commandes pour la création de l’image. Ici on crée un utilisateur yves
  • RUN apt update && apt install -y git curl python3 hugo et RUN apt install -y python3.11-venv: on installe les outils dont on aura besoin
  • USER yves: la suite des commandes ne s’exécutent pas en tant que root comme précédemment, mais en tant que l’utilisateur yves qu’on vient de créer
  • SHELL ["/bin/bash", "-c"] les commandes RUN se feront dans le shell bash
  • WORKDIR /home/yves : indique qu’on va travailler dans le dossier /home/yves
  • S’en suivent les installation de de nvm, de npm et nodejs et enfin de claude-code

L’étape suivante va être de demander à docker de créer l’image en local sur notre machine, à l’aide de la commande docker build -t claudecode .:

yves@localhost $ docker build -t claudecode .
[+] Building 0.5s (13/13) FINISHED                  docker:desktop-linux
 => [internal] load build definition from Dockerfile                0.0s
[...]
yves@localhost $ 

On a créé ici une image à partir du fichier Dockerfile présent dans le répertoire courant, qu’on nommera claudecode.

Utilisation de l’image

Pour utiliser l’image, je vais, sur ma machine hôte, me placer dans le répertoire de travail de mon projet.

yves@localhost $ cd /home/yves/projet1

Ensuite je vais lancer le conteneur de façon interactive en montant ce dossier dans le conteneur:

yves@localhost $ docker run -it --name projet1 -v "$PWD":/home/yves/projet claudecode

Je suis maintenant dans le conteneur et je peux lancer claude, me connecter et commencer à travailler. Ce dernier ne pourra pas voir les autres fichiers de mon ordinateur.

Attention, si je sors de mon conteneur, celui-ci va s’arrêter, mais il est toujours présent dans le système. Pour reprendre où j’en étais, il suffit que je le rappelle avec son nom, et que je le démarre en mode intéractif:

yves@localhost $ docker start -ai projet1

Les inconvénients

Un des principaux inconvénients de travailler comme ça est que claude n’aura pas la possibilité d’exécuter le code qu’il écrit de par lui même, car il ne peut pas installer de dépendances. Par exemple, quand je programme en python, il n’y a pas le module venv de présent, et pip n’est pas installé. On peut évidemment adapter le Dockerfile à notre projet pour que les prérequis à notre projet soit installé, mais d’avoir un conteneur générique me va très bien. Un point de vigilance est de ne pas oublier de faire le ménage dans les conteneurs qu’on lance de temps en temps. C’est facile de lancer 40 projets et conteneurs en même temps, mais comme le conteneur ne contient rien d’autre que claude on peut facilement le détruire et le recréer quand on en a besoin.