In this article
Comment conteneuriser des serveurs MCP en JavaScript
Les serveurs MCP sont des extensions faciles à intégrer aux LLM, mais leur configuration peut parfois être fastidieuse, car ils nécessitent un environnement de développement. Pour contourner cette difficulté, créons une image Docker pour nos serveurs MCP.
Dans un article précédent, j’ai expliqué comment exécuter des serveurs MCP avec Docker afin que les personnes souhaitant connecter des serveurs MCP n’aient pas à se débattre avec l’installation de la bonne version de Python ou à chercher comment installer npm ou npx pour les serveurs MCP basés sur JavaScript.
Dans cet article, nous allons nous intéresser à vous, en tant que développeur de serveurs MCP, et voir à quel point il est simple de fournir aux utilisateurs de MCP une image Docker qu’ils pourront utiliser. Nous allons mettre en place l’environnement de développement MCP suivant :
Configurer un
Dockerfilepour votre serveur MCPCréer un workflow GitHub Actions qui compile l’image Docker
Créer un workflow GitHub Actions qui publie l’image Docker sur GitHub Packages
Nous partons du principe que le projet de serveur MCP est développé en JavaScript (ou TypeScript) et repose sur un environnement de développement Node.js.
Avant de commencer, vous aurez besoin d’un environnement de développement Node.js, du projet MCP que vous souhaitez conteneuriser et de l’application Docker Desktop installée en local.
Configurer un Dockerfile pour votre serveur MCP
Un Dockerfile est la brique de base des images Docker. Il définit la manière dont une image est créée et exécutée lors de la création d’un conteneur.
Créez le Dockerfile suivant :
FROM node:22-slim AS builder
WORKDIR /app
COPY . /app
RUN --mount=type=cache,target=/root/.npm npm install
RUN --mount=type=cache,target=/root/.npm npm run build
RUN --mount=type=cache,target=/root/.npm-production npm ci --ignore-scripts --omit-dev
FROM node:22-slim AS release
WORKDIR /app
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/package.json /app/package.json
COPY --from=builder /app/package-lock.json /app/package-lock.json
ENV NODE_ENV=production
RUN npm ci --ignore-scripts --omit-dev
ENTRYPOINT ["node", "/app/dist/bin/cli.cjs"]Que se passe-t-il dans ce Dockerfile ?
Il s’agit d’un processus de création d’image Docker en plusieurs étapes, qui suit la bonne pratique consistant à séparer l’image utilisée pour compiler le projet de celle utilisée pour créer un conteneur Docker. Il suit les 10 bonnes pratiques Node.js pour conteneuriser des applications Node.js avec Docker.
Il définit un répertoire
/app, dans lequel se trouveront les fichiers du projet de serveur MCP dans le conteneur.À l’exécution du conteneur Docker, le fichier
/app/dist/bin/cli.cjssera lancé comme argument de l’environnement d’exécutionnode. Vous voudrez probablement remplacer ce chemin par celui du point d’entrée de votre serveur MCP, par exempleindex.jsouserver.js.
Et ensuite ? Maintenant que nous avons un Dockerfile, nous pouvons le compiler et l’exécuter en local pour vérifier qu’il fonctionne. Voici comment créer cette image Docker (vous pouvez remplacer my-mcp-server par le nom que vous souhaitez donner à cette image Docker) :
docker build -t my-mcp-server .Exécutez la commande ci-dessus à la racine du projet, où vous devez également placer votre Dockerfile. Une nouvelle image Docker sera alors créée.
Comment exécuter le serveur MCP à partir d’une image Docker ? Utilisez cette commande :
docker run -i --rm --init -e DOCKER_CONTAINER=true my-mcp-serverNous lançons un nouveau conteneur à partir de l’image Docker my-mcp-server créée précédemment. Nous utilisons ensuite les arguments -i et --rm pour indiquer à Docker qu’il s’agit d’un processus interactif connecté à STDIO et que, lorsque le conteneur est arrêté, il doit également être supprimé pour assurer un nettoyage complet.
Comment les utilisateurs peuvent-ils utiliser un serveur MCP via Docker ?
Maintenant que nous avons un serveur MCP, comment les clients MCP et les applications hôtes peuvent-ils l’utiliser ? Comment configurer la commande à exécuter si ce n’est ni ux ni pip pour Python, ni npx pour Node.js ?
Docker doit être installé, et de nombreux développeurs disposent probablement de Docker ou d’une solution compatible, comme Podman. Une fois Docker installé, ils peuvent configurer le serveur MCP comme suit :
{
"mcpServers": {
"my-mcp-server": {
"command": "docker",
"env": {},
"args": [
"run",
"-i",
"--rm",
"my-mcp-server"
]
}
}Presque ! Cet exemple n’est pas complet et ne fonctionnera pas pour les utilisateurs de MCP. Vous avez peut-être remarqué que nous faisons référence à my-mcp-server dans la commande Docker, mais comment Docker sait-il où récupérer cette image ? Et l’avons-nous seulement publiée à cet endroit ?
Exact, c’est ce qui manque. Nous avons créé un Dockerfile et compilé une image Docker en local, mais nous ne l’avons publiée nulle part. Pour simplifier la tâche des développeurs qui créent leurs logiciels sur GitHub, nous allons publier l’image sur le registre GitHub Packages, qui peut héberger des images Docker. C’est d’ailleurs exactement ce que fait aussi le serveur MCP officiel de GitHub.
Créer un workflow GitHub Actions qui compile l’image Docker et la publie sur GitHub Packages
Nous allons commencer par créer un workflow GitHub Actions qui génère une image Docker et comprend les étapes suivantes dans le workflow CI :
Compiler l’image Docker
Publier l’image Docker sur GitHub Packages
Signer l’image Docker
Voici le fichier de workflow complet à créer dans le répertoire suivant, à la racine de votre projet : .github/workflows/docker-publish-to-github.yml.
Avant d’exécuter et d’enregistrer ce fichier, modifiez la variable d’environnement IMAGE_NAME pour utiliser le nom de votre propre image Docker plutôt que l’exemple my-mcp-server :
name: "Docker: GitHub Packages"
on:
push:
branches:
- main
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/my-mcp-server
jobs:
build_and_publish:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
id-token: write
attestations: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }}
type=ref,event=pr
flavor: |
prefix=
suffix=
- name: Build and push Docker image
id: push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v2
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: trueVous remarquerez également que le fichier de workflow GitHub Actions ci-dessus, qui sert à compiler l’image Docker, part du principe que la branche principale s’appelle main.
Ensuite, vous devez accorder un droit d’écriture aux runners GitHub Actions. Pour cela, accédez à Settings -> Actions -> General dans votre dépôt et activez les autorisations de lecture et d’écriture comme suit :

Envie d’aller plus loin avec les MCP ?
Vous vous demandez quelle est la prochaine étape ? Voici quelques ressources utiles pour vous aider à mieux comprendre les serveurs MCP et à les sécuriser :
Guide pour débutants : comprendre visuellement l’architecture MCP
De l’injection de prompt aux autres vulnérabilités de sécurité, Sécurité MCP : rien de nouveau sous le soleil
22 octobre 2025
DevSecCon2025 - Le sommet sur la sécurité de l’IA
Réservez votre place et sécurisez la transition vers l’IA native