今日のゴール
- Docker についてふんわり分かる
- dockcer-compose でイメージのビルドができる
- 最初につらつら概要が書かれているのでいきなり始めたい人はハンズオンから始めてください
Dockerとは
- 軽量仮想化技術
- 標準化されたソフトウェアをコンテナとして管理できる
コンテナと仮想マシン(VM)の比較
https://www.docker.com/resources/what-container から引用
コンテナ
- ハードウェアではなくOSシステムを仮想化する
- コードと依存関係を一緒にパッケージ化するアプリ層の抽象概念
- 同じマシン上っで複数のコンテナを実行し、OSカーネルを他のコンテナと共有できる
- VMよりも占有するスペースが少ないのでより多くのアプリケーションを動かすことができる
仮想マシン
- 仮想マシン(VM)は1台のサーバーを多数のサーバーに変える物理ハードウェアの抽象概念
- 各VMにはOS、アプリケーション、バイナリ、ライブラリの完全なコピーが含まれているので、VMの起動が遅くなりがち
Dockerを体験する
- 前提として
docker
コマンド、docker-compose
コマンドが実行できる環境であること-
https://docs.docker.com/ から自分のOSにあったバイナリをインストールする
- 一番上のメニューにある Get Docker > For Desktops から選ぶ
-
https://docs.docker.com/ から自分のOSにあったバイナリをインストールする
ubuntuを起動する
手始めに Ubuntu の Docker イメージを起動します
$ docker run -it ubuntu /bin/bash
-
-t
はtty
をアロケートする(端末名を取得する) -
-i
は interactive(STDINを開いたままにする)
この辺はオプションを外してみるとどういう動きかわかるので、どういう動きをするかそれぞれ確かめてみよう
$ docker run -i ubuntu /bin/bash
$ docker run -t ubuntu /bin/bash
$ docker run ubuntu /bin/bash
docker run は何をしているか
-
docker run
はdocker create
とdocker start
を同時にやっている
$ docker create -i -t ubuntu /bin/bash
1a2fa0c21916b2f323498d740c74f2a0fc6ac832268e9c906500dcc7c09612c7
$ docker start -a -i 1a2fa0c21916
root@1a2fa0c21916:/#
-
docker create
をすると特定のイメージ(例はubuntu)上に書き込み可能なコンテナレイヤを作成します。表示される英数字はコンテナのIDです。 -
docker start
をすると作成したコンテナを起動することができます。イメージのIDは全てを指定する必要はなく、特定できる長さで大丈夫です。
phpを起動する
$ docker run -it php /bin/bash
- 起動してコンテナの中に入ったらphpのバージョンを確認してみよう
- PHPのバージョンはそのときの最新バージョンが表示されます。
root@79b00020abf8:/# php -v
PHP 7.3.3 (cli) (built: Mar 27 2019 01:07:43) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.3, Copyright (c) 1998-2018 Zend Technologies
root@79b00020abf8:/# php -i
(phpinfo() の結果が表示されます)
image はどこから持ってきているのか
- DockerのイメージはDocker Hubから引っ張ってきています
- https://hub.docker.com/
- 開発を始めるときはDocker Hubでイメージを探して引っ張ってくると便利です
- nginx
- php-apache
- redis
- mysql など
- Amazon ECRやGoogle GCRを指定して引っ張ってくることも可能です
- 会社で使っている場合はこっちの方が多いですね
Dockerをカスタマイズする
DockerfileでDockerイメージをカスタマイズする
- Docker Hubから持ってきたイメージはだいたい最小構成なので、使う用途にあわせてカスタマイズが必要になります
- コンテナに入って必要なものをインストールすることもできますが、
Dockerfile
に記述することで、手順がコード化できるので他の人も再現可能な状態になります
Dockerfile
FROM php:7.4-cli
RUN pecl install redis-5.2.1 \
&& pecl install xdebug-2.9.4 \
&& docker-php-ext-enable redis xdebug
- このDockerfileをbuildして実行してみましょう
$ docker build . -t docker-handson/php:7.4-cli
$ docker run --rm -it docker-handson/php:7.4-cli php -v
docker-composeで複数のコンテナで構成されるアプリを使う
- だいたいのアプリは複数のコンテナを組み合わせて使います
- webサーバー + データベース
- proxyサーバー + アプリサーバー + データベース + キャッシュサーバー
-
docker-compose
を使うことでコンテナ間の通信設定、コンテナのオプション設定、ビルド、コンテナの起動をまとめて行うことができるようになります
ハンズオン
- お題: dockerでlaravelの環境をつくる
- PHP+Apache と mysql の構成でつくって、Laravelを動かすことをできるようにします
準備
- 自分の環境で
docker
コマンドdocker-compose
コマンドを使えるようにします - 作業用のフォルダを作ります
- 必要であれば
git init
してgit管理しておくとメモを使えます
- 必要であれば
$ mkdir docker-handson;
$ cd docker-handson && mkdir docker
サンプルアプリケーションを作ります
-
composer
を実行するだけのimageをpullしてlaravel
のプロジェクトを作成します - Windowsユーザーの方は
$PWD
の環境変数ががないので、$PWD
ところは自分の作業するディレクトリ名に読み替えて指定してください
Dockerfileを作ります
docker/Dockerfile
FROM php:7.4-apache
RUN \
docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-configure mysqli --with-mysqli=mysqlnd --with-libdir=lib/x86_64-linux-gnu/ \
&& docker-php-ext-install mysqli \
&& docker-php-ext-install pdo_mysql
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
RUN a2enmod rewrite
WORKDIR /var/www
docker-composeファイルを作ります
docker-compose.yaml
version: '3'
services:
app:
build:
context: ./docker
volumes:
- ./my-laravel:/var/www/my-laravel
ports:
- "8080:80"
working_dir: /var/www/my-laravel
environment:
APACHE_DOCUMENT_ROOT: /var/www/my-laravel/public
TZ: "Asia/Tokyo"
mysql:
image: mysql:5.7
ports:
- "3306:3306"
environment:
MYSQL_USER: root
MYSQL_DATABASE: laravel
MYSQL_ALLOW_EMPTY_PASSWORD: 1
TZ: "Asia/Tokyo"
コンテナを起動してブラウザでアクセスしてみましょう
$ docker-compose up -d
起動できたら http://localhost:8080/ でアクセスします。Laravelのデフォルト画面が表示できたらOKです。
Advance
ここからは応用なので、自分たちで考えてみよう!
1. appのコンテナからmysqlに接続してみよう
やりたいこと
- CLIで接続するにはどうしたらよいだろうか?
- Laravelのappから接続できるようにしてみよう
- PHPUnitで接続するテストを書いて実行してみよう
ヒント
- dockerコンテナに入らないでコマンドを接続するにはどうしたらいいでしょうか?
-
docker-compose exec
で実現できます
-
- このテストコードが正常に通れば接続できています
src/my-laravel/tests/Unit/DbConnectTest.php
<?php
namespace Tests\Unit;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class DbConnectiTest extends TestCase
{
public function testConnectDatabase()
{
$this->assertTrue(DB::statement('SELECT NOW()'));
}
}
- phpunix.xmlの設定値は適宜変更してください
2. 接続するコンテナを増やしてみよう
やりたいこと
- キャッシュ用にRedisを配置して、appコンテナから接続できるようにしよう
- port8080でアクセスするのが面倒なので、localhost/my-laravel でアクセスできるように、フロントサーバーを配置しよう
ヒント
- コンテナを増やすには
docker-compose.yaml
に追加します - frontサーバーにはnginxを使ってみよう
- nginxの設定で、
/my-laravel
にアクセスがきたら、appコンテナにリクエストを回そう
- nginxの設定で、
3. 別のアプリを増やしてみよう
やりたいこと
- 別のアプリをつくることになったので、コンテナ群にアプリを増やしたい
- front, db, redisは共通のコンテナを使いたい
ヒント
ここまできたらヒントなし!チャレンジしてみましょう。