【市場価値がわかる】エンジニア転職におすすめなサイト

【Docker】Laravel8・PHP8・mysql8でマイグレーションまで実行する【Laravel9対応】

dockerでLaravel8またはLaravel9の環境構築したい….

こんな疑問を解決します。

今回構築する環境は以下です。※Macを使用

PHP8.1
Laravel8orLaravel9
apache2.4
Mysql8.0
phpmyadmin
Composer 2.2.9

Contents

docker環境を構築する前提

まずdockerを使うために、Docker Desktopをインストールしましょう。

Docker Desktop公式

ターミナル上で以下のように表示されればdockerは使えます。

% docker --version
Docker version 20.10.7, build f0df350

Laravelのdocker環境を構築する

Laravelのdocker環境構築手順は以下のステップになります。

STEP
コンテナ作成に必要なファイルを作成する
STEP
コンテナをビルドし、起動する
STEP
Laravelをインストールする
STEP
Laravelの初期設定し、マイグレーションを実行

作成するファイル構造は以下になります。

今回は、todoアプリを作成する想定で、ルートディレクトリがlaravel_todoになります。

任意のプロジェクト名にしてください。

私の環境では、/Desktop/projects/larave_todoのようにしています。
※好みなので、/Desktop/larave_todoとかなんでもいいです。

// Desktopに移動
~ % cd Desktop

// projectsに移動※もしprojectsがないなら、mkdir projectsで作成する。
Desktop % cd projects

// laravel_todoを作成
projects % mkdir laravel_todo

// laravel_todoに移動
projects % cd laravel_todo

// 現在のディレクトリを確認
laravel_todo % pwd
/Desktop/projects/laravel_todo

// code .でvscodeを開く
laravel_todo % code .

私はエディターはVScodeを使っているので、code .でvscodeがひらけます。

dockerコンテナを作成するための最終的な構造は以下のようになります。

まずは、以下のように空のファイルでいいのでファイルを作成しましょう。

laravel_todo
├── docker
│   ├── mysql
│   │   └── my.cnf←MySQLの設定
│   └── php
│       ├── 000-default.conf←ルートディレクトリなどの設定
│       ├── Dockerfile←php・apacheなどの設定
│       └── php.ini←phpの設定
├── src←laravelのソースが入る(今は中身空でOK)
├── .env←ポート番号とか書く
├── .gitignore←git管理しないファイルを記載する
└── docker-compose.yml←コンテナの設計書

画像にすると以下です。※phpmyadmin/sessionsがありますが、コンテナ作成後に自動的に作成されるので今は作成しなくていいです。

srcは空ファイルでOKです。(後でLaravelがインストールされるから。)

それではそれぞれのファイルにdocker環境を構築するためのコードを書いていきます。

docker/mysql/my.cnf

# MySQLサーバーへの設定
[mysqld]
# 文字コード/照合順序の設定
character-set-server = utf8mb4
collation-server = utf8mb4_bin

# タイムゾーンの設定
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# mysqlオプションの設定
[mysql]
# 文字コードの設定
default-character-set = utf8mb4

# mysqlクライアントツールの設定
[client]
# 文字コードの設定
default-character-set = utf8mb4

docker/php/000-default.conf

<VirtualHost *:80>
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/public
       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
       <Directory /var/www/public>
           AllowOverride All
           Require all granted
       </Directory>
</VirtualHost>

docker/php/Dockerfile

# どんなdockerイメージを利用して構築をするか
FROM php:8.1-apache

RUN cd /etc/apache2/mods-enabled \
    && ln -s ../mods-available/rewrite.load

# 設定ファイルをdockerコンテナ内のPHP、Apacheに読み込ませる
ADD php.ini /usr/local/etc/php/
ADD 000-default.conf /etc/apache2/sites-enabled/

# Composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

# ミドルウェアインストール
RUN apt-get update \
    && apt-get install -y \
    git \
    zip \
    unzip \
    libzip-dev \
    vim \
    libpng-dev \
    libpq-dev \
    libfreetype6-dev \
    libjpeg-dev \
    libonig-dev \
    && docker-php-ext-install pdo pdo_mysql mysqli zip

RUN docker-php-ext-configure gd \
    --with-freetype=/usr/include/ \
    --with-jpeg=/usr/include \
    && docker-php-ext-install -j$(nproc) gd

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

RUN composer self-update --2

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN rm -rf node_modules
RUN apt-get install -y nodejs
RUN npm install npm -g n --save-dev cross-env
RUN npm cache clear --force
RUN npm install webpack --save
RUN npm install node-sass --nodedir=/usr/bin/node

WORKDIR /var/www/

docker/php/php.ini

[PHP]
default_charset = UTF-8
[Date]
date.timezone = Asia/Tokyo

docker-compose.yml
※${WEB_PORT}などは後ほど解説。

