Thursday, August 14, 2014

fig and docker on OSX

Docker絡みの話.
figというdocker用のオーケストレーション?ツールがDocker社に買収されて公式ツールになるらしいので触ってみた。
Dockerの軽量さを活かして個人のPCでそこそこのシステムを動かせるならとても嬉しいのだけど。
bash-3.2$ fig run web rails new . --force --database=postgresql --skip-bundle
結構時間がかかる。サイトの説明を見てみると…
Fig will build the image for the web service using the Dockerfile. Then it’ll run rails new inside a new container, using that image.
上のコマンドを実行すると、figはまずDockerfileをベースにイメージを作成、このイメージを使ったコンテナ内でrails newを実行する…らしい。
なるほど重い訳だ。
Dockerfileの中身.
FROM ruby
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
RUN bundle install
ADD . /myapp
  • FROM ruby … rubyという名前の基本イメージをベースにする。
    • 名前の通りrubyに特化したlinuxイメージなんだろな
  • RUN apt-get … postgresql用のバイナリをインストール?
  • 以降… /myappディレクトリを作ってアプリの雛形をbundleでインストール
fig run実行時のログ。
bash-3.2$ fig run web rails new . --force --database=postgresql --skip-bundle
Creating fig_db_1...
Pulling image postgres...
4ee79ff38eba: Pulling dependent layers
...
c84d12730ef9: Download complete
Building web...
Pulling repository ruby
011aa33ba92b: Download complete
...
6bdb3289ca8b: Download complete
# Executing 3 build triggers
Step onbuild-0 : ADD . /usr/src/app
 ---> d0cee0e603a2
Step onbuild-1 : WORKDIR /usr/src/app
 ---> Running in 1ec73019cb0d
 ---> a094423d3c26
Step onbuild-2 : RUN [ ! -e Gemfile ] || bundle install --system
 ---> Running in a95fb45a003f
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and
installing your bundle as root will break this application for all non-root
users on this machine.
Fetching gem metadata from http://rubygems.org/...........
Resolving dependencies...
Installing rake 10.3.2
Installing i18n 0.6.11
Using minitest 4.7.5
Installing multi_json 1.10.1
Installing thread_safe 0.3.4
Installing tzinfo 0.3.41
Installing activesupport 4.0.2
Installing builder 3.1.4
Installing erubis 2.7.0
Installing rack 1.5.2
Installing rack-test 0.6.2
Installing actionpack 4.0.2
Installing mime-types 1.25.1
Installing polyglot 0.3.5
Installing treetop 1.4.15
Installing mail 2.5.4
Installing actionmailer 4.0.2
Installing activemodel 4.0.2
Installing activerecord-deprecated_finders 1.0.3
Installing arel 4.0.2
Installing activerecord 4.0.2
Using bundler 1.6.2
Installing hike 1.2.3
Installing thor 0.19.1
Installing railties 4.0.2
Installing tilt 1.4.1
Installing sprockets 2.12.1
Installing sprockets-rails 2.0.1
Installing rails 4.0.2
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
 ---> 0a6f7eda2733
 ---> 0a6f7eda2733
Removing intermediate container db6342aaa98c
Removing intermediate container 1ec73019cb0d
Removing intermediate container a95fb45a003f
Step 1 : RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
 ---> Running in b676849b1b1e
Reading package lists...
Building dependency tree...
Reading state information...
build-essential is already the newest version.
The following packages were automatically installed and are no longer required:
  libyaml-0-2 rubygems-integration
Use 'apt-get autoremove' to remove them.
Suggested packages:
  postgresql-doc-9.4
The following packages will be upgraded:
  libpq-dev libpq5
2 upgraded, 0 newly installed, 0 to remove and 260 not upgraded.
Need to get 277 kB of archives.
After this operation, 345 kB of additional disk space will be used.
Get:1 http://http.debian.net/debian/ jessie/main libpq-dev amd64 9.4~beta2-1 [159 kB]
Get:2 http://http.debian.net/debian/ jessie/main libpq5 amd64 9.4~beta2-1 [119 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 277 kB in 2s (134 kB/s)
(Reading database ... 30861 files and directories currently installed.)
Preparing to unpack .../libpq-dev_9.4~beta2-1_amd64.deb ...
Unpacking libpq-dev (9.4~beta2-1) over (9.3.4-1+b1) ...
Preparing to unpack .../libpq5_9.4~beta2-1_amd64.deb ...
Unpacking libpq5:amd64 (9.4~beta2-1) over (9.3.4-1+b1) ...
Setting up libpq5:amd64 (9.4~beta2-1) ...
Setting up libpq-dev (9.4~beta2-1) ...
Processing triggers for libc-bin (2.18-7) ...
 ---> 2f06bd40a808
Removing intermediate container b676849b1b1e
Step 2 : RUN mkdir /myapp
 ---> Running in 1348b1fc6e2e
 ---> f3caa2b67285
Removing intermediate container 1348b1fc6e2e
Step 3 : WORKDIR /myapp
 ---> Running in 3889c5376814
 ---> e8976281600f
Removing intermediate container 3889c5376814
Step 4 : ADD Gemfile /myapp/Gemfile
 ---> 1ebecb73d3d2
