In this article
JavaScriptでMCPサーバーをDocker化する方法
MCPサーバーはLLMに簡単に追加できる拡張機能ですが、開発環境が必要なため、セットアップに手間がかかることがあります。そこで、MCPサーバー用のDockerイメージを用意して、この問題を解決しましょう。
以前の記事では、DockerでMCPサーバーを実行する方法を説明しました。MCPサーバーに接続したいユーザーが、適切なPythonのバージョンのインストールに苦労したり、JavaScript製のMCPサーバーを使うためにnpmやnpxのインストール方法を調べたりする必要がなくなります。
この記事では、MCPサーバーの開発者に焦点を当て、MCPを利用する人が使えるDockerイメージを簡単に提供する方法を見ていきます。以下のMCP開発環境を構築します。
MCPサーバー用の
Dockerfileを設定するDockerイメージをビルドするGitHub Actionsワークフローを作成する
DockerイメージをGitHub PackagesにプッシュするGitHub Actionsワークフローを作成する
MCPサーバーのプロジェクトはJavaScript(またはTypeScript)で構築され、Node.js開発環境を使用しているものとします。
前提条件として、Node.js開発環境、Docker化するMCPプロジェクト、ローカルで利用できるDocker Desktopが必要です。
MCPサーバー用のDockerfileを設定する
DockerfileはDockerイメージの構成要素です。イメージのビルド方法と、コンテナの作成時にそのイメージを実行する方法を定義します。
次のDockerfileを作成します。
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"]このDockerfileでは何をしているのでしょうか?
これは、プロジェクトのビルドに使うイメージとDockerコンテナの作成に使うイメージを分けるベストプラクティスに沿った、複数ステップのDockerイメージビルドワークフローです。Node.jsアプリケーションをDockerでコンテナ化するための10のベストプラクティスに従っています。
コンテナ内でMCPサーバーのプロジェクトファイルを配置するディレクトリとして、
/appを定義しますDockerコンテナの実行時には、
/app/dist/bin/cli.cjsファイルをnodeランタイムの引数として実行します。MCPサーバーのエントリーポイントに合わせて、index.jsやserver.jsなどに変更してください。
次は何をすればよいでしょうか?Dockerfileができたので、ローカルでビルドして実行し、正しく動作することを確認できます。Dockerイメージをビルドする方法は次のとおりです(my-mcp-serverは、このDockerイメージに付けたいタグ名に変更できます)。
docker build -t my-mcp-server .プロジェクトのルートディレクトリで上記のコマンドを実行してください。そこにDockerfileを配置すると、新しいDockerイメージがビルドされます。
DockerイメージからMCPサーバーを実行するには、次のコマンドを使います。
docker run -i --rm --init -e DOCKER_CONTAINER=true my-mcp-server先ほどビルドしたmy-mcp-serverのDockerイメージから新しいコンテナを実行します。次に-iと--rmの引数を指定し、STDIOに接続する対話型プロセスとしてDockerに実行させます。コンテナを停止すると、自動的に削除されるため、後片付けも簡単です。
ユーザーはDocker経由でMCPサーバーをどのように利用するのでしょうか?
MCPサーバーを用意できました。MCPクライアントやホストアプリケーションからは、どのように利用するのでしょうか?Pythonのuxやpip、Node.jsのnpxを使わない場合、実行コマンドをどう設定すればよいのでしょうか?
Dockerが利用可能である必要があります。多くの開発者はDockerか、PodmanのようなDocker互換の代替ツールを使っているでしょう。Dockerを利用できる場合は、MCPサーバーを次のように設定できます。
{
"mcpServers": {
"my-mcp-server": {
"command": "docker",
"env": {},
"args": [
"run",
"-i",
"--rm",
"my-mcp-server"
]
}
}あと少しです!これは完全な例ではないため、MCPユーザーはそのままでは使えません。Dockerコマンドでmy-mcp-serverを指定していることに気づいたでしょうか。Dockerはこのイメージをどこから取得するのでしょうか?そもそも、そこに公開したのでしょうか?
そうです。ここが抜けていました。Dockerfileを作成し、Dockerイメージをローカルでビルドしましたが、どこにも公開していません。GitHub上でソフトウェアを開発する人が簡単に使えるよう、DockerイメージをホストできるGitHub Packagesレジストリに公開します。実際、公式のGitHub MCPサーバーも同じ方法を採用しています。
DockerイメージをビルドしてGitHub Packagesに公開するGitHub Actionsワークフローを作成する
まず、Dockerイメージを作成するGitHub Actionsワークフローを作成します。CIワークフローには次のステップを含めます。
Dockerイメージをビルドする
DockerイメージをGitHub Packagesに公開する
Dockerイメージに署名する
以下は、プロジェクトのルートにある次のディレクトリに作成する、ワークフローファイルの全体です。.github/workflows/docker-publish-to-github.yml
このファイルを実行して保存する前に、IMAGE_NAME環境変数を変更し、例として指定しているmy-mcp-serverではなく、ご自身のDockerイメージ名を設定してください。
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: trueまた、上記のDockerイメージをビルドするGitHub Actionsワークフローファイルでは、ブランチ名にデフォルトブランチ名のmainを使用しています。
次に、GitHub Actionsのランナーに書き込み権限を付与します。リポジトリのSettings -> Actions -> Generalに移動し、次のように読み取りと書き込みの権限を有効にしてください。

MCPを使ってさらに開発を進めませんか?
次に何をすればよいかお探しですか?MCPサーバーの理解とセキュリティ対策に役立つリソースをいくつかご紹介します。
プロンプトインジェクションからその他のセキュリティ脆弱性まで、MCPセキュリティ — 過去の脅威が再び注目される理由