mkdevs

[ TWITTER ] [ FACEBOOK ] [ GITHUB ] [ LINKEDIN ]

Bienvenue sur mkdevs



Dockerfile de combat : Bâtir sa Toolbox Dev avec LazyVim, .NET 10, Node & OhMyBash

juin 23, 2026 | Tutos

L'Intro (Le problème)

Qui n'a jamais voulu packager son environnement de dev complet dans un conteneur Docker pour avoir une "Toolbox" portable ? On commence, on ajoute un prompt sympa (OhMyBash), son éditeur fétiche (LazyVim), ses SDK ( .NET 10, NVM/Node)... et là, c'est le drame.

Au premier docker compose up, on se mange des erreurs d'interactivité sur les scripts, des crashs Lua expected string, got nil, et pire : chaque fois qu'on recrée le conteneur, il faut réinstaller tous les plugins Neovim ! Après quelques heures de combat avec les mécanismes de Docker, voici ma pour tout faire cohabiter.

Le Piège Absolu : Les "Bind Mounts" qui écrasent le $HOME

Quand on débute, on a tendance à monter son dossier de travail comme ceci : - "./workspace:/home/devman".

Grave erreur ! Ce bind mount vient écraser et masquer tout ce que vous avez installé dans le répertoire de l'utilisateur pendant la phase de docker build (les configs de LazyVim, OhMyBash, NVM).

La solution ? Utiliser un Volume Nommé pour le $HOME de l'utilisateur (pour persister les outils et les configs) et isoler son code de travail dans un sous-dossier (ex: /home/devman/workspace).

Le Dockerfile.dev de « compétition »

Voici le fichier final qui résout l'installation non-interactive d'OhMyBash, crée les liens symboliques globaux pour Node/NVM (indispensables pour que les LSP de Neovim s'y retrouvent), et injecte proprement les Extras de langages (TypeScript, Angular, Python, .NET, Tailwind) dans le bon ordre pour LazyVim.

FROM debian:trixie-slim

ARG UID=1000
ARG GID=1000
ARG USERNAME=sid

# 1. Dépendances système & Outils
RUN apt update && apt install -y --no-install-recommends \
  bash curl git sudo tzdata build-essential ca-certificates \
  make unzip ripgrep fd-find python3 python3-pip python3-venv \
  libc6 libgcc-s1 libgssapi-krb5-2 libicu76 libssl3t64 libstdc++6 zlib1g \
  && rm -rf /var/lib/apt/lists/* \
  # 2. Neovim global
  && curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz \
  && tar -C /opt -xzf nvim-linux-x86_64.tar.gz && rm nvim-linux-x86_64.tar.gz

# 3. Utilisateur & Sudo
RUN groupadd -g "${GID}" "${USERNAME}" \
  && useradd -u "${UID}" -g "${GID}" -m -s /bin/bash "${USERNAME}" \
  && echo "${USERNAME} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/${USERNAME} \
  && chmod 0440 /etc/sudoers.d/${USERNAME}

USER ${USERNAME}
WORKDIR /home/${USERNAME}

ENV PATH=$PATH:/opt/nvim-linux-x86_64/bin
ENV DOTNET_ROOT=/home/${USERNAME}/.dotnet
ENV PATH=$PATH:$DOTNET_ROOT:$DOTNET_ROOT/tools

# 4. .NET 10 & EF Tools
RUN curl -sSL https://dot.net/v1/dotnet-install.sh -o dotnet-install.sh \
  && chmod +x dotnet-install.sh && ./dotnet-install.sh --channel 10.0 && rm dotnet-install.sh \
  && dotnet workload update && dotnet tool install --global dotnet-ef --version 10.0.*

# 5. OhMyBash (via Git pour le mode non-interactif)
ENV OSH=/home/${USERNAME}/.oh-my-bash
RUN git clone --depth=1 https://github.com/ohmybash/oh-my-bash.git ${OSH} \
  && cp ${OSH}/templates/bashrc.osh-template ~/.bashrc \
  && sed -i 's/OSH_THEME="font"/OSH_THEME="agnoster"/' ~/.bashrc

# 6. NVM, Node LTS + Liens symboliques vitaux pour Mason/LSP
ENV NVM_DIR=/home/${USERNAME}/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \
  && . "$NVM_DIR/nvm.sh" && nvm install --lts && nvm use default \
  && sudo ln -s "$(which node)" /usr/local/bin/node \
  && sudo ln -s "$(which npm)" /usr/local/bin/npm \
  && sudo ln -s "$(which npx)" /usr/local/bin/npx

# 7. LazyVim Starter + Injection des Extras dans le bon ordre
RUN git clone https://github.com/LazyVim/starter ~/.config/nvim && rm -rf ~/.config/nvim/.git \
  && sed -i '/{ import = "lazyvim.plugins" }/a \ \ \ \ { import = "lazyvim.plugins.extras.lang.typescript" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.angular" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.python" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.dotnet" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.markdown" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.tailwind" },\n\ \ \ \ { import = "lazyvim.plugins.extras.lang.json" },' ~/.config/nvim/lua/config/lazy.lua

CMD ["/bin/bash"]

La config Docker Compose magique

L'astuce réside dans le double montage :

services:
  toolbox:
    build:
      context: ./docker/toolbox
      dockerfile: Dockerfile.dev
      args:
        - UID=${UID:-1000}
        - GID=${GID:-1000}
        - USERNAME=${USERNAME:-sid}
    container_name: toolbox-dev
    tty: true
    stdin_open: true
    security_opt:
      - seccomp:unconfined # Requis pour le LSP .NET
    volumes:
      - "toolbox-home:/home/${USERNAME:-sid}"
      - "./workspace:/home/${USERNAME:-sid}/workspace"
    user: "${USERNAME:-sid}"
    working_dir: "/home/${USERNAME:-sid}/workspace"

volumes:
  toolbox-home:

Conclusion

Avec cette stack, plus de pollution locale sur votre machine. Tout est packagé, performant, et persistant. Au premier lancement, LazyVim s'initialise de manière ultra stable dans un vrai TTY interactif, installe ses serveurs via Mason, et vous êtes prêts à coder !

Dépôt GitHub