はじめに
こんにちは。以前、LaradockでLaravelの開発環境を作っていました。ひとまずLaravelを触ってみたい時はそれで十分ですが、ほとんどチュートリアルのコピペで環境構築が終わってしまうので、dockerやdocker-composeが何をしているのかよく分からないままでした。
Laravel以外の環境構築もDockerで行えるようになっておきたいですし、今回は自力でdocker-composeを書いてローカル環境を構築してみます。
環境はmacOS High Sierra 10.13.6、Docker Desktop 2.0.0.2がインストール済みであることを前提とします。
nginxでwebサーバを立てる
適当なディレクトリを決めて、その中で作業します。どこでも構いませんが、今回は~/test
として、必要なコンテナを構築する情報をdocker-compose.yml
に記述していきます。
1 2 3 | $mkdir~/test&&cd$_1 $mkdir-p./docker/web $vi./docker-compose.yml |
1 2 3 4 5 6 7 8 9 | version:"3" services: web: image:nginx:latest ports: -80:80 volumes: -./docker/web/default.conf:/etc/nginx/conf.d/default.conf -.:/var/www/html |
image: nginx:latest
で、DockerHub上にあるnginxの最新版のDockerイメージを指定できます。ローカルにイメージがあればそれを使い、無ければダウンロードされます。ports
はそのままポート番号です。左側がホスト側、右側がコンテナ側です。上記の場合はいずれもhttp通信のデフォルトである80番を指定しています。
例えば8000:80
と記述した場合、ブラウザからアクセスする際はhttp://ホスト名:8000
となります。volumes
でコンテナと共有したいパスを指定します。ホスト側で作成したdefault.conf
を、コンテナ側の同ファイルと置き換えます。
ポートと同じくホスト側パス:コンテナ側パス
の順で記述します。
default.conf作成
nginxの設定ファイルです。ひとまず最低限の設定のみ記述し、PHP関連の設定は後で追記します。
1 2 3 4 5 6 7 8 9 | server{ listen80; root /var/www/html; index index.html; access_log/var/log/nginx/access.log; error_log /var/log/nginx/error.log; } |
index.html作成
nginxの動作を確認できればよいので、htmlの中身は1行で構いません。
1 | $touch./index.html&&echo"<h1>Hello nginx.</h1>">./index.html |
nginxコンテナ起動
1 2 3 | $docker-compose up-d Creating network"test_default"with the defaultdriver Creating test_web_1...done |
ブラウザでhttp://localhost
にアクセスしてHello nginx.
の文字が出てくればOKです。
nginxでPHP-FPMを動作させる
docker-compose.yml編集
静的コンテンツが見れるようになりましたので、次はPHP-FPMです。docker-compose.yml
にPHP-FPMコンテナの情報を記述していきます。
また、nginxにもPHP-FPMとの関連性を追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | version:"3" services: web: image:nginx:latest ports: -80:80 volumes: -./docker/web/default.conf:/etc/nginx/conf.d/default.conf -.:/var/www/html depends_on: -php-fpm php-fpm: image:php:7.3-fpm-alpine volumes: -.:/var/www/html |
image: php:7.3-fpm-alpine
で、nginxと同様にdockerhub上のイメージを指定します。PHP-FPMのイメージはたくさんあるのですが、ここでは軽量なalpine Linuxのイメージを使っています。depends_on:
はコンテナの依存関係を示します。上記のように記述することで「php-fpmコンテナが起動したらwebコンテナを起動する」という意味になり、起動の順番を制御できます。
default.conf編集
nginxの設定ファイルdefault.conf
にもPHP-FPMの設定を追記します。fastcgi_pass
の項にPHP-FPMへの接続情報を記述します。docker-compose.yml
でPHP-FPMの名前として指定しているphp-fpm
を記述し、PHP-FPMのデフォルトポートである9000番を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | server{ listen80; root /var/www/html; index index.php index.html index.htm; access_log/var/log/nginx/access.log; error_log /var/log/nginx/error.log; location~\.php${ fastcgi_split_path_info^(.+\.php)(/.+)$; fastcgi_pass php-fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name; fastcgi_param PATH_INFO$fastcgi_path_info; } } |
index.php作成
index.html
と同様に、起動を確認できれば充分です。
1 | $touch./index.php&&echo"<?phpphpinfo();?>">./index.php |
コンテナ起動
初回起動ではイメージのダウンロードが実行されます。最後2行のdone
が表示されたら起動OKです。再度http://loalhost
にアクセスしてみましょう。
1 2 3 4 5 6 | $docker-compose up-d ... 中略 ... Creating test_php-fpm_1...done Recreating test_web_1 ...done |
MariaDBを立ち上げる
データベースはMariaDBを使用します。MySQLでも問題ありませんが、設定や接続方法はほとんど一緒(らしい)なので、試しに使ってみようという程度のチョイスです。
docker-compose.yml編集
db:
以下がMariaDBに関する記述です。また、php-fpm
にも上述のdepends_on
を追記しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | version:"3" services: web: image:nginx:latest ports: -80:80 volumes: -./docker/web/default.conf:/etc/nginx/conf.d/default.conf -.:/var/www/html depends_on: -php-fpm php-fpm: image:php:7.3-fpm-alpine volumes: -.:/var/www/html depends_on: -db db: image:mariadb:latest ports: -3306:3306 environment: MYSQL_ROOT_PASSWORD:root MYSQL_USER:test MYSQL_PASSWORD:test MYSQL_DATABASE:testdb volumes: -./db-data:/var/lib/mysql |
environment
以下にMariaDBの情報を設定しています。MariaDB最新の10系はMySQL5.7がベースとなっており、MySQL用の設定がそのまま使えるようです。
MYSQL_ROOT_PASSWORD:
rootユーザーの初期パスワードです。MYSQL_USER
root以外の初期ユーザーを設定できます。MYSQL_PASSWORD
↑で設定した初期ユーザーのパスワードです。MYSQL_DATABASE
を指定することで、MariaDBコンテナに接続する際のデータベース名を定義できます。データベースが無い場合は作成されます。
コンテナ起動
docker-compose up -d
でMariaDBコンテナも起動するようになります。
1 2 3 | Creating test_db_1...done Recreating test_php-fpm_1...done Recreating test_web_1 ...done |
接続確認
PHPからMariaDBへの接続はLaravelインストール後に設定しますので、まずはMariaDBが立ち上がっていることの確認のみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #MariaDBコンテナに接続する $docker-compose exec db sh # testdbに接続する $mysql-utest-ptestdb # MYSQL_PASSWORDの値を入力する Enter password: Welcome tothe MariaDB monitor. Commands endwith;or\g. Your MariaDB connection id is9 Server version:10.3.13-MariaDB-1:10.3.13+maria~bionic mariadb.org binary distribution Copyright(c)2000,2018,Oracle,MariaDB Corporation Ab andothers. Type'help;'or'\h'forhelp.Type'\c'toclear the current input statement. MariaDB[testdb]> |
Laravelインストール
ようやくLaravelです。ComposerやPHP拡張など、Laravelのインストールと動作に必要なパッケージを用意します。php-fpm
コンテナの中でコマンドを実行してもよいのですが、docker-compose
コマンド実行時に自動でよしなにやってくれるように、docker-compose.yml
を編集します。
php:7.3-fpm-alpine
イメージには上述のパッケージが含まれていませんので、別途Dockerfile
を作成し、そこにインストールコマンドを記述します。
1 2 3 4 5 6 | php-fpm: build:./docker/php volumes: -.:/var/www/html depends_on: -db |
build:
に記述したパスにDockerfile
を作成します。$ mkdir ./docker/php && vi ./docker/php/Dockerfile
1 2 3 4 5 6 7 8 9 | FROM php:7.3-fpm-alpine RUN apk--update add\ &&apk add build-base curl git zip unzip vim RUN cd/usr/bin&&curl-sS https://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer RUN apk add libxml2-dev curl-devel$PHPIZE_DEPS RUN pecl install xdebug RUN docker-php-ext-install pdo_mysql mbstring xml curl session tokenizer json RUN docker-php-ext-enable pdo_mysql mbstring xml curl session tokenizer json xdebug WORKDIR/var/www/html |
RUN
以降をシェルコマンドとして、コンテナ起動時に実行します。apk add
でパッケージインストールを行います。alpine以外のイメージだと大抵はapt-get
で、CentOSなどのRedHat系で言うyum
ですね。$PHPIZE_DEPS
を指定することで、phpizeに必要なパッケージが自動でインストールされます。phpizeはPHP拡張モジュールを動的にビルドするのに必要で、これがないとPHP拡張を導入する際、いちいちPHP本体をビルドし直すことになってしまいます。pecl install xdebug
はdockerとは関係なく、peclライブラリを入れる時のコマンドそのままですね。必要に応じてimagickやredisなどお好きなものを。docker-php-ext-install
でPHP拡張をインストールし、docker-php-ext-enable
で有効化します。意味こそコマンド名そのままですが、dockerコンテナ上ではこういう書き方になるんですね。
MariaDBはMySQL用のライブラリで接続可能ですのでpdo_mysqlを入れます。その他mbstringなど最低限必要そうなものを入れていますが、ここもお好みで。RUN composer
の行はLaravelのインストールを実行するコマンドです。testapp
はプロジェクト名ですので、ここは自由にどうぞ。
コンテナ再構築
docker-compose up -d
を実行しましょう。パッケージのダウンロード/インストール/ビルドが一斉に走りますので、結構かかります。
上述のDockerfileの最後にLaravelインストールのコマンドを記述すればコンテナ構築と同時にインストールも実行されますが、Dockerfileに書くとコンテナ起動時に毎回Laravelのインストールが走ってしまうので、あとでコンテナに入って実行します。
Laravelインストール
1 2 3 | $docker-compose exec php-fpm sh /var/www/html# composer create-project --prefer-dist laravel/laravel testapp |
ここでもLaravelが依存するComposerのパッケージ群がモリモリ入りますので、数分お待ち下さい。
Laravelのwelcomeページを表示する
Laravelの公開ディレクトリをドキュメントルートにするため、default.conf
を編集します。location
の中に下記の1行を追記し、docker-compose restart
で変更を反映してください。
1 2 3 4 5 6 7 8 9 10 | location~\.php${ root/var/www/html/testapp/public;←追記 fastcgi_split_path_info^(.+\.php)(/.+)$; fastcgi_pass php-fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name; fastcgi_param PATH_INFO$fastcgi_path_info; } |
LaravelからMariaDBに接続する
Laravelプロジェクト内の.env
ファイルに、docker-compose.yml
で設定した接続情報を記述します。DB_HOST
にはMariaDBのコンテナ名が入ります。この場合はdb
ですね。
1 2 3 4 5 6 7 8 | $vi testapp/.env DB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=testdb DB_USERNAME=test DB_PASSWORD=test |
マイグレーション実行
php-fpm
コンテナ内で実行します。DB接続に成功すれば、最初から入っているマイグレーションファイルが実行されます。
1 2 3 4 5 6 7 8 9 | $docker-compose exec php-fpm sh /var/www/html# cd testapp/ /var/www/html/testapp# php artisan migrate Migration table created successfully. Migrating:2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating:2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table |
上記のようなメッセージが表示されればOKです。お疲れ様でした。
さいごに
Laradockはチュートリアルが充実していたおかげで、docker-composeについてはほぼ知識ゼロでも構築ができてしまっていました。今回docker-compose.yml
を調べながら一項目ずつ書くことで、それぞれがどのような意味で何が実行されているのか、多少は把握することができるようになりました。