version: '3'

services:
  php:
    # ./docker/phpの内容(Dockerfile,php.ini,000-default)でphpコンテナ作成する
    build: ./docker/php
    # ./srcと/var/wwwをマウント。./srcと/var/wwwの変更内容が同期される。
    volumes:
      - ./src:/var/www
    # 使用するポート番号を指定
    ports:
      - ${WEB_PORT}:80
    # コンテナ名を指定
    container_name: ${PHP_CONTAINER}

  # laravelの設定の際に、DB_HOSTとして指定される
  mysql:
    image: mysql:8.0
    # mysql8の認証プラグイン。この記述がないと弾かれる。
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
    ports:
        # ${DB_PORT}と.envのWEB_PORTが対応
        - ${DB_PORT}:3306
    environment:
        MYSQL_DATABASE: ${DB_NAME}
        MYSQL_USER: ${DB_USER}
        MYSQL_ROOT_PASSWORD: ${DB_PASS}
        MYSQL_PASSWORD: ${DB_PASS}
    container_name: ${MYSQL_CONTAINER}

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql #mysqlサービス名を指定
      - PMA_USER=${PMA_USER}
      - PMA_PASSWORD=${PMA_PASS}
    links:
      - mysql
    ports:
      - ${PMA_PORT}:80
    volumes:
      - ./phpmyadmin/sessions:/sessions
    container_name: ${PMA_CONTAINER}

.gitignore
※.gitignoreにgit管理しないファイルを記載します。これで、Githubに指定したファイルがアップされることはありません。

.env
phpmyadmin/sessions/

.gitignore記載前

.gitignore記載後。.envファイルをgit管理しないので以下の画像のようにファイル名が薄くなります。

.envファイルがなんのためにあるのか?ですが、ポート番号やDB名、パスワードなど他人にはみられてほしくない情報を記載していきます。

docker-compose.ymlに${WEB_PORT}と書かれている箇所は、.envのDB_PORT=を参照する仕組みです。

ポート番号やDBポートは他のプロジェクトと被らないようにすることが注意点です。

プロジェクトAでWEB_PORT=8888使用していて、プロジェクトBでもWEB_PORT=8888ならば、ポート重複によるdocker側でエラーが起きます。

最後に、.envファイルにdocker-compose.ymlと対応する情報を記載していきましょう。

WEB_PORT=18888
DB_PORT=18889
DB_NAME=laravel_todo
DB_USER=root
DB_PASS=secret
PMA_PORT=18890
PMA_USER=root
PMA_PASS=secret
PHP_CONTAINER=laravel_todo_php
MYSQL_CONTAINER=laravel_todo_mysql
PMA_CONTAINER=laravel_todo_pma

ファイルを作成して必要な記述が終わったので、いよいよdockerのコンテナをビルドし起動していきます。

コンテナを作成し、起動する

コンテナを作成し起動するって聞くと、なんだか難しそうですがコマンド一つでできます。

docker-compose up -d –buildでコンテナを作成し、起動できます。

もし、ビルドできない場合は、
・docker-compose downでコンテナ削除
→docker-compose up –buildでコンテナ作成する
→docker-compose up -dでコンテナ起動する

ポート番号などのエラーでビルドできない
・WEB_PORT、DB_PORT、PMA_PORTが過去のプロジェクトと重複していないようにする。

mysqlのコンテナだけ立ち上がらない
DB_USERやPMA_USERが過去のプロジェクトと重複している可能性がある
→重複しないようにする
例)DB_USER=root DB_PASS=secret→DB_USER=laravel_todo DB_PASS=secretにするなど。
※ありがたいことにこの記事で2回、3回別々のプロジェクトでdocker環境構築していると起きると思います。
また、ボリュームを削除すると解消する可能性もあります。

ビルド時間は長いので、気長に待ちましょう。※5〜10分ぐらいかかります。

laravel_todo % docker-compose up -d
Creating network "laravel_todo_default" with the default driver
Building php
[+] Building 3.7s (23/23) FINISHED                                              
 => [internal] load build definition from Dockerfile                       0.2s
 => => transferring dockerfile: 1.44kB                                     0.1s
 => [internal] load .dockerignore                                          0.1s
....
....
Creating laravel_todo_php ... done
Creating laravel_todo_mysql   ... done
Creating laravel_todo_pma ... done

上記のように…doneとなればコンテナ起動できています。

念の為、docker psコマンドまたはdocker desktopでも確認してみましょう。
※起動できていれば、以下のようにコンテナの情報が出てきます。

