🚀

mise と Docker で始める開発環境構築 2025年10月版

に公開

はじめに

プログラミング学習を始めたばかりの方が、最初に出会う大きな壁、それが「開発環境の構築」です。

「このチュートリアル通りにやったのに動かない...」
「自分のパソコンでは動くのに、友達のパソコンではエラーが出る...」

このような経験はありませんか? プログラミング言語やツールには多くのバージョンがあり、さらにOS(Windows, macOS, Linux)の違いも相まって、全員が同じ環境を揃えるのはきわめて困難です。

この記事では、そんな開発環境の悩みを解決する、2025年10月時点でのモダンな解決策として「mise」と「Docker」を紹介します。

プログラミング初心者の方こそ、最初にこの2つのツールを学ぶことを強くお勧めします。なぜなら、これらを使いこなせれば、特定の言語に縛られず、クリーンで再現性の高い開発環境を驚くほど簡単に手に入れられるようになるからです。

この記事を読み終える頃には、あなたは次のことを理解しているでしょう。

  • なぜ miseDocker が現代の開発に必須なのか
  • mise を使ったスマートなツールバージョン管理の方法
  • Docker を使ったコンテナによる環境分離の威力
  • 実際に miseDocker を使った開発環境を体験する方法

さあ、未来の開発スタイルを一緒に体験してみましょう!

なぜ「mise」と「Docker」なのか?

数あるツールの中で、なぜこの2つが特に重要なのでしょうか。この2つのツールの管理範囲は次のとおりです。

  • mise: 開発者が使う手元の CLI ツール(Go コンパイラ、Node.js ランタイムなど)のバージョンを管理
  • Docker: アプリケーションが実行される環境(ライブラリ、データベースなど)を管理

それぞれの役割の詳細と、組み合わせることで得られるメリットを見ていきましょう。

mise: プロジェクトごとに必要なツールの管理

mise は、プログラミング言語や各種コマンドラインツール(CLIツール)のバージョンを管理するためのツールです。

かつては開発者が使用するプログラミング言語の種類は限定的だったため、Pythonのバージョン管理には pyenv、Node.jsには nvm、Rubyには rbenv など、言語ごとにバージョン管理ツールを使い分けるのが一般的でした。

しかし、最近は IaC(Infrastructure as Code)や AI ツールの普及もあって、ひとつのプログラミング言語だけで開発をすることは少なくなっています。そのため、開発担当レベルでも複数のプログラミング言語のバージョンを管理する機会が増えています。しかし、言語ごとに専用のバージョン管理ツールを使うと管理が煩雑になります。

mise は、これらのツールを一つに統合し、noderubypythongojava など、多様なツールのバージョンを一つの設定ファイルで管理できます。

mise.toml (設定ファイルの例)
[tools]
go = "1.24.5"
node = "20.10.0"
python = "3.12"

この mise.toml というファイルをプロジェクトのフォルダに置いておくだけで、そのフォルダに入った瞬間に、指定されたバージョンのツールが自動的に使えるようになります。

mise の設定ファイル

mise は、ツールがどのバージョンの設定を読み込むかについて、非常に柔軟で強力な仕組みを持っています。初心者のうちは、「プロジェクトのフォルダに置いた設定が最優先される」と覚えておけば大丈夫です。

mise の設定ファイルでは、ツールバージョンだけでなく、プラグイン設定、エイリアス、環境変数なども設定できます。ツールのバージョンは通常、[tools]セクションなどで指定されます。詳細は公式サイトの https://mise.jdx.dev/configuration.html を参照してください。

mise は設定ファイルを以下の優先度で読み込みます(番号が小さいほど優先度が高いです)。

  1. カレントディレクトリの設定 (mise.toml): 今作業しているディレクトリ、またはその親ディレクトリを遡った先にある mise.toml の設定が最優先されます。プロジェクトごとに異なるツールバージョンを使いたい場合に利用します。
  2. グローバルな設定 (~/.config/mise/config.toml): これは、あなたのホームディレクトリ直下に置かれる設定ファイルです。どのプロジェクトにも属さない環境(例:OSに共通で使いたい特定のCLIツールなど)のデフォルトバージョンを設定するために使われます。

このように、miseプロジェクト固有の設定を最優先し、それがない場合にグローバルな設定を適用するという明確なルールで動きます。これにより、あなたの PC 全体での設定と、特定のプロジェクトでの設定が混ざってしまう心配がなくなります。

なお、注意点としては、ツール指定には、mise.toml だけでなく .tool-versions というファイルが使われることもあります。詳細は公式サイトの https://mise.jdx.dev/dev-tools/#how-it-works を参照してください。

