Upgrade to Pro — share decks privately, control downloads, hide ads and more …

サクッと立ち上がる環境構築 docker-compose 入門

C302e84057a922dce0ecbe80207e3fcc?s=47 mu_zaru
October 15, 2020

サクッと立ち上がる環境構築 docker-compose 入門

配信動画はこちら
https://www.youtube.com/watch?v=M3h_z-9DoMQ

もし良かったらムーザルちゃんねるのチャンネル登録お願いします!
https://www.youtube.com/channel/UCLPHXwLp90A5R69Eltxo-sg

Twitter でもプログラミングネタをつぶやいているのでフォローお待ちしております。
ムー
https://twitter.com/mu_book
zaru
https://twitter.com/zaru

C302e84057a922dce0ecbe80207e3fcc?s=128

mu_zaru

October 15, 2020
Tweet

Transcript

  1. YouTube Live (2020.10.15 Thur. 21:00~)

  2. 話す人 現役のエンジニア二人 赤貝が好きな CTO と デザイン勉強中のエンジニア @mu_vpoe 最近の仕事は figma で画

    面設計をつくることで す。英語の勉強してる。 ムー zaru @zaru CTO, Love 赤貝, JavaScript, Firebase, Web Components. Twitter フォロー お願いします!
  3. 話すこと - DockerCompose について - とりあえず環境を作ってみる - ネットワークとボリューム - Dockerfile

    の利用について
  4. 開発環境を作りたい! …なるべく手軽に!

  5. DockerCompose は手軽 ホストに全部用意するやり方 DockerCompose のやり方 依存関係を気にしながら自分で細かく入 れていく必要がある。大変だし面倒くさ い。もう一回やるのはしんどい 分離された環境で、設定ファイルを使っ て自動で環境を作ってくれる。大体の

    ケースにおいて誰でも同じ環境を作るこ とができる
  6. Docker じゃダメなの?

  7. コンテナを簡単に協調できる Docker だけで複数のコンテナを 使おうとすると、個別に起動しな いといけない。ネットワークの設 定なども面倒 DockerCompose ならワンコマンドで、コ ンテナ同士の通信や連携が簡単に設定でき る

  8. 早速 DockerCompose で 開発環境を作ってみる (とりあえず雰囲気を)

  9. こんなやつを作る Node.js MySQL docker-compose.yml コンテナ Docker Compose は docker-compose.yml という設定

    ファイルを使う。これが始まりで あり全て(大袈裟) ブラウザ http://127.0.0.1:3000/ ホスト ( macOS とか ) mysql -h 127.0.0.1 ターミナル
  10. version: '3' services: app: image: 'node:14.13.1-stretch' ports: - '3000:3000' volumes:

    - .:/myapp working_dir: /myapp tty: true db: image: 'mysql:8' ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password docker-compose.yml 設定はこれだけ…! 意味不明…
  11. version: '3' services: app: image: 'node:14.13.1-stretch' ports: - '3000:3000' volumes:

    - .:/myapp working_dir: /myapp tty: true db: image: 'mysql:8' ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password docker-compose.yml バージョン指定、今は 3 が最新 サービスというのがコンテナの 集まりのこと。ここに作りたい コンテナの定義を書く サービス名、自由に付けられ る。サービス内の各コンテナの 通信はこの名前がホスト名とし て使われる 使いたい Docker イメージを指定する ホストとコンテナで通信したいポートを指定す る。これで http://0.0.0.0:3000 でコンテナ 内部のサーバに、ホストからアクセスできる ボリューム…ファイルが集まっている やつ。あとで説明する。ちょっとわか りにくい コンテナを起動させ続けるための指 定。コンテナによって必要だったり不 要だったり コンテナに環境変数を渡すことができ る。コンテナにあらかじめ用意されて いるものもある。例えば MySQL は root ユーザのパスワードをこれで指定 できる 設定はこれだけ…! 意味不明…
  12. $ mkdir node-app $ cd node-app $ touch docker-compose.yml #

    エディタで編集 $ docker-compose up -d Starting node-app_app_1 ... done Starting node-app_db_1 ... done ターミナル 起動してみる DockerCompose はディレクトリ名がプロジェクト名に なる。全く同じディレクトリ名で、別の docker-compose.yml を作るとややこしいことになるの で避けた方が良い
  13. $ docker-compose exec app npm init -y ターミナル exec でコンテナ内部のコマンド実行

    docker-compose exec サービス名 コマンド これで指定サービス(コンテナ)内部のコマンドをホス ト側から実行ができる。 $ docker-compose exec app bash ターミナル コンテナ内部に入りたい場合は bash を実行する npm init をして Node.js プロジェクト初期化する
  14. ところで docker-compose って 打つのダルくないですか? alias fig=docker-compose ~/.bashrc DockerCompose の前身 fig

    コマンドにエイリアスを はれば、めちゃくちゃ楽(Docker 社に買収された) $ docker-compose exec app command $ fig exec app command ターミナル
  15. const http = require('http'); const hostname = '0.0.0.0'; const port

    = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello DockerCompose!'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); index.js 適当にサーバを作る 3000 番ポートで Hello world 的なコンテンツを返すだ けの Web サーバを作る
  16. $ docker-compose exec app npx node index.js Server running at

    http://0.0.0.0:3000/ ターミナル サーバを起動する あとはブラウザで http://0.0.0.0:3000/ にアクセスを すると Hellow DockerCompose! が表示されるはず
  17. $ docker-compose exec db mysql -u root -ppassword \ -e

    'create database sample;' $ docker-compose exec db mysql -u root -ppassword \ sample -e 'create table users (id int);' $ docker-compose exec db mysql -u root -ppassword \ sample -e 'insert into users values (1),(2);' ターミナル 適当にテーブルを作る DB コンテナの MySQL に対して SQL を実行してデータベース とテーブルを作って、ダミーデータを登録する docker-compose exec コマンドを使わなくても、mysql コマン ドや GUI ツールでも接続ができるので好みの方法で
  18. const http = require('http'); const mysql = require('mysql2'); const connection

    = mysql.createConnection({ host: 'db', user: 'root', password: 'password', database: 'sample' }); const hostname = '0.0.0.0'; const port = 3000; const server = http.createServer((req, res) => { connection.query( 'SELECT id FROM `users`', function(err, results, fields) { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); results.forEach((row) => { res.write(`id: ${row['id']}\n`); }); res.end(); } ); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); }); index.js DB に接続して表示する ここがポイント app コンテナから MySQL コンテ ナに接続するには、 docker-compose.yml で定義し たサービス名、ここでは db を指 定すると通信することができる
  19. $ docker-compose stop Stopping node-app_app_1 ... done Stopping node-app_db_1 ...

    done ターミナル 停止してみる これでコンテナを停止できる。コンテナは眠っているだけ なので、また up すれば起動して使える。down するとコ ンテナを削除してしまうので注意。 また、stop する場所は docker-compose.yml ファイル がある場所でないとダメ(--file オプションで指定可能)
  20. None
  21. 簡単でしょ? 本当か?

  22. ネットワークについて

  23. app Node.js db MySQL コンテナ 127.0.0.1:3000 ホスト ( macOS とか

    ) 127.0.0.1:3306 ブラウザや ターミナルなど ホスト側のやつ services: app: ports: - '3000:3000' db: ports: - '3306:3306' docker-compose.yml db app host.docker.internal コンテナとホストの関係
  24. ファイル共有とボリューム

  25. 実行はコンテナでしたいけど ファイルの編集はホストでしたい

  26. Node.js コンテナ ホスト 保存場所は3種類ある ファイル /my-volume ボリューム ./host-dir DockerVM /host-dir

    DockerVM は Docker for Mac/Windows の場合 ❶ ❷ ❸ 参照 参照
  27. Node.js コンテナ ホスト 保存場所は3種類ある ファイル /my-volume ボリューム ./host-dir DockerVM /host-dir

    DockerVM は Docker for Mac/Windows の場合 ❶ ❷ ❸ 参照 参照 ここしか、ホスト(macOS)から ファイルに直接アクセスすること はできない
  28. Node.js コンテナ ホスト 保存場所は3種類ある ファイル /my-volume ボリューム ./host-dir DockerVM /host-dir

    DockerVM は Docker for Mac/Windows の場合 コンテナ内部にあるファイル 特に何もしなくても通常はこれ 注意点はコンテナを削除すると ファイルも一緒に削除されるこ と Dockerfile もしくは docker-compose.yml で設定 して作るボリューム。場所自体 は DockerVM 環境(ホスト 側)にある。コンテナを削除し ても残るので永続化として使わ れる ホスト側のファイルをマウントする形 ファイルの編集はホストでやりたい場合 に使う。ファイルの同期速度が遅いのが ネック docker volume ls コマンドで ボリューム一覧が見られる ❶ ❷ ❸ 参照 参照
  29. マウントの設定 version: '3' services: app: image: 'node:14.13.1-stretch' volumes: - .:/host-dir

    - shared-volume:/shared-volume - /my-volume volumes: shared-volume: docker-compose.yml ❸ホストをマウント [ホスト側パス] : [コンテナ側パス] ❷ボリュームをマウント(名前付き) [ボリューム名] : [コンテナ側パス] トップレベルの volumes: でボリュー ム名を定義する必要がある 特徴としては、他のサービス(コンテ ナ)がマウントすることが可能 ❷ボリュームをマウント(無名) [コンテナ側パス] 名前なしでボリュームを作る (ユニークな ID が自動でつく) このサービス(コンテナ)でしか利用できない
  30. マウントの確認 $ docker inspect $(docker-compose ps -q app) "Mounts": [

    { "Type": "bind", "Source": "/host_mnt/Users/zaru/Desktop/mysql-con/node-app", "Destination": "/host-dir", "Mode": "rw", "RW": true, "Propagation": "rprivate" }, { "Type": "volume", "Name": "node-app_shared-volume", "Source": "/var/lib/docker/volumes/node-app_shared-volume/_data", "Destination": "/shared-volume", "Driver": "local", "Mode": "rw", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "0fdffba5e61811ce46b4384cd982593fc5dd928ba7ac1078f37b5cbbdb1adba7", "Source": "/var/lib/docker/volumes/0fdffba5e61811ce46b4384cd982593fc5dd928ba7ac1078f37b5cbbdb1adba7/_data" , "Destination": "/my-volume", "Driver": "local", "Mode": "rw", "RW": true, "Propagation": "" } ], ターミナル ❸ホストをマウント Mac 側のディレクトリをマウントし ているのがわかる ❷ボリュームをマウント(名前付き) DockerVM 内部にあり、Name が指 定したものになっている ❷ボリュームをマウント(無名) Docker が自動でつけた ID が付いている docker inspect はコンテナの情報 をいろいろ表示するやつ。 docker-compose で立ち上げたコン テナ名はプロジェクト名の prefix が 付いていて覚えにくいので docker-compose ps コマンドで出 力したものを利用している
  31. よく出てくる : は 左がホストで、右がコンテナ /host/dir:/host_dir_in_docker docker run -v $(pwd):/myapp \

    -p 3333:3000 こちらはホスト側の指定 こちらはコンテナ側の指定
  32. Dockerfile と docker-compose.yml

  33. version: '3' services: app: image: 'node:14.13.1-stretch' ports: - '3000:3000' volumes:

    - .:/myapp working_dir: /myapp tty: true db: image: 'mysql:8' ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password docker-compose.yml DockerHub のイメージのみ これは DockerHub で公開されている イメージ名を指定しているパターン
  34. version: '3' services: app: build: context: . dockerfile: ./Dockerfile ports:

    - '3000:3000' volumes: - .:/myapp working_dir: /myapp tty: true db: image: 'mysql:8' ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password docker-compose.yml Dockerfile を指定する image の代わりに build を使うと Dockerfile を指定できる context は Docker が参照するディ レクトリの位置。基本的にはプロジェ クトのトップディレクトリが使いやす いので . を指定することが多い Dockerfile のパス Dockerfile を指定することでオリジナルのイメージを使って開発 環境を作ることができる。基本的には、アプリケーションコンテ ナは Dockerfile を使い、MySQL などのミドルウェアは公式のイ メージをそのまま使うことが多い
  35. 簡単でしょ? ウヘェ

  36. ありがとうございました! 次回は... 未定! 質問感想など呟いていただけると嬉しいです! - ハッシュタグ #mu_zaru - ツイッター情報 @mu_vpoe

    , @zaru チャンネル登録 Good ボタン お願いします! ムーザルちゃんねる