Laravel 6 用に Docker で PHP 7 + Apache + MySQL 環境を構築
はじめに
今日は Docker 公式イメージを使って Laravel 6 用 の PHP 7 + Apache + MySQL 環境を構築する方法をご紹介します。
Laravel の最新版は執筆時点で 8.x ですが、一番サポート期限が長い 6.x にしました。
- Support Policy (Release Notes - Laravel - The PHP Framework For Web Artisans)
- https://laravel.com/docs/8.x/releases#support-policy
- Docker
- 19.03.1
- Docker Compose
- 1.24.1
- Laravel
- 6.19.1
- Apache
- 2.4.38
- PHP
- 7.4.11
- MySQL
- 8.0.22
1. 下準備
今回のファイル構成です。
/path/to/my-project/
├ docker/
│ ├ initdb/
│ │ └ articles.sql
│ │
│ ├ lara6-php74-apache/
│ │ └ Dockerfile
│ │
│ └ docker-compose.yml
│
└ html/
/docker/initdb/articles.sql はコンテナ初回起動時に実行される SQL で、articles テーブルを作ります。既存データベースがあるプロジェクトを考慮して作っていますが、不要な方は省略しても差し支えありません。
SET CHARACTER_SET_CLIENT = utf8mb4;
SET CHARACTER_SET_CONNECTION = utf8mb4;
CREATE TABLE articles (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
body text NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO articles (id, title, body)
VALUES (NULL, 'テスト1', 'テスト\r\nテスト\r\nテスト');
/docker/lara6-php74-apache/Dockerfile は Web サーバコンテナに PHP 拡張などをインストールするために使うファイルで、内容は次章で紹介します。
/html は Web サーバ のコンテナにマウントします。コンテナ上でここに Laravel 6 をインストールして、ローカルでも編集できるようにします。
この /html フォルダは事前に作っておいてください。
2. 独自の PHP - Apache イメージを生成
公式の PHP イメージ(Apache 付)に PHP 拡張 などを追加した独自のイメージを作ります。これにより今後同様の環境を構築する場合に、各種インストールの手間を省くことができます。
今回作った Dockerfile の内容は以下の通りです。
(解説のためにコメントを多めに入れています)
FROM php:7.4-apache
# Composer のバージョン と ハッシュ値
ARG composer_ver=1.10.16
ARG composer_hash=e494bb438e44b9e4782c16940b229a8c46ea8a3baa9b908bf9db310cd0171ee2
# Composer の保存先
ARG composer_path=/usr/local/bin/composer
RUN apt-get update \
# Composer インストール
&& php -r "copy('https://getcomposer.org/download/$composer_ver/composer.phar', '$composer_path');" \
&& chmod 755 $composer_path \
&& php -r "if (hash_file('sha256', '$composer_path') !== '$composer_hash') { \
echo '!!! Failed to install Composer !!!'; \
unlink('$composer_path'); \
} \
echo PHP_EOL;" \
# Vim (省略可)
&& apt-get install -y vim \
# unzip コマンド (composer create-project で必要)
&& apt-get install -y unzip \
# PDO MySQL 拡張
&& docker-php-ext-install pdo_mysql \
# /var/www/html/public をドキュメントルートに変更
# (必要に応じて)
&& sed -ri -e 's!/var/www/html!/var/www/html/public!g' /etc/apache2/sites-available/*.conf \
# mod_rewrite 有効化
&& a2enmod rewrite
- php Tags - Docker Hub
- https://hub.docker.com/_/php?tab=tags
今回は Laravel インストール用に Composer も自動インストールするようにしています。 バージョンとハッシュの組み合わせは、下記 Composer の公式ページに掲載されています。
現時点ではバージョン 2 系の Composer を使うと、後述するLaravel インストール時に
[RuntimeException] Could not delete /var/www/html のエラーになるのでご注意ください。
(執筆時点の最新版は 2.0.2 です)
- Composer (composer.phar) versions history (Composer)
- https://getcomposer.org/download/#composer-history-caption
Vim やドキュメントルート変更部分につきましては、不要な方は削除してください。
Dockerfile を作ったら、下記コマンドでイメージをビルドします。
今回は my-lara6:php74-apache という名前にしています。
build コマンド末尾の . を忘れないようにご注意ください。
$ cd /path/to/my-project/docker/lara6-php74-apache
$ docker build -t my-lara6:php74-apache .
イメージが正常にビルド出来たかは docker images コマンドで確認できます。 (イメージの一覧が表示されます)
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-lara6 php74-apache abcdef123456 5 minutes ago 468MB
3. コンテナを生成
Docker Compose を使って各種コンテナを作ります。
Compose file の内容は以下の通りです。
version: "3"
services:
# PHP-Apache
myapp-web:
container_name: myapp-web
image: my-lara6:php74-apache
# myapp-db 起動後に myapp-web を起動
depends_on:
- myapp-db
# 80 番ポートを割り当て
ports:
- "80:80"
# ローカル の html フォルダを
# コンテナの /var/www/html にマウント
volumes:
- "../html:/var/www/html"
# MySQL
myapp-db:
container_name: myapp-db
image: mysql:8.0
# 初回起動時に /initdb/articles.sql を実行するためにマウント
# (使わない方は削除してください)
volumes:
- "./initdb:/docker-entrypoint-initdb.d"
environment:
MYSQL_DATABASE: sampledb
MYSQL_USER: sample-user
MYSQL_PASSWORD: hi2mi4i6
MYSQL_ROOT_PASSWORD: mu7ya9to
# phpMyAdmin
myapp-pma:
container_name: myapp-pma
image: phpmyadmin/phpmyadmin:5.0
depends_on:
- myapp-db
ports:
- "8080:80"
environment:
PMA_HOST: myapp-db
PMA_USER: root
PMA_PASSWORD: mu7ya9to
Docker toolbox on windows の場合は volumes でマウントするために、VirtualBox の共有フォルダ設定で /docker/initdb と /html を追加する必要があります。
設定方法は「docker toolbox windows volumes 共有」などで検索すると、みつかると思います。
あとは下記コマンドを実行すれば、コンテナが生成されます。
$ cd /path/to/my-project/docker
$ docker-compose -p my-project up -d
-p オプションについては「Docker Compose の -p オプションで VS Code でのコンテナ管理を便利にする」でご紹介していますので、よろしければご覧ください。
4. Laravel を Composer でインストール
今回は Laravel を Composer を使ってインストールします。
Web サーバの myapp-web コンテナに入って、インストール用のコマンドを入力します。
$ docker exec -it myapp-web bash
root@123456789abc:/var/www/html# cd ../
root@123456789abc:/var/www/# composer create-project --prefer-dist laravel/laravel html "6.*"
- docker exec | Docker Documentation
- https://docs.docker.com/engine/reference/commandline/exec/
- Installing Laravel (Installation - Laravel - The PHP Framework For Web Artisans)
- https://laravel.com/docs/6.x/installation#installing-laravel
- インストール 6.x Laravel
- https://readouble.com/laravel/6.x/ja/installation.html
インストールが完了したら .env のデータベース設定を変更します。
.env の編集はコンテナ内で Vim を使ってもいいですし、ローカル側で行っても OK です。
DB_CONNECTION=mysql
DB_HOST=myapp-db
DB_PORT=3306
DB_DATABASE=sampledb
DB_USERNAME=sample-user
DB_PASSWORD=hi2mi4i6
ローカルの /path/to/my-project/html と コンテナの /var/www/html が同期しない場合は、設定が誤っている可能性があります。
5. 動作確認
5-1. phpMyAdmin にアクセス
docker-compose.yml で phpMyAdmin には 8080 ポートで接続するようにしているので、http://localhost:8080 や http://192.168.99.100:8080 などでアクセスしてください。
(ドメインや IP は設定等により異なります)
上記「1. 下準備」の /initdb/articles.sql を設置している場合は、sampledb に articles テーブルが作られています。
5-2. マイグレーションを使ってみる
Laravel にはデフォルトで users テーブルなどのマイグレーションファイルが含まれています。今回はそれを使ってデータベースの接続確認としましょう。
root@123456789abc:/var/www# cd html
root@123456789abc:/var/www/html# php artisan migrate
phpMyAdmin などで sampledb に users テーブルなどが作られていることをご確認いただければと思います。
5-3. サンプルプログラムを動かしてみる
みなさんご自身で何かしらのコードを作られるかとは思いますが、僕が作ったサンプルをご紹介します。よろしければお使いください。
<?php
namespace App\Http\Controllers;
use App\User;
class UserController extends Controller
{
public function index()
{
self::insertUser();
return view('user.index', ['users' => User::get()]);
}
private static function insertUser()
{
$maxId = User::max('id') ?? 0;
$no = $maxId + 1;
$user = new User;
$user->fill([
'name' => "User{$no}",
'email' => "user{$no}@example.com",
'password' => "dummy",
])
->save();
}
}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>User</title>
</head>
<body>
@foreach ($users as $user)
{{ $user->name }}<br>
@endforeach
</body>
</html>
// ↓ 追加
Route::get('/user', 'UserController@index');
ブラウザで http://localhost/user や http://192.168.99.100/user などにアクセスすれば、ダミーユーザーが 1 件ずつ追加されます。
6. おわりに
Composer での Laravel インストールですが、最初は Composer 2.0.1 で試していて、それで前述の RuntimeException が発生し、原因解明に少し時間がかかりました。
(最初はローカル側でのファイルロックなどを疑っていました)
今回は Composer の 1 系を使うことで対処していますが、今後は 2 系が主流になるので、解決方法を探ってみようと考えています。