Go言語で作ったAPIサーバーがのったコンテナをDockerで使ってみる

Posted by on Sun, Feb 7, 2016

Mac OSにdocker-toolboxをインストールし、VM(machine)を立ち上げる

1.docker-toolbox をインストールします。

2.インストールが完了すると、 docker quickstart terminal というのがありますのでそれを起動します。

すると、ターミナルが立ち上がり、下記のようなログが流れます。

bash --login '/Applications/Docker/Docker Quickstart Terminal.app/Contents/Resources/Scripts/start.sh'
Last login: Thu Jan 21 15:14:12 on ttys017
% ~
% bash --login '/Applications/Docker/Docker Quickstart Terminal.app/Contents/Resources/Scripts/start.sh'


Creating CA: /Users/kwmt/.docker/machine/certs/ca.pem
Creating client certificate: /Users/kwmt/.docker/machine/certs/cert.pem
Running pre-create checks...
Creating machine...
(default) Copying /Users/kwmt/.docker/machine/cache/boot2docker.iso to /Users/kwmt/.docker/machine/machines/default/boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...

(default) Starting the VM...
(default) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Machine is running, waiting for SSH to be available...
Detecting operating system of created instance...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect Docker to this machine, run: /usr/local/bin/docker-machine env default


                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/


docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com

完了したら、defaultというVM(machineと呼ぶことにする)が作成され、machineが起動している状態になります。

docker-machineコマンドについて

machineを起動・停止したり、状態を確認するには、docker-machineコマンドを使用します。

  • machineの状態を確認するには、 ls コマンドを実行します。
% docker-machine ls
NAME      ACTIVE   URL          STATE     URL                         SWARM   DOCKER   ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v1.9.1  

defaultというmachine名で、STATEがRunningなので起動していることが確認できます。

  • machineが起動しているかどうかはstatusコマンドで確認できます。
% docker-machine status <machine名>
Running
  • もし起動していなかった場合は、startコマンドを実行します。
% docker-machine start <machine名>
  • machineが起動しているのを止めたい場合は、 stop コマンドを実行します.
% docker-machine stop <machine名>
  • machineにsshログインするには、sshコマンドを実行します。
% docker-machine ssh <machine名>
  • Mac OSのshellからmachine上のコンテナを操作するには、 env コマンドで表示される環境変数をmac側のshellに設定する必要があります。 eval コマンドを使って設定すると簡単です。
% eval $(docker-machine env default)

これで、 sshコマンドでmachineに接続しなくても、macのターミナルからdockerコマンドが使えるようになります。

Goで作ったAPIサーバーのコンテナを作成

コンテナにGoとMySQLをインストールし、それと gozen(オレオレWebフレームワークというかMVCテンプレートみたいなものですが)を使ってコンテナを作成してみたいと思います。

Dockerfileを使ってコンテナを作成するには

1.作業ディレクトリに移動します。

% cd ~/work (←なんでもよい)

2.Dockerfileを作成します。

% touch Dockerfile

内容はgithubをみてください。

3.Dockerfileを元にbuildコマンドでビルドします。

$ docker build -t <REPOSITORY>  <DockerfileのPATH>
(例 docker build -t kwmt/makunouchi-gozen  .)

4.コンテナイメージが作成されたか確認するには、imagesコマンドを使用します。

$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
kwmt/makunouchi-gozen   latest              1339114a1094        About a minute ago   977.5 MB
buildpack-deps          jessie-scm          d6fc4b5b4917        5 days ago           292 MB

作成したコンテナイメージを Docker Hubにpushするには

docker loginコマンドでログインして、pushするだけ。

% docker login
Username: kwmt
Password: 
Email: foo@gmail.com
Login Succeeded
% docker push kwmt/makunouchi-gozen
The push refers to a repository [docker.io/kwmt/makunouchi-gozen] (len: 1)
1339114a1094: Pushed 
0477ae0365f0: Pushed 
~~~~~ 

40分ぐらいかかった。。。

Docker Hubにあるコンテナイメージを使うには

(ご注意)手順が増えてしまいました。自分が知らないだけでもっと手順は短くなると思ってます。分かり次第、修正します。

