OSX, Vagrant, VirtualBoxでdockerを試す

## Vagrant 1.4.1からはdocker provisionerが使えます (2013-12-24追記)
Vagrant 1.4.1からdockerのprovisionerがサポートされています。[vagrantのCHANGELOG](https://github.com/mitchellh/vagrant/blob/master/CHANGELOG.md), [Docker - Provisioning - Vagrant Documentation](http://docs.vagrantup.com/v2/provisioning/docker.html) これを使えば下記のような手順をとらなくても、dockerのインストールと実行が出来ます。CentOSのdocker base imageを実行する例を[VagrantのDocker provisionerでCentOSのイメージを使う - Qiita \[キータ\]](http://qiita.com/hnakamur/items/147f53b565f3d35e76fe)に書きましたのでご参照ください。

--

OSX, Vagrant, VirtualBoxでdockerを試したときのメモです。

## vagrantでdockerのVM imageを起動

[Using Vagrant (Mac, Linux) - Docker Documentation](http://docs.docker.io/en/latest/installation/vagrant/)の手順で実行します。

```shell-session:
git clone https://github.com/dotcloud/docker.git
cd docker
```

お好みでVagrantfileを変更します。私は以下のようにVMに割り当てるRAMを8GBにし、VirtuaBoxのホストオンリーアダプタでVMのIPアドレスを指定しました。

```
diff --git a/Vagrantfile b/Vagrantfile
index 85af128..2ecc2f6 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -76,7 +76,11 @@ Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config|
   config.vm.provider :virtualbox do |vb|
     config.vm.box = BOX_NAME
     config.vm.box_url = BOX_URI
+
+    vb.customize ["modifyvm", :id, "--memory", "8192"]
   end
+
+  config.vm.network :private_network, ip: "192.168.33.31"
 end
 
 if !FORWARD_DOCKER_PORTS.nil?
```

```shell-session:
vagrant up
vagrant ssh
```

VM上でdockerコマンドを引数なしで実行すると使い方が表示され、インストールされていることが確認できます。

```shell-session
vagrant@precise64:~$ sudo docker
Usage: docker [OPTIONS] COMMAND [arg...]
 -H=[unix:///var/run/docker.sock]: tcp://host:port to bind/connect to or unix://path/to/socket to use

A self-sufficient runtime for linux containers.

Commands:
    attach    Attach to a running container
    build     Build a container from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders from the containers filesystem to the host path
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    export    Stream the contents of a container as a tar archive
    history   Show the history of an image
    images    List images
    import    Create a new filesystem image from the contents of a tarball
    info      Display system-wide information
    insert    Insert a file in an image
    inspect   Return low-level information on a container
    kill      Kill a running container
    login     Register or Login to the docker registry server
    logs      Fetch the logs of a container
    port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
    top       Lookup the running processes of a container
    ps        List containers
    pull      Pull an image or a repository from the docker registry server
    push      Push an image or a repository to the docker registry server
    restart   Restart a running container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    search    Search for an image in the docker index
    start     Start a stopped container
    stop      Stop a running container
    tag       Tag an image into a repository
    version   Show the docker version information
    wait      Block until a container stops, then print its exit code
```

## Hello worldの例を試す

[Hello world example - Docker Documentation](http://docs.docker.io/en/latest/examples/hello_world/)の手順で試します。

```ps auxww|grep docker```で確認すると既にdockerは-d付きで起動されているので```sudo docker -d &```は不要でした。

```shell-session
vagrant@precise64:~$ sudo docker pull ubuntu
vagrant@precise64:~$ sudo docker run ubuntu /bin/echo hello world
hello world
```

Hello World Daemonの例も同様に試します。

```shell-session
vagrant@precise64:~$ CONTAINER_ID=$(sudo docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done")
vagrant@precise64:~$ sudo docker logs $CONTAINER_ID
hello world
hello world
hello world
hello world
hello world
hello world
vagrant@precise64:~$ sudo docker attach $CONTAINER_ID
hello world
hello world
hello world
^C
vagrant@precise64:~$ sudo docker ps
ID                  IMAGE               COMMAND                CREATED             STATUS              PORTS
2b65c04d25f7        ubuntu:12.04        /bin/sh -c while tru   25 seconds ago      Up 25 seconds                           
vagrant@precise64:~$ sudo docker stop $CONTAINER_ID
2b65c04d25f7
vagrant@precise64:~$ sudo docker ps
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS
```

## redis serverの例を試す

[Running a Redis service - Docker Documentation](http://docs.docker.io/en/latest/examples/running_redis_service/)の手順で試します。ただし、dockerコンテナ内で```apt-get install redis-server```するためには/etc/apt/sources.listの編集が必要でした。

```shell-session
vagrant@precise64:~$ sudo docker run -i -t ubuntu /bin/bash
root@b527bf7cf8b1:/# cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu precise main
root@b527bf7cf8b1:/# echo "deb http://us.archive.ubuntu.com/ubuntu/ precise universe" >> /etc/apt/sources.list
root@b527bf7cf8b1:/# echo "deb http://us.archive.ubuntu.com/ubuntu/ precise-updates universe" >> /etc/apt/sources.list
root@b527bf7cf8b1:/# cat /etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu precise main
deb http://us.archive.ubuntu.com/ubuntu/ precise universe
deb http://us.archive.ubuntu.com/ubuntu/ precise-updates universe
root@b527bf7cf8b1:/# apt-get update
Ign http://us.archive.ubuntu.com precise InRelease                         
Ign http://us.archive.ubuntu.com precise-updates InRelease                 
Ign http://archive.ubuntu.com precise InRelease
Get:1 http://us.archive.ubuntu.com precise Release.gpg [198 B]
Get:2 http://us.archive.ubuntu.com precise-updates Release.gpg [198 B]
Hit http://archive.ubuntu.com precise Release.gpg         
Get:3 http://us.archive.ubuntu.com precise Release [49.6 kB]
Hit http://archive.ubuntu.com precise Release         
Hit http://archive.ubuntu.com precise/main amd64 Packages 
Get:4 http://us.archive.ubuntu.com precise-updates Release [49.6 kB]
Get:5 http://archive.ubuntu.com precise/main i386 Packages [1641 kB]
Get:6 http://us.archive.ubuntu.com precise/universe amd64 Packages [6167 kB]
Get:7 http://archive.ubuntu.com precise/main TranslationIndex [3706 B]         
Get:8 http://archive.ubuntu.com precise/main Translation-en [893 kB]           
Get:9 http://us.archive.ubuntu.com precise/universe i386 Packages [6180 kB]    
Get:10 http://us.archive.ubuntu.com precise/universe TranslationIndex [2922 B] 
Get:11 http://us.archive.ubuntu.com precise-updates/universe amd64 Packages [276 kB]
Get:12 http://us.archive.ubuntu.com precise-updates/universe i386 Packages [280 kB]
Get:13 http://us.archive.ubuntu.com precise-updates/universe TranslationIndex [2850 B]
Get:14 http://us.archive.ubuntu.com precise/universe Translation-en [4133 kB]  
Get:15 http://us.archive.ubuntu.com precise-updates/universe Translation-en [160 kB]
Fetched 19.8 MB in 28s (701 kB/s)                                              
Reading package lists... Done
root@b527bf7cf8b1:/# apt-get install redis-server
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  redis-server
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 204 kB of archives.
After this operation, 523 kB of additional disk space will be used.
Get:1 http://us.archive.ubuntu.com/ubuntu/ precise/universe redis-server amd64 2:2.2.12-1build1 [204 kB]
Fetched 204 kB in 1s (139 kB/s)        
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package redis-server.
(Reading database ... 7545 files and directories currently installed.)
Unpacking redis-server (from .../redis-server_2%3a2.2.12-1build1_amd64.deb) ...
Setting up redis-server (2:2.2.12-1build1) ...
Starting redis-server: redis-server.
root@b527bf7cf8b1:/# exit
exit
vagrant@precise64:~$
```

dockerのコンテナのスナップショットをとってredis-serverを起動します。[Running a Redis service - Docker Documentation](http://docs.docker.io/en/latest/examples/running_redis_service/)ではsudo無しでdockerを起動している箇所がありますが、permission deniedになるのでsudoが必要でした。

[Why sudo?](http://docs.docker.io/en/latest/use/basics/#why-sudo)によると、dockerの実行にはsudoを使うか、利用ユーザをdockerグループに所属させるか、いずれかが必要とのことです。

```shell-session
vagrant@precise64:~$ docker ps -a
2013/09/21 22:36:58 dial unix /var/run/docker.sock: permission denied
vagrant@precise64:~$ sudo docker ps -a
ID                  IMAGE                   COMMAND                CREATED             STATUS              PORTS
b527bf7cf8b1        ubuntu:12.04            /bin/bash              4 minutes ago       Exit 0                                  
2b65c04d25f7        ubuntu:12.04            /bin/sh -c while tru   7 minutes ago       Exit 137                                
1d54e7335230        ubuntu:12.04            /bin/echo hello worl   8 minutes ago       Exit 0                                  
ded0164fdc90        hnakamur/redis:latest   /usr/bin/redis-serve   31 minutes ago      Exit -127           49153->6379         
df555caa8007        ubuntu:12.04            /bin/bash              35 minutes ago      Exit 0                                  
f74e0bb5517c        ubuntu:12.04            /bin/bash              44 minutes ago      Exit 100                                
c019a7f3340f        ubuntu:12.04            /bin/sh -c while tru   45 minutes ago      Exit 137                                
a7984d6054d9        ubuntu:12.04            /bin/echo hello worl   45 minutes ago      Exit 0                                  
vagrant@precise64:~$ sudo docker commit b527bf7cf8b1 hnakamur/redis
7df6bf3c11ec
vagrant@precise64:~$ sudo coker run -d -p 6379 hnakamur/redis /usr/bin/redis-server
sudo: coker: command not found
vagrant@precise64:~$ sudo docker run -d -p 6379 hnakamur/redis /usr/bin/redis-server
dd13d460a13f
```

コンテナのIPアドレスでredisに繋いで試してみます。

```shell-session
vagrant@precise64:~$ sudo docker ps
ID                  IMAGE                   COMMAND                CREATED             STATUS              PORTS
dd13d460a13f        hnakamur/redis:latest   /usr/bin/redis-serve   5 minutes ago       Up 5 minutes        49153->6379         
vagrant@precise64:~$ sudo docker inspect dd13d460a13f
[{
    "ID": "dd13d460a13f3a301d3fca21098ba618f4b1f5b7702f5107d1f66c0da1dcaf66",
    "Created": "2013-09-21T22:37:51.098223912Z",
    "Path": "/usr/bin/redis-server",
    "Args": [],
    "Config": {
        "Hostname": "dd13d460a13f",
        "Domainname": "",
        "User": "",
        "Memory": 0,
        "MemorySwap": 0,
        "CpuShares": 0,
        "AttachStdin": false,
        "AttachStdout": false,
        "AttachStderr": false,
        "PortSpecs": [
            "6379"
        ],
        "Tty": false,
        "OpenStdin": false,
        "StdinOnce": false,
        "Env": null,
        "Cmd": [
            "/usr/bin/redis-server"
        ],
        "Dns": null,
        "Image": "hnakamur/redis",
        "Volumes": null,
        "VolumesFrom": "",
        "WorkingDir": "",
        "Entrypoint": null,
        "NetworkDisabled": false,
        "Privileged": false
    },
    "State": {
        "Running": true,
        "Pid": 2030,
        "ExitCode": 0,
        "StartedAt": "2013-09-21T22:37:51.109772853Z",
        "Ghost": false
    },
    "Image": "7df6bf3c11ec86352e866ade3f8ef1eacf0e9d7797dc40642fde1f67366aff20",
    "NetworkSettings": {
        "IPAddress": "172.17.0.5",
        "IPPrefixLen": 16,
        "Gateway": "172.17.42.1",
        "Bridge": "docker0",
        "PortMapping": {
            "Tcp": {
                "6379": "49153"
            },
            "Udp": {}
        }
    },
    "SysInitPath": "/usr/bin/docker",
    "ResolvConfPath": "/etc/resolv.conf",
    "HostnamePath": "/var/lib/docker/containers/dd13d460a13f3a301d3fca21098ba618f4b1f5b7702f5107d1f66c0da1dcaf66/hostname",
    "HostsPath": "/var/lib/docker/containers/dd13d460a13f3a301d3fca21098ba618f4b1f5b7702f5107d1f66c0da1dcaf66/hosts",
    "Volumes": {},
    "VolumesRW": {}
}]vagrant@precise64:~$ redis-cli -h 172.17.0.5 -p 6379
redis 172.17.0.5:6379> get docker
(nil)
redis 172.17.0.5:6379> set docker awesome
OK
redis 172.17.0.5:6379> get docker
"awesome"
redis 172.17.0.5:6379> exit
vagrant@precise64:~$
```

ホスト側のIPアドレスでredisに繋いで試してみます。上で値を設定済みなので、最初にgetを実行して取得できました。

```shell-session
vagrant@precise64:~$ sudo docker ps
ID                  IMAGE                   COMMAND                CREATED             STATUS              PORTS
dd13d460a13f        hnakamur/redis:latest   /usr/bin/redis-serve   7 minutes ago       Up 7 minutes        49153->6379         
vagrant@precise64:~$ sudo docker port dd13d460a13f 6379
49153
vagrant@precise64:~$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:88:0c:a6 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
    inet6 fe80::a00:27ff:fe88:ca6/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:15:6a:0b brd ff:ff:ff:ff:ff:ff
    inet 192.168.33.31/24 brd 192.168.33.255 scope global eth1
    inet6 fe80::a00:27ff:fe15:6a0b/64 scope link 
       valid_lft forever preferred_lft forever
4: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether de:50:cb:17:d7:d2 brd ff:ff:ff:ff:ff:ff
    inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0
    inet6 fe80::dc50:cbff:fe17:d7d2/64 scope link 
       valid_lft forever preferred_lft forever
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 8e:b6:d3:f2:94:b1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
    inet6 fe80::a471:1bff:fee1:2e3c/64 scope link 
       valid_lft forever preferred_lft forever
13: vethOWH7o9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master docker0 state UP qlen 1000
    link/ether 8e:b6:d3:f2:94:b1 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::8cb6:d3ff:fef2:94b1/64 scope link 
       valid_lft forever preferred_lft forever
vagrant@precise64:~$ redis-cli -h 192.168.33.31 -p 49153
redis 192.168.33.31:49153> get docker
"awesome"
redis 192.168.33.31:49153> set docker "awesome!!!"
OK
redis 192.168.33.31:49153> get docker
"awesome!!!"
redis 192.168.33.31:49153> exit
```