Slide 1

Slide 1 text

YouTube Live (2020.10.15 Thur. 21:00~)

Slide 2

Slide 2 text

話す人 現役のエンジニア二人 赤貝が好きな CTO と デザイン勉強中のエンジニア @mu_vpoe 最近の仕事は figma で画 面設計をつくることで す。英語の勉強してる。 ムー zaru @zaru CTO, Love 赤貝, JavaScript, Firebase, Web Components. Twitter フォロー お願いします!

Slide 3

Slide 3 text

話すこと - DockerCompose について - とりあえず環境を作ってみる - ネットワークとボリューム - Dockerfile の利用について

Slide 4

Slide 4 text

開発環境を作りたい! …なるべく手軽に!

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Docker じゃダメなの?

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

こんなやつを作る Node.js MySQL docker-compose.yml コンテナ Docker Compose は docker-compose.yml という設定 ファイルを使う。これが始まりで あり全て(大袈裟) ブラウザ http://127.0.0.1:3000/ ホスト ( macOS とか ) mysql -h 127.0.0.1 ターミナル

Slide 10

Slide 10 text

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 設定はこれだけ…! 意味不明…

Slide 11

Slide 11 text

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 ユーザのパスワードをこれで指定 できる 設定はこれだけ…! 意味不明…

Slide 12

Slide 12 text

$ 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 を作るとややこしいことになるの で避けた方が良い

Slide 13

Slide 13 text

$ docker-compose exec app npm init -y ターミナル exec でコンテナ内部のコマンド実行 docker-compose exec サービス名 コマンド これで指定サービス(コンテナ)内部のコマンドをホス ト側から実行ができる。 $ docker-compose exec app bash ターミナル コンテナ内部に入りたい場合は bash を実行する npm init をして Node.js プロジェクト初期化する

Slide 14

Slide 14 text

ところで docker-compose って 打つのダルくないですか? alias fig=docker-compose ~/.bashrc DockerCompose の前身 fig コマンドにエイリアスを はれば、めちゃくちゃ楽(Docker 社に買収された) $ docker-compose exec app command $ fig exec app command ターミナル

Slide 15

Slide 15 text

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 サーバを作る

Slide 16

Slide 16 text

$ 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! が表示されるはず

Slide 17

Slide 17 text

$ 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 ツールでも接続ができるので好みの方法で

Slide 18

Slide 18 text

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 を指 定すると通信することができる

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

簡単でしょ? 本当か?

Slide 22

Slide 22 text

ネットワークについて

Slide 23

Slide 23 text

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 コンテナとホストの関係

Slide 24

Slide 24 text

ファイル共有とボリューム

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

マウントの設定 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 が自動でつく) このサービス(コンテナ)でしか利用できない

Slide 30

Slide 30 text

マウントの確認 $ 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 コマンドで出 力したものを利用している

Slide 31

Slide 31 text

よく出てくる : は 左がホストで、右がコンテナ /host/dir:/host_dir_in_docker docker run -v $(pwd):/myapp \ -p 3333:3000 こちらはホスト側の指定 こちらはコンテナ側の指定

Slide 32

Slide 32 text

Dockerfile と docker-compose.yml

Slide 33

Slide 33 text

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 で公開されている イメージ名を指定しているパターン

Slide 34

Slide 34 text

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 などのミドルウェアは公式のイ メージをそのまま使うことが多い

Slide 35

Slide 35 text

簡単でしょ? ウヘェ

Slide 36

Slide 36 text

ありがとうございました! 次回は... 未定! 質問感想など呟いていただけると嬉しいです! - ハッシュタグ #mu_zaru - ツイッター情報 @mu_vpoe , @zaru チャンネル登録 Good ボタン お願いします! ムーザルちゃんねる