とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

VagrantでDockerが使える?を試してみた

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のライセンス的に問題ないところでは活用したいと思います。