laravel_todo % docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
eab4c900bce1   phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   0.0.0.0:18890->80/tcp, :::18890->80/tcp                  laravel_todo_pma
ce92cbdbc390   laravel_todo_php        "docker-php-entrypoi…"   7 minutes ago   Up 6 minutes   0.0.0.0:18888->80/tcp, :::18888->80/tcp                  laravel_todo_php
b9dd3a8c92b0   laravel_todo_mysql      "docker-entrypoint.s…"   7 minutes ago   Up 5 minutes   33060/tcp, 0.0.0.0:18889->3306/tcp, :::18889->3306/tcp   laravel_todo_mysql

docker desktop↓となっていればOKです。

※2022-03-21追記
laravel_todo_pma RUNNING PORT: 18890
laravel_todo_php RUNNING PORT:18888
laravel_todo_mysql RUNNING PORT:18889

改めて、コンテナが起動しているのが確認できました。

現段階では、localhost:18890でphpmyadminにアクセスできます。
※18888のweb画面の方は、まだLaravel入れていないので404エラーとかサーバーエラーの画面になると思います。

docker側ができたので、Laravelをインストールしていきます。

Laravelをインストールする

Laravelをインストールする流れですが、PHPのコンテナに入り、そこでLaravelのインストールを実行します。

コンテナに入るには、docker exec CONTAINER IDまたはNAMES -it bashを実行します。
docker psしたときに、CONTAINER IDは一番左に、NAMESは一番右にあります。
例)
CONTAINER IDでコンテナに入る場合
docker exec ce92cbdbc390 -it bash

NAMESでコンテナに入る場合
docker exec laravel_todo_php -it bash

PHPのコンテナに入る

docker psを実行したときにPHPコンテナは上から2番目にあります。CONTAINER IDはce92cbdbc390、NAMESはlaravel_todo_phpです。

laravel_todo % docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
eab4c900bce1   phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   0.0.0.0:18890->80/tcp, :::18890->80/tcp                  laravel_todo_pma
ce92cbdbc390   laravel_todo_php        "docker-php-entrypoi…"   7 minutes ago   Up 6 minutes   0.0.0.0:18888->80/tcp, :::18888->80/tcp                  laravel_todo_php
b9dd3a8c92b0   laravel_todo_mysql      "docker-entrypoint.s…"   7 minutes ago   Up 5 minutes   33060/tcp, 0.0.0.0:18889->3306/tcp, :::18889->3306/tcp   laravel_todo_mysql

NAMESでコンテナに入ってみます。

laravel_todo % docker exec -it laravel_todo_php bash
root@ce92cbdbc390:/var/www# 

var/www#となればコンテナに入れています。

Laravelをインストールする前にバージョンを確認しておきます。

// phpのバージョン
/var/www# php -v
PHP 8.1.4 (cli) (built: Mar 18 2022 18:20:14) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.4, Copyright (c) Zend Technologies

// apacheのバージョン
/var/www# apachectl -v
Server version: Apache/2.4.52 (Debian)
Server built:   2022-01-03T21:27:14

// composerのバージョン
/var/www# composer -V
Composer version 2.2.9 2022-03-15 22:13:37

// exitでコンテナから抜ける
/var/www# exit
exit

mysqlコンテナに入って、バージョンを確認する(PHPのコンテナでmysqlのバージョン確認してもそもそもコンテナ違うから確認できない。)

こちらもNAMESを使ってmysqlのコンテナに入ります。

// コンテナの情報確認
laravel_todo % docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS          PORTS                                                    NAMES
eab4c900bce1   phpmyadmin/phpmyadmin   "/docker-entrypoint.…"   37 minutes ago   Up 37 minutes   0.0.0.0:18890->80/tcp, :::18890->80/tcp                  laravel_todo_phpmyadmin_1
ce92cbdbc390   laravel_todo_php        "docker-php-entrypoi…"   37 minutes ago   Up 37 minutes   0.0.0.0:18888->80/tcp, :::18888->80/tcp                  laravel_todo_php_1
b9dd3a8c92b0   laravel_todo_mysql      "docker-entrypoint.s…"   37 minutes ago   Up 35 minutes   33060/tcp, 0.0.0.0:18889->3306/tcp, :::18889->3306/tcp   laravel_todo_mysql_1

// mysqlのコンテナに入って、バージョン確認する
laravel_todo % docker exec -it laravel_todo_mysql bash
root@fcd79d873997:/# mysql --version
mysql  Ver 8.0.26 for Linux on x86_64 (MySQL Community Server - GPL)

// コンテナから抜ける
/# exit
exit

バージョンの確認ができたので、いよいよLaravelをインストールします。

docker-compose.ymlに
php:
build: ./docker/php
volumes:
– ./src:/var/www
とあります。
srcのソースとPHPコンテナのvar/www#を同期させるという意味です。
つまり、var/www#で実行した内容は、srcに反映されるということ。

mysqlのコンテナからは抜けて、再度PHPコンテナに入ります。(ここにlaravelをインストールするのに必要なPHPやcomposerなどが入っているため。)

laravel_todo % docker exec -it laravel_todo_php bash

