dockerでLaravel8またはLaravel9の環境構築したい….
こんな疑問を解決します。
今回構築する環境は以下です。※Macを使用
PHP8.1
Laravel8orLaravel9
apache2.4
Mysql8.0
phpmyadmin
Composer 2.2.9
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
docker環境を構築する前提
まずdockerを使うために、Docker Desktopをインストールしましょう。
ターミナル上で以下のように表示されればdockerは使えます。
% docker --version
Docker version 20.10.7, build f0df350
Laravelのdocker環境を構築する
Laravelのdocker環境構築手順は以下のステップになります。
作成するファイル構造は以下になります。
今回は、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
もしわからないことがあれば、気軽に下記にあるコメントやツイッターでご質問ください。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント