圧倒亭グランパのブログ

30年後の自分にもわかるように書くブログ

ちょっとしたdocker環境を素早く作れるツールを作った

3回同じことを繰り返したので自動化しました。

 

作ったもの

crystalで des というツールをつくりました。docker環境の設定ファイルを生成するCLIツールです。

github.com

まれによくあるケース

  • crystalを試したいけどcrystalがローカルに入っていない
  • php7を試したいがphp7がローカルに入っていない
  • ディープラーニング本の勉強のためにpython環境がほしい

サクッと試したいだけなのに、ローカルにいろいろ入れるのは面倒ですよね。自分の場合は、実現したい環境をdockerで用意していました。DockerfileMakefiledocker-compose.yml の雛形を用意しておき、必要な時にそれをコピーし、適宜書き換えて利用していました。

この作業が面倒だったのでツールを作りました。

使い方

以下の3つのコマンドを打てば、docker環境に入ることができます。

$ des --image=hogehoge --container=hoge_test
$ make setup
$ make attach

より詳しい例を見ていきます。

crystalのコードを試したいけど、crystalがインストールされていない状況を想定します。

$ ls
sample.cr

$ cat sample.cr
puts "I want to run this crystal code."

$ crystal -v
bash: crystal: command not found

ここで、desを使って設定ファイルを生成します。

$ des --image=crystallang/crystal --container=my_crystal_container
Create ./Dockerfile
Create ./Makefile
Create ./docker-compose.yml
  • imageは crystallang/crystal
  • container名はmy_crystal_container

としていることがわかります。あとは make setup すればbuildとupが行われます。

$ make setup
docker-compose -f ./docker-compose.yml build
Building app
Step 1/5 : FROM crystallang/crystal

...

Successfully built xxxxxxxxxx
docker-compose -f ./docker-compose.yml up -d
Creating network "destest_default" with the default driver
Creating my_crystal_container
$

make attachすれば、そこはもうcrystalがインストールされた環境です。

$ make attach
docker exec -it my_crystal_container /bin/bash
root@xxxxxxxxx:~/my_crystal_container# crystal -v
Crystal 0.22.0 [3c71228] (2017-04-20) LLVM 3.5.0

attachしたディレクトリはhost側のディレクトリにマウントされているので、その場でscriptを実行できます。

root@xxxxxxxxx:~/my_crystal_container# ls -la
total 20
drwxr-xr-x 6 root root  204 Jun 21 00:18 .
drwx------ 3 root root 4096 Jun 21 00:22 ..
-rw-r--r-- 1 root root  139 Jun 21 00:18 Dockerfile
-rw-r--r-- 1 root root  365 Jun 21 00:18 Makefile
-rw-r--r-- 1 root root  199 Jun 21 00:18 docker-compose.yml
-rw-r--r-- 1 root root   40 Jun 21 00:16 sample.cr
root@xxxxxxxxx:~/my_crystal_container# crystal run sample.cr
I want to run this crystal code.

数ステップでscriptを実行でき、かつhostマシンに無駄なものはインストールされていません。

今回の例はcrystalでしたが、--image=php:7としたり、--image=continuumio/anaconda3としたりして使っています。--image=hoge-i hogeでもOKです。

desが行うことはファイル生成なので、雛形生成コマンドとしても利用できます。

 

web-appオプション

--web-app を付けると、nginxとmysqlの設定も含まれます。crystalのwebフレームワーク kemal で試してみます。

kemalのコードが置いてあるリポジトリディレクトリに入ります。

$ ls -la
drwxr-xr-x 17 root root  578 Jun 21 23:52 ./
drwx------  3 root root 4096 Jun 21 23:51 ../
drwxr-xr-x 10 root root  340 Jun 21 23:48 .git/
-rw-r--r--  1 root root   28 Jun 21 23:48 .gitignore
drwxr-xr-x  6 root root  204 Jun 21 23:49 .shards/
-rw-r--r--  1 root root   18 Jun 21 23:48 .travis.yml
-rw-r--r--  1 root root 1085 Jun 21 23:48 LICENSE
-rw-r--r--  1 root root  626 Jun 21 23:48 README.md
drwxr-xr-x  5 root root  170 Jun 21 23:49 lib/
-rw-r--r--  1 root root  222 Jun 21 23:49 shard.lock
-rw-r--r--  1 root root  255 Jun 21 23:49 shard.yml
drwxr-xr-x  4 root root  136 Jun 21 23:48 spec/
drwxr-xr-x  4 root root  136 Jun 21 23:50 src/

desで設定ファイルを生成します。この時、--web-appオプションを付けます。

$ des --image=crystallang/crystal --container=kemal_test --web-app
Create ./Dockerfile
Create ./Makefile
Create ./docker-compose.yml
Create ./nginx.conf

make setupします。

$ make setup
docker-compose -f ./docker-compose.yml build

...

docker-compose -f ./docker-compose.yml up -d
kemal_test-mysql is up-to-date
kemal_test is up-to-date
Recreating kemal_test-nginx

mysqlコンテナとnginxコンテナが立ち上がっています。make attachしてコンテナ内に入り、crystalコードをbuild&runします。

$ make attach
docker exec -it kemal_test /bin/bash
root@dfa15bbde978:~/kemal_test# cat src/kemal_test.cr
require "./kemal_test/*"
require "kemal"

get "/" do
  "Hello World!"
end

Kemal.run
root@dfa15bbde978:~/kemal_test# crystal build src/kemal_test.cr
root@dfa15bbde978:~/kemal_test# ./kemal_test
[development] Kemal is ready to lead at http://0.0.0.0:3000

リクエストを受け付ける状態になりました。ここで、hostマシンに戻って http://0.0.0.0:80/に接続します。

$ curl http://0.0.0.0:80/
Hello World!

ちゃんと接続できています。

このように、webアプリを構築できるオプションも用意しました。

 

設定ファイル

実行時、設定ファイル ~/.desrc.yml が存在しなければ生成するかどうかを聞かれます。

$ des --image=crystallang/crystal --container=my_container_test
/path/to/home/.desrc.yml is not found.
Create? (y or n) > y
Create /path/to/home/.desrc.yml
Create ./Dockerfile
Create ./Makefile
Create ./docker-compose.yml
$ cat ~/.desrc.yml
default_param:
  image: crystallang/crystal
  packages:
    - curl
    - vim
  container: my_container_test
  save_dir: .
  web_app: false
  overwrite: false

これは、desの初期設定を書いておくファイルです。オプションを指定しなければ、これらの設定が使用されます。頻繁に使う設定にしておけば、オプション無しでガンガン使うことができます。

さらに詳しい情報はgithubを参照してください。

  

まとめ

今回の学びは以下です。

  • 自分が楽になるツールを作るのはモチベーションが維持できる
  • 自分自身が過去に作ったライブラリを使用でき、さらにそれを改善するきっかけになったのはなんかうれしい
  • homebrewでバイナリを配布する方法を学べた

homebrewでのバイナリ配布については、下記のサイトを参考にしました。

qiita.com

reiki4040.hatenablog.com

 

こういう簡単なツールは楽しくサクッと作れるので、今後も作っていくと思います。

   

これも学び。