えいのうにっき

主に Web 系技術ネタ。背景画像 is powered by grass-graph.shitemil.works

Docker for Mac がずいぶん良いらしいので、Docker で Rails アプリを動かしてみた

Docker は、以前に「勉強」だけはしていたのだけど「実践」はあんまりできていなかった。でも、ここのところ Docker for Mac の評判がずいぶん良いらしいので、遅くはなったけど「実践」の頃合いかなということで腰を上げてみた。Docker 再入門、ってことで。

Docker for Mac のインストールと Getting Started

ここの通りに進めていってみる。Docker for mac は 2016/06/29 現在、public beta。

進めていくなかで、Getting Started の途中にある、hello-world の docker run にて

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
Pulling repository docker.io/library/hello-world
docker: Network timed out while trying to connect to 
https://index.docker.io/v1/repositories/library/hello-world/images.
You may want to check your internet connection or if you are behind a proxy..
See 'docker run --help'.

となってしまった。

調べてみたところ理由は人それぞれって感じっぽいんだけど、僕の場合は DNS サーバの指定順序がよくなかったようす。 雑に、一番上に 8.8.8.8 を指定したら、うまくいった。

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

a9d36faac0fe: Pull complete 
Digest: sha256:e52be8ffeeb1f374f440893189cd32f44cb166650e7ab185fa7735b7dc48d619
Status: Downloaded newer image for hello-world:latest

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

この解決策は、 Docker for Mac の forumのやりとりがヒントになった。 まだβだし、ぐぐるよりもこの forum を見るようにするのがいいかも。

Getting Started では、これ以外には特につまづいたところはなかった。

作業…のまえに、用語の確認

をする。 docker-hogehoge っていうのが多すぎて、何が何だかわかんなくなってきちゃったので。

docker-engine

Docker の実行環境そのもの、って思っていいのかな。 Get Docker | Docker には Docker Engine runs on Linux to create the operating environment for your distributed applications. とあるので、Linux 環境上で、ということみたいだ。

docker-compose

こちらのブログにあった 複数のコンテナを利用して一つのサービスを提供する場合に YAML 一発で構築出来るようにするツール という説明が、一番しっくりきた。

あれ、 docker swarm もそんなんじゃなかったっけ、と思ったのだけど、swarm はコンテナが起動しているホストも複数あるような状況で使うやつ、って感じなのかな。

docker-machine

Docker Machine Overview | Docker Documentation を見ると、

Docker Machine is a tool that lets you install Docker Engine on virtual hosts, and manage the hosts with docker-machine commands. You can use Machine to create Docker hosts on your local Mac or Windows box, on your company network, in your data center, or on cloud providers like AWS or Digital Ocean. – What is Docker Machine? - https://docs.docker.com/machine/overview/

とあって、上述の docker-engine を、バーチャルホストや MacWindows でも使えるようにしてくれるもの、って感じだろうか。ややこしい。

でも、これらのややこしいツール類のセットアップが Docker for Mac のインストールだけで済んじゃうのは、とても有り難い。

Rails アプリケーションが動く環境を作ってみる

頻出用語の確認ができたところで、次のステップ。

ここでのゴールとしては、いちおう Rails アプリケーションである、僕のポートフォリオページ・ home.a-know.me を Docker コンテナで動かせること、というのを目指してみる。リポジトリはこれ↓。

以下の2つのページを参考・見比べながら、Dockerfile と docker-compose.yml を作成してみる。

FROM ruby:2.3.0
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
npm nodejs-legacy
RUN npm install -g phantomjs-prebuilt
RUN gem install bundler

ENV APP_HOME /a-know-home
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile* $APP_HOME/
RUN bundle install

ADD . $APP_HOME

Dockerfile は、ちょいちょい docker build して確認をしながらイメージを作っていった。

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/a-know-home
    ports:
      - "3000:3000"

今回コンテナ内で起動させようとしている Rails アプリ(自分のポートフォリオページ)は本当に薄いアプリケーションで、DB すら使っていない。なので docker-compose.yml も非常にシンプル。DB を使うような場合だと、 services の中に db: を追加するかんじっぽい。

また、アプリケーションの動作に必要な環境変数なんだけど、もともと使う前提にしていた dotenv に、いったんは任せてみることにした。 docker-compose.yml 内で指定することもできるらしい。

docker-compose.ymlcommand にアプリケーションを起動させるための rails s を書いてるんだけど、コンテナを起動しつつこの command を実行させるには docker-compose up でいいみたい。

$ docker-compose up
Recreating aknowhomerails_web
Attaching to aknowhomerails_web
web_1  | WARNING: Nokogiri was built against LibXML version 2.9.4, but
has dynamically loaded 2.9.1
web_1  | => Booting Puma
web_1  | => Rails 5.0.0.rc2 application starting in development on
http://0.0.0.0:3000
web_1  | => Run `rails server -h` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 3.4.0 (ruby 2.3.0-p0), codename: Owl Bowl Brawl
web_1  | * Min threads: 0, max threads: 16
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3000
web_1  | Use Ctrl-C to stop

で、 http://localhost:3000 を開いてみるとー。

f:id:a-know:20160629164456p:plain

おっけー。

今回の作業内容のまとめは↓こちらに。

感想

home.a-know.me の本番環境は、Rails の他に

  • fluentd(td-agent)
  • nginx
  • mackerel

…といったものが動いてるんだけど、Docker を使ってこの本番環境を再現しようとするならば、それぞれごとにコンテナを用意して、それらを docker-compose で管理する…、、といったかんじになる、のかな。 そうなれば、Docker さえ使える環境であればどこでもアプリケーションを動かせることになる。うーん、理想の世界。

今の本番環境は、こういったミドルウェアのインストールとかはぜんぶ Chef でやっている。カスタムレシピを書くのもそれはそれで楽しいんだけど、面倒だったり難しい部分も無くは無い。やっぱり今後は Docker・コンテナな世界がやってくるんだろうかなぁ。

既存のアプリケーションを Docker に、となるとちょっと勢いが必要だけど、今度なにか新しいアプリケーションをつくるときには、最初から Docker 前提で進めてみてもいいかもしれない。と思った。

…あと、Docker for Mac、今回の作業をやるぶんには Docker 環境周りで何もつまづくところがなかったので、本当にイイかんじなんだと思います! Docker な世界が拡がるのが加速しそう!



follow us in feedly