.tool-versions は、mise が互換性を持つ asdf-vmhttps://asdf-vm.com/)によってサポートされているファイルです。シンプルにツール名とバージョンを列挙する形式で、主にツールのバージョン指定に使用されます。

mise を使用するメリットは次のとおりです。

メリット 説明
単一ツールで完結 様々な言語・ツールのバージョン管理を mise だけで行える。
プロジェクトごとの自動切換え cd コマンドでディレクトリを移動するだけで、必要なツールのバージョンが自動で有効になる
環境差異の解消 チームメンバー全員が同じ mise.toml を共有することで、ツールのバージョン違いによる問題を根本からなくせる。

Docker: どこでも同じ実行環境を提供

Docker は、アプリケーションを実行するための OS レベルの環境(カーネル以外の OS のソフトウェア、ミドルウェア、ライブラリなど)を「コンテナ」という独立した環境の中に丸ごとパッケージングする技術です。

コンテナ技術は、アプリケーションをホスト OS から隔離して実行する技術です。仮想マシン(Virtual Machine、VM)とは異なり、コンテナはホスト OS のカーネルというものを共有するため、仮想マシンよりもはるかに起動が速く、リソース消費も少ないのが特徴です。

Dockerfile という設計図を書くことで、誰でも、どこでも、Docker 環境があれば、全く同じ環境を再現できます。

Docker のメリットは次のとおりです。

メリット 説明
完全な環境の再現性 Dockerfile さえあれば、開発環境から本番環境まで、全く同じ環境を簡単に定義可能
ローカルマシンをクリーンに保持 データベースや Web サーバーなどをコンテナとして分離できるため、PC への直接インストールや設定が不要
ポータビリティ(可搬性) 一度コンテナとしてパッケージ化すれば、そのアプリは「どこの Docker 環境でも動く」というポータビリティの確保

mise + Docker: 最強の組み合わせ

この2つを組み合わせるメリットは次の通りです。

メリット 説明
クリーンな開発環境 コンテナ(Docker)で OS レベルの依存関係を隔離し、ツールマネージャmise)で言語バージョンを隔離・管理することで、ローカルマシンをクリーンに保持
高い再現性 Dockerfilemise.toml を共有することで、ローカル、チーム、CI/CD、本番環境すべてで一貫した環境を維持可能
学習コストの削減 環境構築の複雑さから解放され、異なるプロジェクト間でも環境設定を気にすることなく、すぐにコード作成という本来のタスクに集中可能

これらのメリットは、開発環境のセットアッププロジェクトのポータビリティという二つの大きな課題を解決します。この管理により、「ローカルでは動いたのに、CI/CD で動かない」といった環境差異によるバグを極小化できます。

また、新しいチームメンバーがプロジェクトに参加する際、「VS Code と docker と mise のセットアップが済んでいる開発マシンで、リポジトリをクローンして、docker compose up を実行するだけ」という極めてシンプルな手順で開発を開始できるようになり、オンボーディングの時間とコストを大幅に削減できます。

今回紹介する dvc-mise のように mise が使える開発コンテナを用意してある場合は、「VS Code と docker のセットアップが済んでいる開発マシンで、リポジトリをクローンして、VS Code で開発コンテナを実行するだけ」となり、mise のインストールさえ必要がありません。

dvc-mise で mise と Docker を体験しよう

理論を学んだら、次は実践です。しかし、Dockerや、Dockerと連携するVS Codeの「Dev Containers」機能をいきなりゼロから設定するのは少しハードルが高いかもしれません。

そこで、Dev Containers と mise の利点を組み合わせた、モダンな開発環境をすぐに体験できるプロジェクト「dvc-mise」を次のリポジトリに用意しました!

このリポジトリ内の https://github.com/hiro345g/dcfwd/tree/dvc-mise/dvc-mise にサンプルコードがあります。

dvc-mise は、様々なプログラミング言語のサンプルプロジェクトを含んだ「開発環境のお試しセット」です。これを使えば、面倒な初期設定なしに、miseDocker の便利さをすぐに実感できます。詳細は dvc-msie/README.md にあるので、そちらも参照してから作業するとスムーズになるはずです。

なお、開発環境として mise + Docker を組み合わせる場合、Docker で開発コンテナを用意して、そこへ mise をインストールしたものが最強です。dvc-mise には、その環境を用意してあります。

dvc-mise のダウンロードと準備