Laravel8をインストールする場合

root@ce92cbdbc390:/var/www# composer create-project --prefer-dist "laravel/laravel=8.*" .
Creating a "laravel/laravel=8.*" project at "./"
Installing laravel/laravel (v8.6.11)
  - Downloading laravel/laravel (v8.6.11)
  - Installing laravel/laravel (v8.6.11): Extracting archive
...
...
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
No publishable resources for tag [laravel-assets].
Publishing complete.
> @php artisan key:generate --ansi
Application key set successfully.

// Laravelのバージョンを確認
/var/www# php artisan -V
Laravel Framework 8.83.0

Laravel9をインストールする場合

root@ce92cbdbc390:/var/www# composer create-project --prefer-dist "laravel/laravel=9.*" .
...
...
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
No publishable resources for tag [laravel-assets].
Publishing complete.
> @php artisan key:generate --ansi
Application key set successfully.

// Laravelのバージョンを確認
/var/www# php artisan -V
Laravel Framework 9.5.1

// npmのバージョン
/var/www# npm -v
8.5.5

// nodeのバージョン
/var/www# node -v
v12.22.11

srcにLaravelがインストールされます。

WEB_PORTは18888で設定しているので、http://localhost:18888にアクセスすると、Laravelの初期画面が表示されます。

Laravelの初期設定をし、マイグレーションを実行する

Laravelのインストールができたので、Laravelの.envファイルなどを設定してデータベースに繋げます。

srcの中にLaravelのソースが入っているので、その.envを以下のように修正します。※コンテナを作成したときの.envとは別(src > .envであることに注意)

APP_NAME=Laravel_todo
....
DB_CONNECTION=mysql
DB_HOST=mysql # (デフォルトの127.0.0.1だとエラー。docker-compose.ymlのmysqlのサービス名にすること)
DB_PORT=3306 # (3306にすること。よくあるミスで${DB_PORT}:3306とdocker-compose.ymlで設定しているので、${DB_PORT}の値にしたくなるが、それだと接続できない)
DB_DATABASE=laravel_todo # ${DB_NAME}で設定した値
DB_USERNAME=root # ${DB_USER}で設定した値
DB_PASSWORD=secret # ${DB_PASS}で設定した値

DB_HOSTとDB_PORTがややこしいですね。
docker-compose.ymlでは、以下のように設定しています。
サービス名というのはmysqlとしているところ。
mysql:←DB_HOST
build: ./docker/mysql
ports:
– ${DB_PORT}:3306←DB_PORT

もし、
db:
build: ./docker/mysql
ports:
– ${DB_PORT}:3306←DB_PORT
としていれば、DB_HOST=dbになります。

次に、config/app.phpを変更します。(任意)

'name' => env('APP_NAME', 'Laravel_todo'),←アプリ名
...
'timezone' => 'Asia/Tokyo',
...
...
'locale' => 'ja',

Laravel側の設定も終わったので、マイグレーションを実行します。

上記で正しくデータベースの設定ができていれば下記のようにマイグレーションは成功し、設定が違えばマイグレーションエラーが出ます。

エラーが出た場合は、設定の見直しをしましょう。

マイグレーションエラーで、Access denied(権限エラー)が出ることありますが、その際はコンテナのボリュームを削除し、コンテナを作り直して再度Laravelを入れるようにします。
参考記事:docker + mysql が接続できない

/var/www# php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (171.74ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (128.83ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (85.78ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (145.31ms)

Laravelに既存で備わっているマイグレーションが実行でき、usersテーブルなどが作成できます。

phpmyadminで確認してみると、(URLにlocalhost:18890と入力でアクセス)usersの他にも先ほどマイグレーションで実行した内容がしっかりあることも確認できます。

phpmyadminへのアクセスは、docker Desktopのオレンジで囲ったアイコンをクリックすることでもできます。

これで、dockerでLaravelの環境構築ができました。

Dockerの基本コマンド

コンテナを作成するためにビルド、またはdockerファイルを修正してその変更を反映

% docker-compose up --build

コンテナのイメージ、作成、起動するなら

% docker-compose up -d

コンテナを起動

% docker-compose start

コンテナを再起動

% docker-compose restart

コンテナ停止

 % docker-compose stop

コンテナを停止して削除

 % docker-compose down

コンテナの確認
コンテナIDやコンテナ名、コンテナのステータスやポート番号などを確認できる

% docker ps

コンテナに入る

% docker exec -it コンテナIDまたはNAMES bash

もしわからないことがあれば、気軽に下記にあるコメントやツイッターでご質問ください。

>>転職するのにおすすめのサイトはこちらをクリック
>>副業で稼ぐためにおすすめのサイトはこちらをクリック

スキルを売り買いするならココナラ

オンライン動画学習ならUdemy

コメント

コメントする

CAPTCHA


Contents
閉じる