Removing intermediate container 6def9af6926a
Step 5 : RUN bundle install
 ---> Running in e642bd491e17
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and
installing your bundle as root will break this application for all non-root
users on this machine.
Fetching gem metadata from http://rubygems.org/...........
Resolving dependencies...
Using rake 10.3.2
Using i18n 0.6.11
Using minitest 4.7.5
Using multi_json 1.10.1
Using thread_safe 0.3.4
Using tzinfo 0.3.41
Using activesupport 4.0.2
Using builder 3.1.4
Using erubis 2.7.0
Using rack 1.5.2
Using rack-test 0.6.2
Using actionpack 4.0.2
Using mime-types 1.25.1
Using polyglot 0.3.5
Using treetop 1.4.15
Using mail 2.5.4
Using actionmailer 4.0.2
Using activemodel 4.0.2
Using activerecord-deprecated_finders 1.0.3
Using arel 4.0.2
Using activerecord 4.0.2
Using bundler 1.6.2
Using hike 1.2.3
Using thor 0.19.1
Using railties 4.0.2
Using tilt 1.4.1
Using sprockets 2.12.1
Using sprockets-rails 2.0.1
Using rails 4.0.2
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
 ---> c1f3d4fff3fe
Removing intermediate container e642bd491e17
Step 6 : ADD . /myapp
 ---> eda8814fd49e
Removing intermediate container 520b22eccc25
Successfully built eda8814fd49e
       exist  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
       force  Gemfile
      create  app
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/assets/images/.keep
      create  app/mailers/.keep
      create  app/models/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/bundle
      create  bin/rails
      create  bin/rake
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  lib/assets
      create  lib/assets/.keep
      create  log
      create  log/.keep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/robots.txt
      create  test/fixtures
      create  test/fixtures/.keep
      create  test/controllers
      create  test/controllers/.keep
      create  test/mailers
      create  test/mailers/.keep
      create  test/models
      create  test/models/.keep
      create  test/helpers
      create  test/helpers/.keep
      create  test/integration
      create  test/integration/.keep
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
最初はDocker用の基本イメージを作っている(dbとweb、2つ作ってる?)。
ハッシュ値で表されているのはfs layerと呼ばれるもの(多分)。LXCの「元のイメージを壊さずに順番に重ねていく」ということかな。
基本イメージの立ち上げ後、Dockerファイルの2行目以降に書いた命令が順番に実行されていく。
コマンド実行後、Gemfileが上書きされている。Gemfileを開いてtherubyracerを有効にして再ビルドしろと書いてあるのでやってみる。
bash-3.2$ fig build
db uses an image, skipping
Building web...
# Executing 3 build triggers
Step onbuild-0 : ADD . /usr/src/app
 ---> 11334d9d17c3
...
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
 ---> 94c537526f32
Removing intermediate container 3d782eb9c15f
Step 6 : ADD . /myapp
 ---> 280d26cf922d
Removing intermediate container 0265b7152c45
Successfully built 280d26cf922d
流石にfs layerの再ダウンロードからはやり直していない。よかったっ。
続いてデータベースの接続先を書き換える。config/database.ymlを開いて接続先をデフォルトのlocalhostからコンテナdb_1に変更。
development: &default
  adapter: postgresql
  template: template0
  encoding: unicode
  database: postgres
  pool: 5
  username: postgres
  password:
  host: db_1

test:
  <<: *default
  database: myapp_test
そんでもってfig up
bash-3.2$ fig up
Recreating fig_db_1...
Recreating fig_web_1...
Attaching to fig_db_1, fig_web_1
db_1  | LOG:  database system was shut down at 2014-08-15 05:24:52 UTC
db_1  | LOG:  database system is ready to accept connections
db_1  | LOG:  autovacuum launcher started
web_1 | [2014-08-15 05:24:56] INFO  WEBrick 1.3.1
web_1 | [2014-08-15 05:24:56] INFO  ruby 2.1.2 (2014-05-08) [x86_64-linux]
web_1 | [2014-08-15 05:24:56] INFO  WEBrick::HTTPServer#start: pid=1 port=3000
おおお、動き出したぞ。
最後に別のターミナルを開いてデータベースを作成する。ここで、環境変数DOCKER_HOSTが指定されていないと怒られるので注意(エラートレースが長くて最初分からなかった)。
yukaarynote:fig yukaary$ export DOCKER_HOST=tcp://172.16.42.43:4243
yukaarynote:fig yukaary$ fig run web rake db:create
DOCKER_HOSTってどこなのん?って思ったら,docker-osx sshしてifconfigすれば分かる。
ただ、上のdbの作成コマンド発行してもエラーなんだよね…
db_1  | ERROR:  database "postgres" already exists
db_1  | STATEMENT:  CREATE DATABASE "postgres" ENCODING = 'unicode' TEMPLATE = "template0"
db_1  | ERROR:  database "myapp_test" already exists
何度かTry & Error繰り返している内に作っちゃったのか?そもそもドロップしないのん?
yukaarynote:fig yukaary$ fig run web rake db:drop
Starting fig_db_1...
PG::ObjectInUse: ERROR:  cannot drop the currently open database
: DROP DATABASE IF EXISTS "postgres"
/usr/local/lib/ruby/gems/2.1.0/gems/activerecord-4.0.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `async_exec'
dropしようとすると怒られる。でもコンテナを立ち上げないとdropできないでござるの巻。しょぼん。
ともあれhttp://localdocker:3000/にアクセスしたら繋がったっ。figコマンドを見てみるとスケールアウトができるみたいだし暇があったら試してみようかな。
おまけ。
yukaarynote:fig yukaary$ fig ps
  Name               Command             State        Ports      
----------------------------------------------------------------
fig_db_1    postgres                     Up      49157->5432/tcp 
fig_web_1   bundle exec rackup -p 3000   Up      3000->3000/tcp
アプリとサービスで区別しないところに好感。別件でCloud Foundryを使っているけど、あれよく分からないorz
Written with StackEdit.

No comments:

Post a Comment