まずは、dvc-mise プロジェクトを手元に用意しましょう。一番簡単な方法は次の URL 経由で入手できるアーカイブファイルをダウンロードして展開したものから dvc-mise フォルダを取り出すことです。

Web ブラウザで URL を開き、「Code」をクリックして表示される「Download ZIP」から dvc-mise.zip ファイルをダウンロードします。

ダウンロードした dvc-mise.zip を展開すると dcfwd-dvc-mise フォルダが作成されます。その中の dvc-mise フォルダが必要なものです。これを /workspacesC:\workspaces など好きな場所にフォルダを作って、そこへ dvc-mise フォルダを置きます。

これ以降、この dvc-mise フォルダを ${PROJECT_DIR} と表記することにし、ここではパスを /workspaces/dvc-mise にしたとして、説明します。

また、この後に説明するコマンドは、ターミナルで cd コマンドを使って ${PROJECT_DIR} をカレントにして実行するとします。

cd $PROJECT_DIR
ターミナルで準備する場合

ダウンロードと準備についてターミナル上で準備することもできます。

ここではターミナルを開いて作業を開始します。Windows の場合は Git Bash で作業すると良いでしょう。

/workspaces のパスが使えない環境の場合は ~/workspaces を指定するように読み替えて作業すれば良いです。

ここでは、サンプルコードを置くパスは、開発コンテナの中で使うパスと一致させておくと作業しやすいだろうと考えて、そうしています。とはいえ、開発コンテナの中に入ってしまえば /workspaces/dvc-mise となるので、それほどこだわらなくても良いです。

# /workspaces フォルダの作成
# (~/workspaces を使う場合は `mkdir ~/workspaces`)
sudo mkdir /workspaces
# /workspaces フォルダの所有者をユーザに変更
# ~/workspaces を使う場合は実行する必要なし
sudo chown $(id -u):$(id -g) /workspaces

dvc-mise フォルダの用意。

# /workspaces フォルダをカレントにして作業
# (~/workspaces を使う場合は `cd ~/workspaces`)
cd /workspaces
# サンプルコードを含むアーカイブファイルのダウンロード
curl -L -O https://github.com/hiro345g/dcfwd/archive/refs/heads/dvc-mise.zip
# ダウンロードしたファイルを展開
unzip dvc-mise.zip 
# dvc-mise フォルダを /workspaces/dvc-mise へ移動
mv dcfwd-dvc-mise/dvc-mise .
# 不要となったファイルを削除
rm -fr dcfwd-dvc-mise/ dvc-mise.zip
# この後、作業するためのフォルダ(プロジェクトのルート)へ移動
cd dvc-mise
# PROJECT_DIR 環境変数へプロジェクトのルートパスを設定
PROJECT_DIR=$(pwd)

dvc-mise を使うときに必要なもの

お使いの PC に VS Code がインストールされている必要があります。

また、次の VS Code 拡張機能もインストールしておいてください。

Docker と Git も必要です。個人の環境で Windows を使っているなら、次のものを用意するのが手軽です。

  • Git for Windows
  • Docker Desktop for Windows

Windows では、管理者モードで起動したターミナルで次のコマンドを実行すれば、これらをインストールできます。

winget install -e --id Git.Git
winget install -e --id Docker.DockerDesktop

イメージのビルド

このプロジェクトを利用するには、まず開発コンテナイメージをビルドする必要があります。build-base-image ディレクトリにある build.sh スクリプトを使用してビルドすることができます。

bash ./build-base-image/build.sh

少し時間がかかりますから、気長に待ちましょう。また、内部的に Ruby や PHP をソースコードからビルドするため、高負荷になります。

16GB メモリを搭載した CPU が i5 の Ubuntu Desktop マシンでも、VS Code や Chrome を起動しながらビルドするとメモリ不足でプロセスが落ちてしまうことがありました。その場合は、ビルド対象外とするために、mise.tomlrubyphp の行頭に ## をつけて(##ruby##php のようにする)からビルドします。

.gemini フォルダの用意

今回用意した開発コンテナでは Gemini CLI をインストールして使えるようにしてあります。その設定用フォルダは Docker ホストマシンで用意する設定となっているので、用意します。

Gemini CLI を使っている場合は ~/.gemini フォルダがあるはずなので、それをコピーします。使っていない場合は空の .gemini フォルダを作成します。

そのためのスクリプト init.sh を用意してあるので、次のように実行します。

bash ./script/init.sh

開発コンテナの起動と利用

イメージのビルドと .gemini フォルダの用意ができたら、開発コンテナを起動して使ってみましょう。

