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

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

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

mu_zaru

October 15, 2020
Tweet

More Decks by mu_zaru

Other Decks in Programming

Transcript

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

    面設計をつくることで す。英語の勉強してる。 ムー zaru @zaru CTO, Love 赤貝, JavaScript, Firebase, Web Components. Twitter フォロー お願いします!
  2. こんなやつを作る Node.js MySQL docker-compose.yml コンテナ Docker Compose は docker-compose.yml という設定

    ファイルを使う。これが始まりで あり全て(大袈裟) ブラウザ http://127.0.0.1:3000/ ホスト ( macOS とか ) mysql -h 127.0.0.1 ターミナル
  3. 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 設定はこれだけ…! 意味不明…
  4. 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 ユーザのパスワードをこれで指定 できる 設定はこれだけ…! 意味不明…
  5. $ 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 を作るとややこしいことになるの で避けた方が良い
  6. $ docker-compose exec app npm init -y ターミナル exec でコンテナ内部のコマンド実行

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

    コマンドにエイリアスを はれば、めちゃくちゃ楽(Docker 社に買収された) $ docker-compose exec app command $ fig exec app command ターミナル
  8. 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 サーバを作る
  9. $ 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! が表示されるはず
  10. $ 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 ツールでも接続ができるので好みの方法で
  11. 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 を指 定すると通信することができる
  12. $ docker-compose stop Stopping node-app_app_1 ... done Stopping node-app_db_1 ...

    done ターミナル 停止してみる これでコンテナを停止できる。コンテナは眠っているだけ なので、また up すれば起動して使える。down するとコ ンテナを削除してしまうので注意。 また、stop する場所は docker-compose.yml ファイル がある場所でないとダメ(--file オプションで指定可能)
  13. 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 コンテナとホストの関係
  14. Node.js コンテナ ホスト 保存場所は3種類ある ファイル /my-volume ボリューム ./host-dir DockerVM /host-dir

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

    DockerVM は Docker for Mac/Windows の場合 コンテナ内部にあるファイル 特に何もしなくても通常はこれ 注意点はコンテナを削除すると ファイルも一緒に削除されるこ と Dockerfile もしくは docker-compose.yml で設定 して作るボリューム。場所自体 は DockerVM 環境(ホスト 側)にある。コンテナを削除し ても残るので永続化として使わ れる ホスト側のファイルをマウントする形 ファイルの編集はホストでやりたい場合 に使う。ファイルの同期速度が遅いのが ネック docker volume ls コマンドで ボリューム一覧が見られる ❶ ❷ ❸ 参照 参照
  16. マウントの設定 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 が自動でつく) このサービス(コンテナ)でしか利用できない
  17. マウントの確認 $ 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 コマンドで出 力したものを利用している
  18. よく出てくる : は 左がホストで、右がコンテナ /host/dir:/host_dir_in_docker docker run -v $(pwd):/myapp \

    -p 3333:3000 こちらはホスト側の指定 こちらはコンテナ側の指定
  19. 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 で公開されている イメージ名を指定しているパターン
  20. 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 などのミドルウェアは公式のイ メージをそのまま使うことが多い