開発環境でDockerをちっちゃく導入する - Re.Ra.Ku アドベントカレンダー day 19

Re.Ra.Ku アドベントカレンダー 19日目です。

こんにちは、神場です。

前回まででSwift関連の記事を2つほど書かせていただきましたが、今回はDockerの記事です。

開発環境でのDocker

開発環境でDockerを導入する場合、アプリケーション、DBなどに分けてdocker-composeでコンテナを立てるのが一般的かと思います。

RailsPostgresqldocker-compose.ymlの例

version: '2'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    links:
      - db  
  db:
    image: postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: me
    volumes:
      - ./postgres:/var/lib/postgresql/data
    ports:
      - 5432:5432

このようにアプリケーションのレイヤーも含めてコンテナ化する例が多いと思うのですが、場合によってはアプリケーションレイヤーを除いてコンテナ化するのが良い場合もあるのではないか?というのがこの記事の内容です。

(上の例であれば、postgresのコンテナさえ立てておけばポートフォワードはされているので、アプリケーションのコンテナを立てなくてもホスト側からpsql -U me -h 127.0.0.1で接続出来ます。)

アプリケーションレイヤーを除いてコンテナ化した場合のメリット

思いつくものをいくつか列挙してみます。

ちょっと動作を試したい・見たいときにコンテナにsshで入る必要がない

これは要はアプリケーションレイヤーまでコンテナ化すると、例えばある単体テストを個別に実行したい、コンソール(RubyirbScalasbtなど)を起動したいという時にdocker exec等でコンテナに入っておく必要があるということです。手元でサクッと試したい、という場合にローカルのほうが楽な場合があるという感じでしょうか。

公式のイメージがあるものだけを使えばDockerfileを書く必要がない

MySQLPostgreSQLなど有名どころのものであればすでにイメージがあるので、自前でDockerfileを書く必要はなくなります。ただ、もちろんその代わりアプリケーションを起動するローカルの環境は整える必要があるので、以下の条件

  • アプリケーションを起動するまでの初期設定が複雑である
  • 使っている言語にバージョン管理やパッケージ管理(Rubyならrbenvbundler)のエコシステムが揃っていない

に当てはまるときは、素直にDockerfileを書いたほうが良さそうです。

buildする必要がない

Dockerfileがないのでもちろんbuildもなくなります。

まとめ

上記のことを踏まえてまとめると、

  • アプリケーションの初期設定が容易である
  • 開発の初期段階で、まだDockerfileが頻繁に変更されるフェーズにある
  • プロジェクト全体としてはDockerを使っていないが、個人的には使いたい
  • アプリケーションレイヤーをコンテナ化すると開発環境で気になるほどパフォーマンスが下がる(実際にどのぐらい下がるのか未検証ですが。。)

といったような場合には検討しても良さそうです。限定的ではありますし、環境を完全に揃えたい場合はもちろんDockerfileを書くべきですが、最初の導入としてまずはアプリケーション以外のレイヤーだけをコンテナにするという選択肢もあるのではないかと思います。