VS Code を起動し、「ファイル」メニューから「フォルダを開く...」を選択して、先ほど用意した dvc-mise フォルダを開きます。

もしくはターミナルで次のコマンドを実行します。

cd $PROJECT_DIR
code .

フォルダを開いた VS Code の画面が表示されると、VS Code の右下に「フォルダーには開発コンテナー構成ファイルが含まれています。コンテナーで再度開きますか?」という通知が表示されます。「コンテナーで再度開く」ボタンをクリックしてください。

もし通知が表示されない場合は、F1 キー(または Ctrl+Shift+P)でコマンドパレットを開き、Dev Containers: Reopen in Container と入力して実行します。

これだけで、dvc-mise 用に設定された Docker の開発コンテナが起動し、その中で VS Code が再起動します。VS Code の左下が「開発コンテナー: dvc-mise」のようになれば成功です。

このコンテナの中には、開発に必要なツールと mise がすでにインストールされています。あなたのローカル PC の環境については変更がされていなくて、クリーンな状態が保持されています。これが Dev Containers の力です!

mise を使ってみる

開発コンテナに入ったら、さっそく mise の威力を体験してみましょう。

開発コンテナをアタッチした VS Code のメニューから「ターミナル」-「新しいターミナル」を選択し、コンテナ内のターミナルを開きます。

まずは mise がインストールされていることを確認します。

mise --version

実行例は次のようになります。

vscode ➜ /workspaces/dvc-mise $ mise --version
              _                                        __              
   ____ ___  (_)_______        ___  ____        ____  / /___ _________
  / __ `__ \/ / ___/ _ \______/ _ \/ __ \______/ __ \/ / __ `/ ___/ _ \
 / / / / / / (__  )  __/_____/  __/ / / /_____/ /_/ / / /_/ / /__/  __/
/_/ /_/ /_/_/____/\___/      \___/_/ /_/     / .___/_/\__,_/\___/\___/
                                            /_/                 by @jdx
2025.10.16 linux-x64 (2025-10-23)

開発コンテナ内の /workspaces/dvc-mise フォルダは Docker ホストの ${PROJECT_DIR}(記事内では /workspaces/dvc-mise とした) フォルダをバインドマウントしているため、そこにある各プログラミング言語のサンプルプロジェクトが、そのまま使えるようになっています。

ls コマンドで実行すると次のようになります。

vscode ➜ /workspaces/dvc-mise $ ls -1 /workspaces/dvc-mise/
build-base-image
goapp001
javaapp001
mise.toml
nodeapp001
phpapp001
pyapp001
README.md
rubyapp001
script

mise の最も強力な機能の一つが、ディレクトリを移動するだけでツールのバージョンが自動的に切り替わることです。実際に試してみましょう。

  1. /workspaces/dvc-mise をカレントにして、Go と Python のバージョンを確認
  2. 新しい NewProject プロジェクトと mise.toml を作成し、そこへ移動して Go と Python のバージョンを確認

まず、mise.toml の Go と Python のバージョンを確認し、それから実際に使われるバージョンの確認をします。

cd /workspaces/dvc-mise
cat mise.toml | grep -e "go" -e "python"
go version
python --version

実行例は次のようになります。/workspaces/dvc-mise/mise.toml の指定について、go が 1.24.9、python が 3.12.12 で、実際に実行したコマンドの結果と一致しています。

vscode ➜ /workspaces/dvc-mise $ cd /workspaces/dvc-mise/
vscode ➜ /workspaces/dvc-mise $ cat mise.toml | grep -e "go" -e "python"
go = "1.24.9"
python = "3.12.12"
vscode ➜ /workspaces/dvc-mise $ go version
go version go1.24.9 linux/amd64
vscode ➜ /workspaces/dvc-mise $ python --version
Python 3.12.12

次に、新しい NewProject プロジェクトと mise.toml を作成します。

mkdir /workspaces/dvc-mise/NewProject
cat << EOS > /workspaces/dvc-mise/NewProject/mise.toml
[tools]
go = "1.25.3"
python = "3.13.9"
EOS

準備ができたら、NewProject へ移動します。

cd /workspaces/dvc-mise/NewProject

すぐに Go と Python のバージョンを確認したいところですが、実行する前に準備が必要です。

まず、mise trust を実行してフォルダにあるファイルについて mise が信頼する設定をします。

mise trust

これを実行しないと、フォルダを信頼して mise を実行するかどうかのプロンプトが表示されます。

vscode ➜ /workspaces/dvc-mise/NewProject $ go version
mise config files in /workspaces/dvc-mise/NewProject are not trusted. Trust them?


   Yes     No     All  

