🧊

Docker?なにそれおいしいの? for フロントエンド(だけやる)エンジニア

最初に結論を書いてしまうけど、フロントエンド(だけやる)エンジニアにはたぶんおいしくない。

っていうことに気付くまでの学びを社内勉強会用にまとめたメモ。
概念的なところがメインなので、細かいDockerのコマンドとかそういうのには触れません。

あんまり詳しい分野じゃないので、なんか変なこと書いてたら教えてください・・・!

Docker is 何

Docker Documentation - Docker Documentation

Docker is コンテナ型の仮想化技術

  • "ざっくり"いうと、KVMとかVMWareとかHyper-VとかVirtualBoxとかと同じ
    • ホストOS(たとえばmac)上で、ゲストOS(たとえばLinux)を動かせる
  • もう少しだけ"厳密"にいうと、コンテナ型の仮想化技術というもの
    • 先述のVirtualMachineたち(完全仮想化とか言ったりする)とは違う

コンテナ

  • What is a Container | Docker
    • 仮想化する部分が一部 = 軽快
    • ポータビリティ!
  • アプリケーション(WebサーバーとかDBサーバーとか)の実行環境
    • そのサービスの実行に必要なものを全部ひとまとめにしたもの
  • そんなサービスが起動するプロセスの単位
    • 黒い画面でなんかコマンド叩くと実行されて、終わったら消えるアレがプロセス
    • 何回やってもどこでやっても同じ結果
    • 状態は持たない <- 重要
    • あの感覚でアプリケーションを動かせる

コンテナ = イメージをビルドしたもの

よさそう

  • コンテナの単位でデプロイとかできるといいよね
  • Dockerさえ動けば、どこでも動かせる
    • Windows, macOS, Linux, Heroku, AWS, ..etc
    • 仮想リソースなのでいらなくなったら消せばいい

だが実際は

  • コンテナ = ブラックボックス
    • メモリ足りなくて死んだりするのどうやって拾うの
    • 障害時の切り分け
    • ログ吐いたり見たりしたいけどドコに・・
  • Dockerfileのメンテが辛い
  • 実際に運用するにはオーケストレーションツールが別途でほぼ必須
    • docker-compose, Swarm, Kubernetes, ...etc

と、有識者の方々はおっしゃる・・( ˘ω˘)
可能性はあるが、まだ枯れてはいないというのが現状のステータスっぽい。

ここまでのまとめ

  • アプリケーションをコンテナという単位で扱えるのがキモ
    • Dockerが動くところであればコンテナが動く = サービスが動く
  • イメージの中に、アプリのコードや依存関係は含まれる
    • コードをGitHubにpush -> CIが動いてイメージをビルド
    • そのイメージ(=コンテナ)が、本番環境でもそのまま実行される

というのがそもそものDockerの本意。

我々にとっておいしいか

おいしいも何も、関係ない(かも)

ここまで見てきて、自分には関係ないかな・・と思ったら、関係ない。

Dockerの本来の用途に関して言えば、

  • `localhost`にサーバー建てて開発する
  • 環境依存なのはNode.jsくらい
  • GitHubにコードをpushすればおわり
  • あっても静的なデータを返すAPIモックサーバーくらい

っていういわゆるフロントエンド(だけやる)エンジニアにとっては、無用の長物なのは間違いない。
使いたいなら使えばいいけど。

おいしいかもしれない

  • フロントエンドはいつもどおり`localhost`で開発
  • ただし他にもサーバーがないと開発できない場合
    • サーバーサイドで動かすべきロジックがある
    • モックデータの入ったDBサーバーがいる
    • Redisみたいなやつもいる・・etc

適当にモック用のBFFみたいなの用意したらええやんってのはさておき、こういうのがDockerで動かせる場合はおいしい。

適当なコマンド一発でコンテナが起動して、適当なポートでアクセスできるようにしてるはず。
`npm start`するついでに`docker run`とか`docker-compose up`すればいいだけ。

Dockerさえインストールしてれば、環境構築したり他に何かインストールしたりしなくていいので楽ちん。

Docker = ただの軽いVMではない

けども、そういう使い方もできてしまう。

  • ホストOS(たとえばmac)で、ゲストOS(たとえばLinux)を動かす
    • 実行環境(Nodeとか)は、ゲストOS側に
    • ソースコード(`node_modules`含む)は、ホストOS側に

みたいに、コンテナの中で状態が持てないなら、開発中で変化するものはホスト側に残しておくしかない。
コンテナの実行時にコピーしたりボリューム共有したりしてやってく。

ただしその場合、VirtualBoxとかVagrantとかで過去にやってたのと同じ問題がつきまとう。

ホスト <-> ゲスト間のファイルI/Oが激遅い問題

修正した内容が反映されるのが遅いとか、いわゆる`npm run watch`的なやつが遅くて使い物にならん問題。

File access in mounted volumes extremely slow · Issue #77 · docker/for-mac · GitHub

公式でもだいぶ前から取り上げられてるけど、イマイチ解決策が出てきてない。
Vagrant x VirtualBoxの頃は`rsync`で手動コピーしたりしてなんとかしてた思い出がある・・。

Dockerの場合でも一緒。

などなど結局がんばるしかなくて、Docker for Macとかから参入したエンジョイ勢はたぶんここで駆逐される。
大したファイル数がないとか、別にこの遅さが待てるとかなら問題にはならんけど。

ホストとゲストでOS違う問題

Cとかのネイティブモジュールを使うモジュールにありがち。`node-sass`とか。
`npm install`する側(= ホスト側 = mac)でビルドしたモジュールが、ゲスト側で使えない。

どうしようもない気がする。

諦めて全部ホスト側でやったらいいと思う。
`yarn.lock`で依存関係もだいぶマシになったし、せいぜい解決できてNodeのバージョンくらい・・。

まとめ

というわけで、フロントエンド(だけやる)エンジニアにとっては、知らなくても困らんと思う。

まあ知識は無駄にならんし、CircleCIが2.0になってDockerが1stサポートになったので、ちょっと楽ができるかもーくらい。

本質を見極めた上で、選択・判断しよう、そのために日々勉強しようという話か・・。