フレームワーク
 

DockerでLaravel環境構築(2021/02)

       

Homesteadしか使用したことがなかったのですが、最近Docker上にLaravelの開発環境を構築したので忘れないうちにまとめたいと思います。最初にLaravelコンテナ単体で動作確認を行い、MySQLコンテナ、Nginxコンテナを追加して、最終的には3つのコンテナで動作する環境を構築します。

ディレクトリ構成

最終的に下記のような構成になります。

project
├── docker
│   ├── db
│   │   ├── data
│   │   └── my_cnf
│   ├── nginx
│   │   └── default.conf
│   └── php
│       └── Dockerfile
|       └── php.ini
├── docker-compose.yml
└── src
    └── sample

1. Laravelコンテナ作成

任意の場所に作業ディレクトリを作成し、作成したディレクトリに移動します。
本環境ではDesktop配下に作成しています。

$ mkdir project
$ cd project

docker-compose.ymlファイル作成

Laravelのインストールを行うコンテナを作成するために、docker-compose.ymlを作成します。
複数のコンテナを一度に作成、制御することが可能になり効率的に環境構築を行うことができます。今回は1つずつコンテナを作成するため、最初は1つのコンテナの設定情報のみ記述しますが、後ほどMySQL、Nginxの設定もファイルに追記していきます。

下記が作成した、docker-compose.ymlになります。

version: '3.7'

services:
  php:
    build:
      context: ./docker/php
      dockerfile: Dockerfile
    container_name: php
    volumes:
      - ./src:/var/www/html
    ports:
      - "8000:8000"
  • version:docker-composeのフォーマットバージョンを指定しています。バージョンによって記述方法が異なります。
  • services:コンテナを表しており、他のコンテナと区別することができます。後ほど追加するDBはdb、Nginxはnginxとしてservicesを設定します。
  • context:Dockerfileへのパス
  • dockerfile:Dockerfile名
  • volumes:ローカルのディレクトリとコンテナ上のディレクトリのリンクを設定しています。docker-compose.ymlのディレクトリ直下のsrcからコンテナ内の/var/www/htmlにアクセスすることができます。
  • ports:ローカル側のポートとコンテナ側のポートを設定しています。8000ポートにアクセスするとコンテナ側の8000にアクセスすることができます。

Dockerfile作成

Dockerfileにはコンテナに利用するイメージ情報と、そのイメージに追加するパッケージや構成変更を行うコマンドを記述することができます。各ユーザーが個別の設定をしておくことで全く同じ環境を構築することができます。

LaravelではPHPを利用する為「php:7.4-fpm-alpine」のイメージを利用します。


FROM php:7.4-fpm-alpine

RUN docker-php-ext-install pdo pdo_mysql

Laravelコンテナ作成

docker-compose.ymlとDockerfileが作成できたので、下記コマンドでコンテナの作成を行います。docker-composeコマンドは実行時にdocker-compose.ymlファイルの中身を確認するためのdocker-compose.ymlファイルが存在するディレクトリで実行してください。

$ docker-compose up -d

オプション-dはバックグラウンドでコンテナを実行してくれます。
イメージがローカルにない場合は、自動でダウンロードしてくれてビルドを行うため、初回は少し時間がかかります。ローカルにイメージがある場合は、そちらを利用してくれるので短い時間で処理が完了します。

次にdocker-compose ps aコマンドを実行し、コンテナのステータスを確認します。StatusがUpになっていれば正常に起動しています。

$  docker-compose ps -a
Name              Command              State                Ports              
-------------------------------------------------------------------------------
php    docker-php-entrypoint php-fpm   Up      0.0.0.0:8000->8000/tcp, 9000/tcp

Laravelのインストール

コンテナの作成が完了したので、Laravelのインストールを行います。Laravelをインストールするためには、PHPのライブラリ管理ツール「composer」が必要になりますので、ダウンロードします。ダウンロード方法は割愛させていただきます。

ダウンロードしたcomposerを利用して./src/sampleディレクトリにLaravelをインストールします。
コマンド最後のsampleはプロジェクト名になりますので、任意の名前を付けてください。

composer create-project laravel/laravel

開発サーバの起動

Webサーバの設定を行っていないので開発サーバを起動することで画面を表示できるように下記の設定を行います。

$ docker exec -it php php artisan serve --host=0.0.0.0 --port=8000

このコマンド実行後、ブラウザで127.0.0.1:8000または0.0.0.0:8000にアクセスするとLaravelの初期画面が表示されます。

laravel/uiインストール

ユーザー認証の画面を作成するために、laravel/uiパッケージをcomposerを使用して、インストールを行います。

$ composer require laravel/ui

laravel/uiパッケージのインストールが完了したら、php artisanコマンドを実行します。

$ docker exec -it php php artisan ui vue --auth
Vue scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
Authentication scaffolding generated successfully.

上記メッセージにも表示されている通り、npm install && npm run devでJavaScript関係のパッケージインストールとビルドを行います。

$ npm install && npm run dev

開発サーバを起動した状態でアクセスするとログイン画面を表示できることを確認します。

Laravelからデータベースに接続することができないため、ユーザを登録を行うとエラーが発生してしまいます。
次にMySQLコンテナを作成することで、ユーザー登録ができるようになります。

2. MySQLコンテナ作成

MySQLコンテナを利用してアプリケーションで生成されるデータを保存します。

docker-compose.ymlファイルへ追記

laravelコンテナを作成する際に記述した、docker-compose.ymlのservicesにmysqlを追加します。

version: '3.7'