←/→ toggle • y/n/a/enter submit

このプロンプトでは矢印キーで選択肢の指定ができるので、Yes を選択して Enter を入力すると、フォルダを mise で信頼できます。これは、mise trust を実行するのと同じことになります。

次に、mise install を実行して必要なバージョンのツールをインストールします。

mise install

dvc-mise の開発コンテナでは、必要なバージョンのツールがインストールされていない場合、次のような警告が表示されるように設定してあります。デフォルトの設定では、自動で必要なバージョンのツールがインストールされます。

vscode ➜ /workspaces/dvc-mise/NewProject $ go version
mise ERROR Tool not installed for shim: go
Missing tool version: core:go@1.25.3
Install all missing tools with: mise install
mise ERROR Run with --verbose or MISE_VERBOSE=1 for more information

準備ができたら、Go と Python のバージョンを確認します。

go version
python --version

一連のコマンドを実行すると、次のようになります。

vscode ➜ /workspaces/dvc-mise/NewProject $ mise trust
mise trusted /workspaces/dvc-mise/NewProject
vscode ➜ /workspaces/dvc-mise/NewProject $ mise install
mise hint use multiple versions simultaneously with mise use python@3.12 python@3.11
mise go@1.25.3  install                                                                                                    ⠁  0s
mise hint installing precompiled python from astral-sh/python-build-standalone
if you experience issues with this python (e.g.: running poetry), switch to python-build by running mise settings python.compile=1
vscode ➜ /workspaces/dvc-mise/NewProject $ go version
go version go1.25.3 linux/amd64
vscode ➜ /workspaces/dvc-mise/NewProject $ python --version
Python 3.13.9

NewProject/mise.toml で指定したバージョンのものが使われていることがわかります。再度 /workspaces/dvc-mise フォルダへ移動して Go と Python のバージョンを確認すると、自動で /workspaces/dvc-mise/mise.toml に指定したバージョンのものが使われることがわかります。

このように、mise を使うと、各フォルダにある mise.toml ファイルを使って、使用するツールのバージョンの自動切り替えができるようになります。

仕組みとしては、mise はカレントディレクトリにある mise.toml ファイルを読み込み、指定されたバージョンのツールが使われるように、環境変数の PATH を自動で設定してくれます。これにより、あなたは「このプロジェクトではどのバージョンの Python を使っていたかな?」といったことについて悩む必要がなくなります。

mise のインストールについて

mise は環境が用意されていれば、手軽に使えて便利なのですが、実際に利用するツールによっては注意が必要です。

ここで紹介している dvc-mise の開発コンテナにおける mise のインストールについては、script/install-mise.sh.devcontainer/Dockerfile を参照するとわかります。

install-mise.sh は、mise の公式のインストール手順をスクリプト化したものになります。ここまでは簡単です。

script/install-mise.sh
#!/bin/sh
# shellcheck disable=SC2016,SC2088

curl https://mise.run | sh

cat << EOS >> ~/.bashrc
if [[ "\$TERM_PROGRAM" == "vscode" ]]; then
  eval "\$(~/.local/bin/mise activate bash --shims)"
else
  eval "\$(~/.local/bin/mise activate bash)"
fi
EOS

echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc
cat << EOS >> ~/.zprofile
if [[ "\$TERM_PROGRAM" == "vscode" ]]; then
  eval "\$(~/.local/bin/mise activate zsh --shims)"
elif; then
  eval "\$(~/.local/bin/mise activate zsh)"
fi
EOS

Dockerfile では、root ユーザーでツールのビルドに必要なパッケージのインストールをしてから、vscodemise install コマンドを使ってデフォルトで使用するツールをインストールしています。

FROM dvc-mise:base
# 略
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get -y install \
      build-essential autoconf \
      libssl-dev libyaml-dev zlib1g-dev libffi-dev libgmp-dev rustc \
  && DEBIAN_FRONTEND=noninteractive apt-get install -y locate \
      autoconf bison build-essential \
      curl gettext git libgd-dev libcurl4-openssl-dev libedit-dev \
      libicu-dev libjpeg-dev libmariadb-dev-compat libmariadb-dev libonig-dev \
      libpng-dev libpq-dev libreadline-dev libsqlite3-dev libssl-dev libxml2-dev \
      libzip-dev openssl pkg-config re2c zlib1g-dev \
  && apt-get -y autoremove \
  && apt-get -y clean \
  && rm -rf /var/cache/apt /var/lib/apt/lists \
  && /usr/bin/updatedb

USER vscode