1.適当な作業ディレクトリ(例:work)に移動し、コンテナイメージを起動します。

% docker run --name="gozen_docker" -p 8080:9000 -d -it kwmt/makunouchi-gozen 

明示的にpullしなくてもローカルになければ、DockerHubから探してpullしてくれます。

1-1.現在起動中のコンテナを確認するには ps コマンドを使用します。

% docker ps
CONTAINER ID        IMAGE                   COMMAND             CREATED             STATUS              PORTS                              NAMES
a43200ebc23e        kwmt/makunouchi-gozen   "/bin/bash"         About an hour ago   Up About an hour    3306/tcp, 0.0.0.0:8080->9000/tcp   gozen_docker

2.コンテナの/gopathにあるデータをホストにコピーします。

% docker cp gozen_docker:/gopath .

3.コピーが終わったら、立ち上げ直します。(TODO: 最初からvオプション付けるとホスト側にソースがないので、ソースがない状態が共有されてしまい、docker cpしてもホスト側にコピーされない。この手順はなくしたい)

3-1.いったんコンテナとイメージは削除します。

% docker rm -f $(docker ps -a -q) && docker rmi -f $(docker images -q)

3-2.ホストとコンテナのVolumeを共有するオプション(-v)をつけて起動します。

% docker run --name="gozen_docker" -v $(pwd)/gopath:/gopath -p 8080:9000 -d  -it kwmt/makunouchi-gozen

4.コンテナにログインして、サーバー起動のための準備をします。(TODO: 本来ならこれもDockerfileに埋め込みたい)

% docker exec -it gozen_docker bash

4-1.MySQLサーバーを起動します。(TODO: docker-composeなど使ってDBサーバーを別コンテナ化したら不要になるかも?)

$ /etc/init.d/mysql start

4-2.DB・ユーザー作成(TODO: Dockerfileとかで何とかしてこの手順を無くしたい)

$ mysql -u root -prootpass < db/setup/mysql.sql 

4-3.マイグレーションを実行します。

$ cd $GOPATH/src/gozen
$ goose up (insert sample data into DB)

5.Intellij IDEAを使用する場合は、ホスト側(Mac側)で実行してください。 $GOPATH/src/gozen/vendor/src$GOATH のシンボリックリンクをはります。これにより、Intellijでglideでパッケージ管理されてるライブラリの補完が効くようになります。

% cd work/gopath/src/gozen
% ./symlinkVendor.sh 

6.コンテナ側で、APIサーバーを起動します.

$ cd $GOPATH/src/gozen
$ ./build.sh

7.確認します。サンプルとして /api/users/1にアクセスしてみてください。

コンテナにログインしている場合は、localhost:9000で確認。

$ curl http://localhost:9000/api/users/1
{"Id":1,"Name":"田中"}

コンテナの外から確認するなら、docker-machine ip default でipアドレスを確認してアクセスする。

% curl $(docker-machine ip default):8080/api/users/1
{"Id":1,"Name":"田中"}

コンテナやイメージを削除するには

  • イメージ削除
$ docker rmi -f <IMAGE ID>

-fは強制的に削除します。

  • 全イメージ削除
$ docker rmi -f $(docker images -q)

imagesコマンドの-qオプションは、Image Idのみ表示するオプションです。

  • 全コンテナ削除
$ docker rm -f $(docker ps -a -q)

エラーが出た時の対策

docker runやpull imageをpullするときにNetwork timed outと出た場合

現象

docker runやpullで pull中に下記のエラーが出た

% docker pull golang
Using default tag: latest
Pulling repository docker.io/library/golang
Network timed out while trying to connect to https://index.docker.io/v1/repositories/library/golang/images. You may want to check your internet connection or if you are behind a proxy.

対策

$ docker-machine restart default && eval $(docker-machine env default)

Network timed out while trying to connect to https://index.docker.io

参考

  • Installation on Mac OS X
  • Mac OSX で Docker 入門 (Docker Toolbox版) - fugafuga.write
  • Docker 入門ハンズオン資料 - Qiita


comments powered by Disqus