services:
  php:
    build:
      context: ./docker/php
      dockerfile: Dockerfile
    container_name: php
    volumes:
      - ./src:/var/www/html
    ports:
      - "8000:8000"

    mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "4306:3306"
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my_conf:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: laravel
    
  • image:Laravelコンテナの場合はDockerfileを利用しましたが、MySQLコンテナではイメージをそのまま使用するため「mysql:8.0」を設定しています。
  • container_name:ここでは「mysql」というコンテナ名を設定しています。
  • ports:MySQLのデフォルトポートの3306を利用しローカル環境から4306ポートを使ってMySQLのデータベースに接続することができます。ローカルでMySQLデータベースが動作しているため、ポートが重複しないように設定しています。
  • volumes:今回は、2つ設定していますが、ローカルディレクトリの./docker/db/dataにはMySQLコンテナに保存されているデータ/var/lib/mysqlと紐づけています。./docker/db/my_confはMySQLコンテナの設定ファイルが保存されているディレクトリ/etc/mysql/conf.dと紐づけています。
  • environment:MySQLのrootユーザのパスワードとデータベースの設定のみ行っています。

mysqlの設定ファイル作成

docker-compose.ymlに設定したvolumesのdataとmyconfディレクトリを作成します。

/User/◯◯/Desktop/project

$ mkdir db
$ cd db
$ mkdir data
$ mkdir my_conf

my_confの下には設定ファイルmysql8.0.cnfファイルを作成し、日本語対応できるように文字コードの設定を行います。

[mysqld]
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4

MySQLコンテナ作成

MySQLコンテナを作成する前に、docker-compose.ymlを変更したので下記コマンドでコンテナを再構築します。

$ docker-compose up -d

正常に起動しているか確認します。

$ docker-compose ps -a
Name               Command              State                 Ports              
---------------------------------------------------------------------------------
mysql   docker-entrypoint.sh mysqld     Up      0.0.0.0:4306->3306/tcp, 33060/tcp
php     docker-php-entrypoint php-fpm   Up      0.0.0.0:8000->8000/tcp, 9000/tcp

データベース接続

Laravelからデータベースへ接続するために.envファイルの環境変数を変更します。srcディレクトリ内にある.envファイルを開いてデータベースの接続に関する設定を下記のように設定します。

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=password

設定が完了したら、php artisan migrateコマンドを実行してデータベースにテーブルが作成されるか確認しましょう。
接続が正常に行われた場合は下記のようなメッセージが表示されます。

$ docker-compose exec php php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.09 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.03 seconds)

ここまでの設定でLaravelコンテナとMySQLコンテナ接続完了になります。次で最後のコンテナになります。

3. Nginxコンテナ作成

ここまでは開発サーバを起動してLaravelへアクセスを行っていましたがNginxコンテナを作成し、Webサーバ経由でLaravelにアクセスします。

docker-compose.yml追記

docker-compose.ymlついてはphpとmysqlコンテナと同様に追加していきます。

version: '3.7'

services:
  php:
    build:
      context: ./docker/php
      dockerfile: Dockerfile
    container_name: php
    volumes:
      - ./src:/var/www/html
    ports:
      - "9000:9000"

    mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "4306:3306"
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my_conf:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: laravel

    nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
      - mysql
    
  • image:
  • container_name:nginxというコンテナ名を設定しています。
  • ports:ローカルから8080でアクセスできるように8080:80を設定しています。
  • volumes:volumesの設定の1つはphpと同じ設定を行っています。もう一つはnginxの設定ファイルを指定しています。設定ファイルはこの後作成します。
  • depends_on:コンテナの依存関係を定義しています。依存は起動の順序に関係し、phpとmysqlが起動してからnginxが起動するようになっています。

Nginxと通信する際にポート9000を利用するため、phpのポートを先ほどまで8000:8000に設定していましたが、9000:9000に変更を行ってください。

nginxの設定ファイル作成

mysql同様、ローカル上に設定ファイルを保存するnginxディレクトリを作成します。

/User/◯◯/Desktop/project
$ mkdir nginx

nginxディレクトリ内にNginxの設定ファイルdefault.confファイルを作成し、下記のように記述します。

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

7行目rootの/var/www/html/publicがlaravelをインストールしたディレクトリ直下にあるpublicと一致している必要があります。

nginxコンテナ作成

Nginxの設定が完了したので、コンテナの作成を行いますが、docker-compose.ymlを変更したのでコンテナの再構築を忘れずに行います。

$ docker-compose up -d

正常に起動しているか確認もします。

$ docker-compose ps -a
Name               Command              State                 Ports              
---------------------------------------------------------------------------------
mysql   docker-entrypoint.sh mysqld     Up      0.0.0.0:4306->3306/tcp, 33060/tcp
nginx   nginx -g daemon off;            Up      0.0.0.0:8080->80/tcp  
php     docker-php-entrypoint php-fpm   Up      0.0.0.0:9000->9000/tcp, 9000/tcp

StatusがUpの状態で、ブラウザから127.0.0.1:8080にアクセスしてLaravelのトップページが表示されたらNginx経由でLaravelにアクセスできています。ユーザの登録やログインが行えるか一通り動作確認を行ってください。

トップページ以外で404が表示される場合は、nginxの設定ファイルの記述に間違いがある場合があります。

以上でDockerでLaravel開発環境構築の完成です。お疲れ様でした。

おまけ

各種ファイル変更時

docker-compose.yml Dockerfile
イメージ 再構築なし 再構築あり

docker-compose build
コンテナ 再構築あり

docker-compose up -d
再構築あり

docker-compose up -d
 
  • このエントリーをはてなブックマークに追加