# vscode ユーザーで mise インストール
# Ruby と PHP については、処理が重くなるので一時的に除外
RUN sed -i 's/php =/#php =/' /home/vscode/.config/mise/config.toml
RUN sed -i 's/ruby =/#ruby =/' /home/vscode/.config/mise/config.toml
RUN bash -c '\
  eval "$(~/.local/bin/mise activate bash)"; \
  mise install -y --jobs 2; \
'

# gemini-cli を vscode ユーザーでグローバルインストール
RUN bash -c '\
  eval "$(~/.local/bin/mise activate bash)"; \
  npm install -g @google/gemini-cli; \
  mkdir /home/vscode/.gemini; \
'

# locate 用 DB のアップデート
RUN sudo /usr/bin/updatedb

# 作業用に workspace/dvc-mise の用意
RUN sudo mkdir -p /workspaces/dvc-mise && sudo chown -R vscode:vscode /workspaces/dvc-mise
WORKDIR /workspaces/dvc-mise

# Ruby
RUN sed -i 's/#ruby =/ruby =/' /home/vscode/.config/mise/config.toml
RUN bash -c '\
  eval "$(~/.local/bin/mise activate bash)"; \
  mise install -y; \
'

# PHP
RUN sed -i 's/#php =/php =/' /home/vscode/.config/mise/config.toml
RUN bash -c '\
  eval "$(~/.local/bin/mise activate bash)"; \
  mise install -y; \
'

# mise trust WORKDIR and set auto_install=false
RUN bash -c '\
  eval "$(~/.local/bin/mise activate bash)"; \
  mise trust; \
  mise settings auto_install=false; \
'

こちらについては、Docker イメージ作成についての知識がそれなりに必要となります。

また、mise が対応しているツールであっても、簡単にインストールができないものがいくつかあります。dvc-mise においては rubyphp が該当します。

これらについては、Dockerfile 内で mise install を実行する前にビルドに必要なパッケージを追加しています。

Ruby のビルドに必要なパッケージは https://mise.jdx.dev/lang/ruby.html を確認してインストールするようにしました。

PHP のビルドに必要なパッケージは https://github.com/asdf-community/asdf-php から、https://github.com/asdf-community/asdf-php/blob/master/.github/workflows/workflow.yml を参照してインストールするようにしました。ただし、MySQL のライブラリについては Ubuntu の標準が MariaDB なので、そちらへ置き換えてあります。

こういったパッケージの追加が必要なものが出てくると、それについての知識が必要になります。

とはいえ、困った場合は、dvc-mise のように docker コマンドが使える開発コンテナで Ubuntu をベースにしてある場合は、mise ではなく APT パッケージか Docker でツールを管理するようにすれば良いので、なんとかなります。

Docker を使ってみる

mise コマンドではツールのバージョン管理はできますが、Web サーバや DB サーバのようなソフトウェアのバージョン管理まではできません。これらのソフトウェアについても、開発時に使用するバージョンの管理が必要なので、それについては Docker が使われます。

今回、用意してあるサンプルコードは単純なコンソールアプリなので、関連ソフトウェアのバージョンを管理することはありません。そのため、具体的に役に立つ例を示すことができませんが、Docker を知らない人のために docker コマンドを簡単に使ってみる程度のことは紹介したいところです。

また、開発コンテナの中で Docker を使ってみたことがない人もいるかと思います。dvc-mise のように、docker-outside-of-docker フィーチャーを使うと、ホスト OS で動作する dockerd と開発コンテナが通信して、コンテナ操作ができるようになります。これに興味を持つ人もいるのではないでしょうか。

docker-outside-of-docker フィーチャーについて

dvc-mise の開発コンテナでは dvc-mise/build-base-image/devcontainer.jsondocker-outside-of-docker フィーチャーを指定することで、docker コマンドが実行できるようにしてあります。

dvc-mise/build-base-image/devcontainer.json
{
  "name": "dvc-mise-base",
  "image": "mcr.microsoft.com/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/devcontainers/features/common-utils:2": {},
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/docker-outside-of-docker:1.6.5": {}
  }
}

それでは、Docker を使ってみましょう。ここでは、mise.toml で指定してある go のバージョンが 1.24.9 なので、これよりも新しい go のバージョンが動作するコンテナを用意して、現在のプログラムが実行可能か確認してみましょう。

VS Code と Docker Compose を使うと楽に作業ができるのですが、開発コンテナ内で使う場合はバインドマウントを基本的に使わないようにするのが良く、慣れていないと難しいです。そのため、ここでは開発コンテナで使っても副作用が起きない機能に絞って、docker コマンドを使って作業してみます。

