開発におけるdockerの利点とかその他諸々

インターン先での開発時はdockerを使って環境を構築することが多いです。

でも最近までdockerがなんたるかをwebで読んでもちんぷんかんぷんだったにも関わらず使ってると便利だなーって思えるようになりました。

でも環境構築するまでは結構苦労がありました。今回はdockerについて溜まった知見をメモしていこうと思います。

docker 概要

そもそもdockerとはなにものなのか。

一言で言えば 軽量なコンテナ型の仮想化環境

うーんわからない。

というわけで自分なりに解釈、要約してみます。

仮想化環境

仮想化技術で一番使ってるのが多いと思われるのはホスト型の仮想化技術。 これはよくある、「Linux上でWindows動かせるよ」とか、「Windows上でLinux動かせるよ」みたいなやつです。

こいつらはGUI上で他のOSのGUIでいじりたい時とかOS丸ごと動かしたい時は重宝するやつですね。

これに対して、Dockerのコンテナ型っていうのは、

一つのプロセスが独自の名前空間やリソースを持ってその中でアプリケーションを実行させる という感じだと思ってます。

例えば仮想化したWindowsGUI上でゲームしたい場合はゲーム以外にもWindowsっていうOS自体やそのOSの中でたくさんのプロセスが走ってます。Dockerの一つのコンテナはこのプロセス一つ一つに焦点を当てたもの。だから軽量でコンテナ型という文言があるのですね。

用途

なんでDockerが流行っているのか、何が便利なのか。自分なりにまとめてみます。

例えば以下のようなアーキテクチャのシステムを構築するとします。

f:id:kk_river108:20170617192844p:plain

ではこのWebサーバーでなんかWebアプリが動いてる、RailsでもDjangoでもなんでもいいです。 RedisやMySQLは別サーバーで稼働中。

ではこのWebアプリを開発するとして環境はどうすべきか。当然自分のPCにMySQLを入れて、Redisも入れて、ユーザー設定して。。。 とやっても全然いいです。

しかし、もし複数人で共同で開発する場合そういう風に環境を構築すると思わぬ齟齬が生まれる場合があります。 例えばポート番号が違うとか、ユーザーのパスワードが違うとか、ホスト名が違うとか。

開発環境を統一したい。新しい人が入って来てもこちらがわざわざ指示せずに開発環境をパッケージ化しておきたい。 そういう時にDockerは便利です。

Dockerは上記の図のWebサーバー、DB, inMemoryDBそれぞれをコンテナとして動かすことができます。

実際に構成がどのようになるかと言えば

  • 自分のPCのマシン 192.168.2.70
  • Gateway 172.0.0.1
  • Webサーバー 172.10.0.2
  • DBサーバー 172.10.0.3
  • Redisとか 172.10.0.4

Dockerはこれらを単一で走らせることもできますが、Docker-composeというものがあってこの構成をひとまとめに一括で起動することもできます。ネットワークの構成も自動でやってくれる優れものです。

簡単な環境構築の流れとしては

  1. プロジェクト直下に Dockerfile docker-compose.ymlを作成
  2. Dockerfileにはアプリのビルドプロセスを、docker-compose.ymlには各種サービスの起動手順を (詳しくはグーグル先生へ)
  3. docker-compose build でイメージを作成
  4. docker-compose up で起動

これが上手くいけば、他の人のPCでもプロジェクトのディレクトリをgitか何かで共有して docker-compose build docker-compose up みたいにするとすぐに開発環境が立ち上がります。DockerコンテナのIPアドレスは指定しないかぎり毎回ランダムですが自分のlocalhostポートと紐つけることができるので不便になることはありません。

図のようにAWSのサービスとかを利用する場合も環境変数等をファイルに記述し、鍵を読み込ませることもできます。環境変数ファイルはgitignoreとかで隠します。

ホスト名等もDockerでサポートしているサービスであれば基本的に面倒な設定いらずに統一できます。 Dockerfileを個別に作る必要もありません。

例:

Mysql ==> ホスト名: mysql
Redis ==> ホスト名: redis

docker-composeはプロジェクトのディレクトリ直下にdocker-compose.ymlを作成してdocker-compose upすると コンテナ群が起動します。

docker 便利です。

コンテナ内での作業

例えばMySQLへの書き込みをアプリでしていて実際に書き込まれているか見たい、なんて時もコンテナのシェルをすぐにいじることができます。

docker-compose exec -it sample_container_mysql_1 bash

と叩くとシェルに入れます sample_container_mysql_1 はコンテナ名みたいなやつで docker-compose psで確認できます

Webサーバーだけ再起動して動作確認したい。

docker-compose upでコンテナ群を起動して docker-compose down で落とします。

これらは全てのコンテナを操作するので多少時間がかかりますがWebサーバーのソース更新したからそこだけ、MySQLだけとかを再起動させる場合は

docker-compose restart web みたいにサービス名を入力すると単一的に再起動させることができます。最初知らなくて一々全部起動して、終了して、起動してを繰り返してました。

面倒くさいこと

マイクロサービスアーキテクチャが主流のなかでDockerは便利です。 しかし、この環境を作ること自体は結構面倒くさかったりします。docker-compose.ymlを何回も書き直してbuildしてイメージが増えすぎて消すのが結構面倒くさかったこともあります。

ある程度ネットワークや構築するシステムのアーキテクチャを知っている必要はあるのかなーって思いました。 あと自分でちょろーっと簡単なアプリ開発!なんていう時は必要ないかもしれません。AzureやGAEやHeroku使った方が早いと思います。

大きなシステムとしてその内部の一部を開発する時とかの環境構築として便利だと私は思ってます。

何事もケースバイケースですね。まだまだdockerは勉強中なのでこれからも使うかと思います。

またなんかあったら纏めてみようかな・・・