Vagrantは仮想マシンを作るためのソフトウェアだと思っていました。 いつのまにか、VagrantでDockerをサポートしていました。 Vagrantは仮想マシンを作成するのにしか使っていませんでした。
ドキュメントを見るといくつかの使い方の説明があります。
https://developer.hashicorp.com/vagrant/docs/providers/docker/basics
まずは一番基本的なDockerコンテナを動かすやつを試してみます。イメージは何でもいいですが、Ubuntuのイメージを使いましょう。
$ cat Vagrantfile Vagrant.configure("2") do |config| config.vm.provider "docker" do |d| d.image = "ubuntu:24.04" end end
このディレクトリーでvagrant up
を実行してみます。ああ、そのまえにDocker Desktopなどの起動をお忘れなく(何でそんなことを言ったかというと、自分が忘れたからです)。
コンテナが起動して、何も設定しなかったのでそのままコンテナーは停止しました。
$ vagrant up Bringing machine 'default' up with 'docker' provider... ==> default: Creating and configuring docker networks... ==> default: Creating the container... default: Name: vagrant-docker_default_1754023157 default: Image: ubuntu:24.04 default: Volume: /Users/ytooyama/tmp/vagrant-docker:/vagrant default: default: Container created: 920c3a5a9435eded ==> default: Waiting for container to enter "running" state... The container started either never left the "stopped" state or very quickly reverted to the "stopped" state. This is usually because the container didn't execute a command that kept it running, and usually indicates a misconfiguration. If you meant for this container to not remain running, please set the Docker provider configuration "remains_running" to "false": config.vm.provider "docker" do |d| d.remains_running = false end
実際dockerコマンドを実行すると、コンテナが動いたときの記録が残っています。 なるほど、確かに動いたみたいです。でも停止しているのでもう一息です。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 920c3a5a9435 ubuntu:24.04 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago vagrant-docker_default_1754023157
エラーメッセージから、以下の設定を書けば永続してコンテナを実行してくれるそうです。dockerコマンドでいう--ttyと同じイメージですかね。エラーメッセージは永続して動かさない場合はfalseと書けとありますので、その逆をしたいのでtrueと書きます。
config.vm.provider "docker" do |d| d.remains_running = true end
先ほどのVagrantファイルに追記してみましょう。
% cat Vagrantfile Vagrant.configure("2") do |config| config.vm.provider "docker" do |d| d.name = "vagrant-ubuntu" d.image = "ubuntu:24.04" d.remains_running = true #ここに追記しました end end
もう一度実行すると次のように表示されました。警告はでませんでしたが、コンテナは継続して動作しませんでした。まだ何か足りないようです。
% vagrant up Bringing machine 'default' up with 'docker' provider... ==> default: Creating and configuring docker networks... ==> default: Creating the container... default: Name: vagrant-docker_default_1754024064 default: Image: ubuntu:24.04 default: Volume: /Users/ytooyama/tmp/vagrant-docker:/vagrant default: default: Container created: 8578329e8d64b5ed ==> default: Waiting for container to enter "running" state... The container started either never left the "stopped" state or very quickly reverted to the "stopped" state. This is usually because the container didn't execute a command that kept it running, and usually indicates a misconfiguration. If you meant for this container to not remain running, please set the Docker provider configuration "remains_running" to "false": config.vm.provider "docker" do |d| d.remains_running = false end
もうちょっと増やしてみます。
% cat Vagrantfile Vagrant.configure("2") do |config| config.vm.provider "docker" do |d| d.image = "ubuntu:24.04" d.remains_running = true d.create_args = ["--tty", "--interactive"] #いつものあれを追加 end end
その上で実行すると、今度はコンテナの永続化ができました。 たいていのコンテナイメージは最小のイメージとして作られているので、このような方法でUbuntuコンテナを動かすのはこう言うときだけではあるのですが、まずは第一歩は達成できました。
% vagrant up Bringing machine 'default' up with 'docker' provider... ==> default: Creating and configuring docker networks... ==> default: Creating the container... default: Name: vagrant-docker_default_1754024330 default: Image: ubuntu:24.04 default: Volume: /Users/ytooyama/tmp/vagrant-docker:/vagrant default: default: Container created: d68f46c77b331b98 ==> default: Enabling network interfaces... ==> default: Starting container... % docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d68f46c77b33 ubuntu:24.04 "/bin/bash" 22 seconds ago Up 22 seconds vagrant-docker_default_1754024330
じゃあ次にもう一つ、いつものあれことNGINXコンテナを動かしてみます。
まずはVagrantfileを書き換えてください。ここから先はコンテナー名がランダムだと分かりにくいので、d.name
も設定しようと思います。
Vagrant.configure("2") do |config| config.vm.provider "docker" do |d| # Nginxの公式イメージを使用 d.image = "nginx:latest" #コンテナ名 d.name = "vagrant-nginx" # コンテナを永続実行させる設定 d.remains_running = true # ポートフォワーディング: ホスト8888 -> コンテナ80 d.ports = ["8888:80"] # TTYを有効化(--ttyオプション相当) d.create_args = ["--tty"] end end
ブラウザーで次にアクセスするとNGINXのデモページが表示されると思います。
ちなみに言い忘れましたが、コンテナへのアクセスは次のコマンドで可能だそうです。もちろん、わざわざ特別なコマンドを実行することなく、従来のようにdocker exec
コマンドを使っても良いと思います。
% vagrant docker-exec default -it -- /bin/sh / #
最後に、NGINXで特定のページに置き換えてVagrant upで環境構築するのを試してみようと思います。 ディレクトリーはこのような感じでVagrantfileを置いたディレクトリーと同じ階層にhtmlディレクトリーを作って、その中に
project/ ├── Vagrantfile └── html/ # 自動作成される └── index.html # Hello Worldページ
先ほどのVagrantfileに次のようにValumeを記述します。
% cat Vagrantfile Vagrant.configure("2") do |config| config.vm.provider "docker" do |d| # Nginxの公式イメージを使用 d.image = "nginx:alpine-slim" d.name = "vagrant-nginx" # コンテナを永続実行させる設定 d.remains_running = true # ポートフォワーディング: ホスト8888 -> コンテナ80 d.ports = ["8888:80"] # TTYを有効化(--ttyオプション相当) d.create_args = ["--tty"] d.volumes = ["./html:/usr/share/nginx/html:ro"] #追加した行 end end
適当にディレクトリーとファイルを作っておきます。
$ mkdir html $ echo "<h1>Hello, This is My Custom Page</h1>" > html/index.html
vagrant up
コマンドを実行してブラウザーでアクセスすると、「Hello, This is My Custom Page」と表示されると思います。ブラウザーの状態によってはリロードが必要かもしれません。
と言うわけで、確かにVagrantでDockerの制御ができることがわかりました。 ここまでやってきた中で、VagrantでDockerを使うメリットとしてはDockerfileやdockerコマンドを触らなくてもコンテナでアプリケーションが動かせると言うことでしょうか。
Dockerfileを用意すればイメージのビルドなどもvagrantコマンドから行えるようなので、自動化するときに使えるのかなあなんて思ったりしています。テンプレート化はやりやすそうですね。
ちなみにこう書くとマシンの名前がdefaultから指定した名前になるので、vagrant docker-exec
コマンドを実行するときの違和感はなくなると思います。
Vagrant.configure("2") do |config| config.vm.define "nginx" do |nginx| nginx.vm.provider "docker" do |d| # Nginxの公式イメージを使用 d.image = "nginx:alpine-slim" d.name = "vagrant-nginx" # コンテナを永続実行させる設定 d.remains_running = true # ポートフォワーディング: ホスト8888 -> コンテナ80 d.ports = ["8888:80"] # TTYを有効化(--ttyオプション相当) d.create_args = ["--tty"] d.volumes = ["./html:/usr/share/nginx/html:ro"] end end end
試しに実行してみましょう。
% vagrant docker-exec nginx -it -- /bin/sh / #
VagrantでDockerを触るのははじめてでした。 VagrantでVirtualBoxで仮想マシンを作るのと同じツールを使って、Dockerコンテナーでアプリケーションを動かせるのは便利なシーンもあるかもしれません。 必要なときには今回の事を思い出して、VagrantでDockerを利用するのもありかなと思いました。 Vagrantのライセンス的に問題ないところでは活用したいと思います。