Docker イメージとしては golang:1.25.3 を使うことにして、go version を実行します。ここでは、コンテナ終了時に自動でクリーンアップがされるように --rm オプションをつけます。

docker container run --rm golang:1.25.3 go version

実行例は次のようになり、たしかに go の 1.25.3 が使われることがわかります。

vscode ➜ /workspaces/dvc-mise $ docker container run --rm golang:1.25.3 go version
go version go1.25.3 linux/amd64

次に、コンテナで作業をするために docker container run-d オプションをつけてデタッチモードで起動します。

アタッチするにはコンテナ名があった方が使いやすいので --namegolang-1.25.3 というコンテナ名をつけます。

実行するコマンドは bash とします。bash のような対話的なプログラムを実行する場合は、疑似 tty の割当(-t)と STDIN をオープン(-i)が必要なので、これらを一緒に指定する -it オプションもつけます。

コンテナを起動したら、docker container ls で実行中のコンテナの一覧を表示し、起動の確認をします。

docker container run -d --rm -it --name golang-1.25.3 golang:1.25.3 bash
docker container ls

実行例は次のとおりです。

vscode ➜ /workspaces/dvc-mise $ docker container run --rm -it golang:1.25.3 go version
go version go1.25.3 linux/amd64
vscode ➜ /workspaces/dvc-mise $ docker container run -d --rm -it --name golang-1.25.3 golang:1.25.3 bash
[1] 5153
vscode ➜ /workspaces/dvc-mise $ docker container ls
CONTAINER ID   IMAGE                       COMMAND () NAMES
ed50dac9ead2   golang:1.25.3               "bash"  () golang-1.25.3 
a7857343455a   vsc-dvc-mise-fc(略)-uid   "/bin/sh() dvc-mise

コンテナの一覧に、golang-1.25.3 のものがあることがわかります。

次に、コンテナ内で作業するために docker container cpgoapp001 フォルダをコンテナ内の /app へコピーしてから、docker attatch コマンドでコンテナへアタッチします。

docker container cp goapp001 golang-1.25.3:/app
docker attach golang-1.25.3

実行例は次のようになります。

vscode ➜ /workspaces/dvc-mise $ docker container cp goapp001 golang-1.25.3:/app
Successfully copied 5.63kB to golang-1.25.3:/app
vscode ➜ /workspaces/dvc-mise $ docker attach golang-1.25.3
root@4c90c28921a8:/go#

コピーが成功すると Successfully copied というメッセージが表示され、

コンテナへのアタッチが成功すると、root@4c90c28921a8:/go# といったプロンプトが表示されます。

コンテナにアタッチできたら、/app をカレントにして、Go アプリを実行してみましょう。単純な実行なら go run を使います。

cd /app
go run main.go

実行例は次のようになり、Hello, world! と表示されていたら成功です。

root@4c90c28921a8:/go# cd /app
root@4c90c28921a8:/app# go run main.go
Hello, world!

次に、dvc-mise/README.md に説明してある go-task を使う手順でプログラムを動作させてみます。go installgo-tasktask コマンドをインストールしてから task start でプログラム実行です。

go install github.com/go-task/task/v3/cmd/task@latest
task start

実行例は次のようになります。必要なファイルのダウンロードとインストールがされ、task: [start] のメッセージ行の後に、Hello, world! と表示されていたら成功です。

root@4c90c28921a8:/app# go install github.com/go-task/task/v3/cmd/task@latest
(略)
go: downloading github.com/cloudflare/circl v1.6.1
go: downloading github.com/pierrec/lz4/v4 v4.1.22
root@4c90c28921a8:/app# task start
task: [start] go run main.go
Hello, world!

コンテナを終了するには起動時に実行した bash コマンドを終了すれば良いので exit を実行します。

ちなみに、コンテナを終了せずにデタッチするには Ctrl + p(Ctrl と p を同時に入力)を入力後に Ctrl + q を連続して入力します。コンテナを強制終了したい場合は Ctrl + d を入力します。

このように、Docker を使うことで、新しいバージョンの gogoapp001 のプログラムを動かすことができました。

新しいバージョンの go コマンドを使うだけなら mise でも対応できますが、Docker を使うと、今回のようにコードを単にコピーして動作確認後に環境全体を削除することができます。これは、もとの環境をクリーンに保持したまま、別の環境で同じような作業ができるということになるのです。

各プロジェクトについて

ここで用意してある各プロジェクトについて、簡単な動作方法を説明します。用意してあるプログラムは Hello world のような文字列を表示するだけの単純なコンソールアプリです。

ここでは、タスクランナーツールなども含めて、簡単なプロジェクト風にしたかったので、単にメッセージ表示するだけのプログラムにしては大袈裟な構成となっています。

goapp001 プロジェクト

goapp001 アプリケーションを実行するには、/workspaces/dvc-mise/goapp001mise コマンドが使えるように mise trust を実行します(最初のときだけ必要)。

それから、task コマンドが使えるようにインストールします(最初のときだけ必要)。

具体的なコマンドは次のようになります。

cd /workspaces/dvc-mise/goapp001
mise trust
go install github.com/go-task/task/v3/cmd/task@latest

それから、task コマンドを実行します。start タスクは Taskfile.yml に定義してあります。

task start

アプリケーションを実行すると Hello, world! と表示されます。

実行例

$ task start
task: [start] go run main.go
Hello, world!

javaapp001 プロジェクト

javaapp001 アプリケーションを実行するには、開発コンテナ内で以下のコマンドを実行します。

cd /workspaces/dvc-mise/javaapp001
./gradlew run

アプリケーションを実行すると Hello World! と表示されます。

実行例

$ ./gradlew run
(略)
Starting a Gradle Daemon (subsequent builds will be faster)
Calculating task graph as no cached configuration is available for tasks: run

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 32s
2 actionable tasks: 2 executed
Configuration cache entry stored.

nodeapp001 プロジェクト

nodeapp001 アプリケーションを実行するには、開発コンテナ内で以下のコマンドを実行します。

cd /workspaces/dvc-mise/nodeapp001
npm start

アプリケーションを実行すると Hello, world! と表示されます。

実行例

$ npm start

> nodeapp001@1.0.0 start
> node index.js

Hello, world!

phpapp001 プロジェクト

phpapp001 アプリケーションを実行するには、開発コンテナ内で以下のコマンドを実行します。

cd /workspaces/dvc-mise/phpapp001
composer install
composer run start

アプリケーションを実行すると Hello, PHP Console App! と表示されます。

実行例

$ composer install
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Nothing to install, update or remove
Generating autoload files
$ composer run start
> php main.php
Hello, PHP Console App!

pyapp001 プロジェクト

goapp001 アプリケーションを実行するには、/workspaces/dvc-mise/pyapp001mise コマンドが使えるように mise trust を実行します(最初のときだけ必要)。

具体的なコマンドは次のようになります。

cd /workspaces/dvc-mise/pyapp001
mise trust

アプリケーションを実行するには mise run を使います。start タスクは mise.toml に定義してあります。

mise run start

mise run start は、仮想環境を初期化し(既に存在する場合はスキップ)、仮想環境をアクティブにしてから、アプリを実行します。なお、mise.toml に指定されている uv コマンドがインストールされていない場合は、インストールします。

アプリケーションを実行すると Hello, world! と表示されます。

実行例

$ mise run start

[init] $ [ -d .venv ] || uv venv
[start] $ . .venv/bin/activate && python main.py
Hello, world!
Finished in 23.9ms

rubyapp001 プロジェクト

rubyapp001 アプリケーションを実行するには、開発コンテナ内で以下のコマンドを実行します。

cd /workspaces/dvc-mise/rubyapp001
bundle install
bundle exec ruby main.rb

アプリケーションを実行すると Hello, world! と表示されます。

実行例

$ bundle install
Bundle complete! 1 Gemfile dependency, 1 gem now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
$ bundle exec ruby main.rb
Hello, world!

まとめ

本記事では、プログラミング初学者こそ学ぶべき、現代的な開発環境構築ツールとして「mise」と「Docker」を紹介しました。

ソフトウェア 説明
mise mise.toml ファイルで、プロジェクトごとに使うプログラミング言語やツールのバージョンをスマートに管理可能
Docker Dockerfilecompose.yaml で、アプリケーションの実行環境そのものをコード化し、Docker さえあれば、誰でもどこでも同じ環境を再現可能

そして、この2つの強力なツールをすぐに体験できる dvc-mise プロジェクトを紹介しました。

かつては、各プロジェクトに応じた開発環境の構築は、多くの開発者を悩ませる複雑な作業でした。しかし、miseDocker が登場した今、その悩みは過去のものとなりつつあります。

これからプログラミングを本格的に学んでいく皆さん、ぜひ dvc-mise で示したような開発環境を構築して、このストレスフリーでモダンな開発スタイルを体験してみてください。環境構築で迷う時間を減らし、もっと多くの時間を創造的なコーディングに使いましょう!

Discussion