Docker 入門
Laravel アプリケーション実行環境を Docker で構築する
Docker を使って Laravel アプリケーションを公開する
ここでは Laravel アプリケーションを本番環境で公開するための実行環境を Docker で構築します.具体的には下図の通り,Web サーバには nginx を利用し http://localhost/ という URL でリクエストを受け付けます.Web サーバへのリクエストは PHP をインストールしたアプリケーションサーバに転送され処理されます.さらに,バックエンドのデータベースは MySQL のコンテナで運用します.
このページの Docker サンプルコードは GitHub の Laravel02Nginx フォルダで公開しています.また,Laravel のコードも GitHub で公開しています.
ファイル/フォルダ構成
任意の新規ディレクトリを作成し,その中に次の構成でディレクトリとファイルを設置します.なお,Laravel プロジェクトは laravel ディレクトリに設置します.Docker の Git リポジトリには Laravel プロジェクトのコードが含まれないように laravel/.gitignore を設置しておきます.また,ログファイルも Git に含まれないように logs/nginx/.gitignore も設置しておきます.さらに,.env ファイルには MySQL のユーザ名とパスワードなどを保存しますが,やはりそのファイルが Git のリポジトリに含まれないように .gitignore を設置します.
Laravel02Nginx % tree -a -F ⏎
./
├── .env
├── .env.example
├── .gitignore
├── docker-compose.yml
├── laravel/
│ └── .gitignore
├── logs/
│ └── nginx/
│ └── .gitignore
├── mysql/
│ ├── Dockerfile
│ ├── my.cnf
│ └── script/
│ └── init-db.sql
├── nginx/
│ └── conf.d/
│ └── default.conf
├── php/
│ ├── Dockerfile
│ └── php.ini
└── Readme.md
9 directories, 13 files
Laravel02Nginx %
全体設計
全体の設計図である docker-compose.yml は次のような内容にします.つまり,3つのサービスと1つのボリュームから構成されます.Web サーバとなる nginx コンテナ,アプリケーションサーバとなる laravel_php コンテナ(サービス名 app),データベースサーバとなる laravel_mysql コンテナ(サービス名 mysql) というコンテナと,データベースを保存するためのボリューム(ボリューム名 mysqlvolume) からなる構成です.
docker-compose.yml
services:
nginx:
image: nginx:1.25.5
container_name: nginx
ports:
- 80:80
volumes:
- ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
- ./laravel/example-laravel-app:/var/www/html
- ./logs/nginx:/var/log/nginx
depends_on:
- app
app:
build:
context: .
dockerfile: ./php/Dockerfile
args:
IMAGE: ${PHP_IMAGE}
container_name: laravel_php
volumes:
- ./php/php.ini:/usr/local/etc/php/php.ini
- ./laravel/example-laravel-app:/var/www/html
depends_on:
- mysql
mysql:
build:
context: .
dockerfile: ./mysql/Dockerfile
args:
IMAGE: ${MYSQL_IMAGE}
container_name: laravel_mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- mysqlvolume:/var/lib/mysql
- ./mysql/script:/docker-entrypoint-initdb.d
ports:
- 3306:3306
volumes:
mysqlvolume:
Laravel のプロジェクトは laravel/example-laravel-app に配置しますが,これ自体が Docker の Git リポジトリに含まれないように laravel/.gitignore に次の指定をしておきます.
laravel/.gitignore
*
Nginx の設定
Nginx は docker-compose.yml の3行目にあるとおり,nginx:1.25.5 イメージをそのまま利用してコンテナを起動します.Nginx の設定ファイルには次のような nginx/conf.d/default.conf を利用することにします.ここで,23行目の app は docker-compose.yml のサービス名 app と一致させていることに注意してください.また,Nginx と FastCGI (php-fpm) という組合せで PHP の実行プロセスを処理することにも注意してください.
server {
listen 80;
server_name localhost;
root /var/www/html/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ [^/]\.php(/|$) {
fastcgi_pass app:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_hide_header X-Powered-By;
include fastcgi_params;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_param HTTP_PROXY "";
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Nginx のアクセスログ (access.log および error.log) は log/nginx/ に格納されます.これらのログファイルが Git のリポジトリに含まれないように log/nginx/.gitignore は次の内容にします.
log/nginx/.gitignore
*
PHP-FPM の設定
次に,PHP のアプリケーションサーバとなる Docker イメージを設計します.まず,利用する Docker イメージを .env で指定します.PHP-FPM (FastCGI Process Manager) は負荷の高いサイトに主に役立ついくつかの機能を備えた主要な PHP FastCGI 実装です.
.env(抜粋)
# PHP
PHP_IMAGE=php:8.4.14-fpm
PHP の Docker イメージを設計するための Dockerfile は次の内容とします.具体的には php-fpm ベースイメージのアップデートを実施し,いくつかのコマンド (git, curl など) をインストールした後,PHP 拡張モジュールを Docker にインストールするヘルパーコマンド (docker-php-ext-install),PHP から MySQL データベースへのアクセスを可能にするためのドライバ (pdo_mysql) をインストールしています.
php/Dockerfile
ARG IMAGE
FROM ${IMAGE}
RUN apt-get update \
&& apt-get install -y git curl zip unzip \
&& docker-php-ext-install pdo_mysql
WORKDIR /var/www
PHP の設定は次のとおりとします.
php/php.ini
[PHP]
post_max_size = 100M
upload_max_filesize = 100M
variables_order = EGPCS
MySQL の設定
続いて MySQL の準備を行います.ベースイメージの指定とユーザ名,パスワードは .env に設定します.ここで,管理者パスワード MYSQL_ROOT_PASSWORD とユーザ (docker-user) のパスワード MYSQL_PASSWORD には複雑な文字列を設定するようにしてください.
.env(抜粋)
# MySQL
# MYSQL_IMAGE=arm64v8/mysql:8.4
MYSQL_IMAGE=mysql:8.4
MYSQL_ROOT_PASSWORD=password
MYSQL_USER=docker-user
MYSQL_PASSWORD=secret
MySQL はここやここと同じように日本語文字の文字化けが発生しないように Docker イメージのビルドを次のとおり設定します.
mysql/Dockerfile
ARG IMAGE
FROM ${IMAGE}
RUN microdnf install -y glibc-locale-source glibc-langpack-en && \
microdnf clean all
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
LANGUAGE="ja_JP:ja" \
LC_ALL="ja_JP.UTF-8"
また,MySQL の設定ファイルも次のとおり準備します.
mysql/my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
[client]
default-character-set=utf8mb4
さらに,MySQL コンテナの初回起動時にはボリュームが生成され,データベースの生成,ユーザ権限の設定を行います.この指示は init-db.sql に記載します.ここでユーザ名 (docker-user) は .env で設定したユーザ名と同じものを設定するようにしてください.また,データベース名 (commentsDB) は Laravel プロジェクトの .env にも同じ名称を設定しなければならないことにも注意してください.
mysql/script/init-db.sql
CREATE DATABASE IF NOT EXISTS `commentsDB`;
GRANT ALL PRIVILEGES ON `commentsDB`.* TO 'docker-user';
.env にはパスワードを記載する必要があるため,Git のリポジトリに .env を含めてはなりません.このため,プロジェクト全体の .gitignore には .env を指定します.(macOS の場合は .DS_Store も入れておくと良いでしょう.)
.gitignore
.env
.DS_Store
Laravel プロジェクトの準備
次に,Laravel のプロジェクトについて GitHub から (2) のコマンドでクローンを作成します.ここで,プロジェクトは laravel/example-laravel-app/ 以下に設置することがdocker-compose.yml で指定されていることに注意し,(4) ではダウンロードしたディレクトリ名(フォルダ名)を変更しています.
Laravel02Nginx % cd laravel ⏎ # (1) ディレクトリの移動 laravel % git clone git@github.com:rinsaka/laravel-comment-app-2025.git ⏎ # (2) クローンの作成 Cloning into 'laravel-comment-app-2025'... remote: Enumerating objects: 236, done. remote: Counting objects: 100% (236/236), done. remote: Compressing objects: 100% (138/138), done. remote: Total 236 (delta 78), reused 228 (delta 70), pack-reused 0 (from 0) Receiving objects: 100% (236/236), 101.37 KiB | 313.00 KiB/s, done. Resolving deltas: 100% (78/78), done. laravel % ls ⏎ # (3) ディレクトリ/ファイルの一覧(Windows では dir コマンド) laravel-comment-app-2025 laravel % mv laravel-comment-app-2025 example-laravel-app ⏎ # (4) ディレクトリ名の変更(Windows では ren / rename コマンド) laravel % ls ⏎ # (5) ディレクトリ/ファイルの一覧(Windows では dir コマンド) example-laravel-app laravel %
クローンを作成した Laravel プロジェクトにはセキュリティの関係で .env は含まれておらず,そのサンプルである .env.example が含まれています.次のコマンドで,.env.example のコピーを .env として作成します.
laravel % cd example-laravel-app ⏎ # (1) ディレクトリを移動 example-laravel-app % cp .env.example .env ⏎ # (2) ファイルをコピー(Windows では copy コマンド) example-laravel-app %
.env のデータベースに関する設定を次のとおり編集します.ここで,データベース名 (DB_DATABASE) には init-db.sql に指定した名称と同じものを設定するようにしてください.また,ユーザ名 (DB_USERNAME) とパスワード (DB_PASSWORD) には Docker プロジェクトの .env に設定した内容と同じものを設定してください.
laravel/example-laravel-app/.env(抜粋)
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=commentsDB
DB_USERNAME=docker-user
DB_PASSWORD=secret
GitHub からクローンを作成した Laravel プロジェクトには vendor ディレクトリ以下のファイルが含まれていません.vendor ディレクトリには PHP Composer 他,Laravel の実行に必要な様々なパッケージをインストールする必要があります.次のコマンドで PHP Composer などをインストールします.
example-laravel-app % docker run --rm \
-v $(pwd):/opt \
-w /opt \
laravelsail/php84-composer:latest \
bash -c "composer install" ⏎
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 112 installs, 0 updates, 0 removals
- Downloading doctrine/inflector (2.1.0)
- Downloading doctrine/lexer (3.0.1)
- Downloading webmozart/assert (1.11.0)
- Downloading dragonmantank/cron-expression (v3.4.0)
- Downloading symfony/deprecation-contracts (v3.6.0)
- Downloading fakerphp/faker (v1.24.1)
- Downloading symfony/polyfill-php83 (v1.33.0)
- Downloading symfony/polyfill-mbstring (v1.33.0)
- Downloading symfony/http-foundation (v7.3.4)
- Downloading fruitcake/php-cors (v1.3.0)
- Downloading psr/http-message (2.0)
- Downloading psr/http-client (1.0.3)
- Downloading ralouphie/getallheaders (3.0.3)
- Downloading psr/http-factory (1.1.0)
- Downloading guzzlehttp/psr7 (2.8.0)
- Downloading guzzlehttp/promises (2.3.0)
- Downloading guzzlehttp/guzzle (7.10.0)
- Downloading symfony/polyfill-php80 (v1.33.0)
- Downloading guzzlehttp/uri-template (v1.0.5)
- Downloading symfony/polyfill-intl-grapheme (v1.33.0)
- Downloading symfony/string (v7.3.4)
- Downloading symfony/service-contracts (v3.6.0)
- Downloading symfony/console (v7.3.4)
- Downloading nunomaduro/termwind (v2.3.2)
- Downloading phpoption/phpoption (1.9.4)
- Downloading graham-campbell/result-type (v1.1.3)
- Downloading vlucas/phpdotenv (v5.6.2)
- Downloading symfony/css-selector (v7.3.0)
- Downloading tijsverkoyen/css-to-inline-styles (v2.3.0)
- Downloading symfony/var-dumper (v7.3.4)
- Downloading symfony/polyfill-uuid (v1.33.0)
- Downloading symfony/uid (v7.3.1)
- Downloading symfony/routing (v7.3.4)
- Downloading symfony/process (v7.3.4)
- Downloading symfony/polyfill-php85 (v1.33.0)
- Downloading symfony/polyfill-php84 (v1.33.0)
- Downloading symfony/polyfill-intl-idn (v1.33.0)
- Downloading symfony/mime (v7.3.4)
- Downloading psr/event-dispatcher (1.0.0)
- Downloading symfony/event-dispatcher-contracts (v3.6.0)
- Downloading symfony/event-dispatcher (v7.3.3)
- Downloading psr/log (3.0.2)
- Downloading egulias/email-validator (4.0.4)
- Downloading symfony/mailer (v7.3.4)
- Downloading symfony/error-handler (v7.3.4)
- Downloading symfony/http-kernel (v7.3.4)
- Downloading symfony/finder (v7.3.2)
- Downloading ramsey/collection (2.1.1)
- Downloading brick/math (0.14.0)
- Downloading ramsey/uuid (4.9.1)
- Downloading symfony/translation-contracts (v3.6.0)
- Downloading symfony/translation (v7.3.4)
- Downloading symfony/clock (v7.3.0)
- Downloading nesbot/carbon (3.10.3)
- Downloading monolog/monolog (3.9.0)
- Downloading league/uri-interfaces (7.5.0)
- Downloading league/uri (7.5.1)
- Downloading league/mime-type-detection (1.16.0)
- Downloading league/flysystem-local (3.30.0)
- Downloading league/flysystem (3.30.0)
- Downloading nette/utils (v4.0.8)
- Downloading nette/schema (v1.3.2)
- Downloading dflydev/dot-access-data (v3.0.3)
- Downloading league/config (v1.2.0)
- Downloading league/commonmark (2.7.1)
- Downloading laravel/serializable-closure (v2.0.6)
- Downloading laravel/prompts (v0.3.7)
- Downloading laravel/framework (v12.34.0)
- Downloading laravel/pail (v1.2.3)
- Downloading laravel/pint (v1.25.1)
- Downloading symfony/yaml (v7.3.3)
- Downloading laravel/sail (v1.46.0)
- Downloading nikic/php-parser (v5.6.1)
- Downloading psy/psysh (v0.12.12)
- Downloading laravel/tinker (v2.10.1)
- Downloading hamcrest/hamcrest-php (v2.1.1)
- Downloading mockery/mockery (1.6.12)
- Downloading filp/whoops (2.18.4)
- Downloading nunomaduro/collision (v8.8.2)
- Downloading staabm/side-effects-detector (1.0.5)
- Downloading sebastian/version (5.0.2)
- Downloading sebastian/type (5.1.3)
- Downloading sebastian/recursion-context (6.0.3)
- Downloading sebastian/object-reflector (4.0.1)
- Downloading sebastian/object-enumerator (6.0.1)
- Downloading sebastian/global-state (7.0.2)
- Downloading sebastian/exporter (6.3.2)
- Downloading sebastian/environment (7.2.1)
- Downloading sebastian/diff (6.0.2)
- Downloading sebastian/comparator (6.3.2)
- Downloading sebastian/code-unit (3.0.3)
- Downloading sebastian/cli-parser (3.0.2)
- Downloading phpunit/php-timer (7.0.1)
- Downloading phpunit/php-text-template (4.0.1)
- Downloading phpunit/php-invoker (5.0.1)
- Downloading phpunit/php-file-iterator (5.1.0)
- Downloading sebastian/lines-of-code (3.0.1)
- Downloading sebastian/complexity (4.0.1)
- Downloading sebastian/code-unit-reverse-lookup (4.0.1)
- Downloading phpunit/php-code-coverage (11.0.11)
- Downloading myclabs/deep-copy (1.13.4)
- Downloading phpunit/phpunit (11.5.42)
0/102 [>---------------------------] 0%
11/102 [===>------------------------] 10%
22/102 [======>---------------------] 21%
34/102 [=========>------------------] 33%
42/102 [===========>----------------] 41%
53/102 [==============>-------------] 51%
65/102 [=================>----------] 63%
74/102 [====================>-------] 72%
82/102 [======================>-----] 80%
95/102 [==========================>-] 93%
102/102 [============================] 100%
- Installing doctrine/inflector (2.1.0): Extracting archive
- Installing doctrine/lexer (3.0.1): Extracting archive
- Installing symfony/polyfill-ctype (v1.33.0): Extracting archive
- Installing webmozart/assert (1.11.0): Extracting archive
- Installing dragonmantank/cron-expression (v3.4.0): Extracting archive
- Installing symfony/deprecation-contracts (v3.6.0): Extracting archive
- Installing psr/container (2.0.2): Extracting archive
- Installing fakerphp/faker (v1.24.1): Extracting archive
- Installing symfony/polyfill-php83 (v1.33.0): Extracting archive
- Installing symfony/polyfill-mbstring (v1.33.0): Extracting archive
- Installing symfony/http-foundation (v7.3.4): Extracting archive
- Installing fruitcake/php-cors (v1.3.0): Extracting archive
- Installing psr/http-message (2.0): Extracting archive
- Installing psr/http-client (1.0.3): Extracting archive
- Installing ralouphie/getallheaders (3.0.3): Extracting archive
- Installing psr/http-factory (1.1.0): Extracting archive
- Installing guzzlehttp/psr7 (2.8.0): Extracting archive
- Installing guzzlehttp/promises (2.3.0): Extracting archive
- Installing guzzlehttp/guzzle (7.10.0): Extracting archive
- Installing symfony/polyfill-php80 (v1.33.0): Extracting archive
- Installing guzzlehttp/uri-template (v1.0.5): Extracting archive
- Installing symfony/polyfill-intl-normalizer (v1.33.0): Extracting archive
- Installing symfony/polyfill-intl-grapheme (v1.33.0): Extracting archive
- Installing symfony/string (v7.3.4): Extracting archive
- Installing symfony/service-contracts (v3.6.0): Extracting archive
- Installing symfony/console (v7.3.4): Extracting archive
- Installing nunomaduro/termwind (v2.3.2): Extracting archive
- Installing voku/portable-ascii (2.0.3): Extracting archive
- Installing phpoption/phpoption (1.9.4): Extracting archive
- Installing graham-campbell/result-type (v1.1.3): Extracting archive
- Installing vlucas/phpdotenv (v5.6.2): Extracting archive
- Installing symfony/css-selector (v7.3.0): Extracting archive
- Installing tijsverkoyen/css-to-inline-styles (v2.3.0): Extracting archive
- Installing symfony/var-dumper (v7.3.4): Extracting archive
- Installing symfony/polyfill-uuid (v1.33.0): Extracting archive
- Installing symfony/uid (v7.3.1): Extracting archive
- Installing symfony/routing (v7.3.4): Extracting archive
- Installing symfony/process (v7.3.4): Extracting archive
- Installing symfony/polyfill-php85 (v1.33.0): Extracting archive
- Installing symfony/polyfill-php84 (v1.33.0): Extracting archive
- Installing symfony/polyfill-intl-idn (v1.33.0): Extracting archive
- Installing symfony/mime (v7.3.4): Extracting archive
- Installing psr/event-dispatcher (1.0.0): Extracting archive
- Installing symfony/event-dispatcher-contracts (v3.6.0): Extracting archive
- Installing symfony/event-dispatcher (v7.3.3): Extracting archive
- Installing psr/log (3.0.2): Extracting archive
- Installing egulias/email-validator (4.0.4): Extracting archive
- Installing symfony/mailer (v7.3.4): Extracting archive
- Installing symfony/error-handler (v7.3.4): Extracting archive
- Installing symfony/http-kernel (v7.3.4): Extracting archive
- Installing symfony/finder (v7.3.2): Extracting archive
- Installing ramsey/collection (2.1.1): Extracting archive
- Installing brick/math (0.14.0): Extracting archive
- Installing ramsey/uuid (4.9.1): Extracting archive
- Installing psr/simple-cache (3.0.0): Extracting archive
- Installing symfony/translation-contracts (v3.6.0): Extracting archive
- Installing symfony/translation (v7.3.4): Extracting archive
- Installing psr/clock (1.0.0): Extracting archive
- Installing symfony/clock (v7.3.0): Extracting archive
- Installing carbonphp/carbon-doctrine-types (3.2.0): Extracting archive
- Installing nesbot/carbon (3.10.3): Extracting archive
- Installing monolog/monolog (3.9.0): Extracting archive
- Installing league/uri-interfaces (7.5.0): Extracting archive
- Installing league/uri (7.5.1): Extracting archive
- Installing league/mime-type-detection (1.16.0): Extracting archive
- Installing league/flysystem-local (3.30.0): Extracting archive
- Installing league/flysystem (3.30.0): Extracting archive
- Installing nette/utils (v4.0.8): Extracting archive
- Installing nette/schema (v1.3.2): Extracting archive
- Installing dflydev/dot-access-data (v3.0.3): Extracting archive
- Installing league/config (v1.2.0): Extracting archive
- Installing league/commonmark (2.7.1): Extracting archive
- Installing laravel/serializable-closure (v2.0.6): Extracting archive
- Installing laravel/prompts (v0.3.7): Extracting archive
- Installing laravel/framework (v12.34.0): Extracting archive
- Installing laravel/pail (v1.2.3): Extracting archive
- Installing laravel/pint (v1.25.1): Extracting archive
- Installing symfony/yaml (v7.3.3): Extracting archive
- Installing laravel/sail (v1.46.0): Extracting archive
- Installing nikic/php-parser (v5.6.1): Extracting archive
- Installing psy/psysh (v0.12.12): Extracting archive
- Installing laravel/tinker (v2.10.1): Extracting archive
- Installing hamcrest/hamcrest-php (v2.1.1): Extracting archive
- Installing mockery/mockery (1.6.12): Extracting archive
- Installing filp/whoops (2.18.4): Extracting archive
- Installing nunomaduro/collision (v8.8.2): Extracting archive
- Installing staabm/side-effects-detector (1.0.5): Extracting archive
- Installing sebastian/version (5.0.2): Extracting archive
- Installing sebastian/type (5.1.3): Extracting archive
- Installing sebastian/recursion-context (6.0.3): Extracting archive
- Installing sebastian/object-reflector (4.0.1): Extracting archive
- Installing sebastian/object-enumerator (6.0.1): Extracting archive
- Installing sebastian/global-state (7.0.2): Extracting archive
- Installing sebastian/exporter (6.3.2): Extracting archive
- Installing sebastian/environment (7.2.1): Extracting archive
- Installing sebastian/diff (6.0.2): Extracting archive
- Installing sebastian/comparator (6.3.2): Extracting archive
- Installing sebastian/code-unit (3.0.3): Extracting archive
- Installing sebastian/cli-parser (3.0.2): Extracting archive
- Installing phpunit/php-timer (7.0.1): Extracting archive
- Installing phpunit/php-text-template (4.0.1): Extracting archive
- Installing phpunit/php-invoker (5.0.1): Extracting archive
- Installing phpunit/php-file-iterator (5.1.0): Extracting archive
- Installing theseer/tokenizer (1.2.3): Extracting archive
- Installing sebastian/lines-of-code (3.0.1): Extracting archive
- Installing sebastian/complexity (4.0.1): Extracting archive
- Installing sebastian/code-unit-reverse-lookup (4.0.1): Extracting archive
- Installing phpunit/php-code-coverage (11.0.11): Extracting archive
- Installing phar-io/version (3.2.1): Extracting archive
- Installing phar-io/manifest (2.0.4): Extracting archive
- Installing myclabs/deep-copy (1.13.4): Extracting archive
- Installing phpunit/phpunit (11.5.42): Extracting archive
0/112 [>---------------------------] 0%
13/112 [===>------------------------] 11%
26/112 [======>---------------------] 23%
35/112 [========>-------------------] 31%
45/112 [===========>----------------] 40%
57/112 [==============>-------------] 50%
70/112 [=================>----------] 62%
79/112 [===================>--------] 70%
93/112 [=======================>----] 83%
104/112 [==========================>-] 92%
110/112 [===========================>] 98%
112/112 [============================] 100%
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
laravel/pail .......................................................... DONE
laravel/sail .......................................................... DONE
laravel/tinker ........................................................ DONE
nesbot/carbon ......................................................... DONE
nunomaduro/collision .................................................. DONE
nunomaduro/termwind ................................................... DONE
81 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
example-laravel-app %
さらに,Laravel の実行時,storage フォルダにファイルが出力されます.書き込み権限が必要になるため,アクセス権を変更します(この作業はスキップしても良いかもしれません).
example-laravel-app % ls -l | grep storage ⏎ # (1) アクセス権を確認 drwxr-xr-x 5 rinsaka staff 160 11月 13 16:21 storage example-laravel-app % chmod -R 777 storage ⏎ # (2) アクセス権の変更 example-laravel-app % ls -l | grep storage ⏎ # (3) アクセス権を確認 drwxrwxrwx 5 rinsaka staff 160 11月 13 16:21 storage example-laravel-app % cd ../../
コンテナの起動
ようやく準備ができたのでコンテナを起動します.最初の起動時は --build オプションを付与してイメージのビルドを行います.
Laravel02Nginx % docker compose up -d --build ⏎
[+] Building 19.7s (18/18) FINISHED
=> [internal] load local bake definitions 0.0s
=> => reading from stdin 900B 0.0s
=> [mysql internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 276B 0.0s
=> WARN: InvalidDefaultArgInFrom: Default value for ARG ${IMAGE} results 0.0s
=> [app internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 191B 0.0s
=> WARN: InvalidDefaultArgInFrom: Default value for ARG ${IMAGE} results 0.0s
=> [app internal] load metadata for docker.io/library/php:8.4.14-fpm 2.6s
=> [mysql internal] load metadata for docker.io/library/mysql:8.4 1.6s
=> [auth] library/php:pull token for registry-1.docker.io 0.0s
=> [auth] library/mysql:pull token for registry-1.docker.io 0.0s
=> CACHED [app internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [mysql 1/3] FROM docker.io/library/mysql:8.4@sha256:b306273d4d36bc1a7 0.0s
=> CACHED [mysql 2/3] RUN microdnf install -y glibc-locale-source glibc- 0.0s
=> CACHED [mysql 3/3] RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 0.0s
=> [mysql] exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:dbf6a819532a16dc9da7d948948187f286d9232949867 0.0s
=> => naming to docker.io/library/laravel02nginx-mysql 0.0s
=> [mysql] resolving provenance for metadata file 0.0s
=> [app 1/3] FROM docker.io/library/php:8.4.14-fpm@sha256:95876d81a4cbc8 5.8s
=> => resolve docker.io/library/php:8.4.14-fpm@sha256:95876d81a4cbc86f8e 0.0s
=> => sha256:fc5665bd22995935b24c5d8766394552c6720fb813a 3.25kB / 3.25kB 0.0s
=> => sha256:a979881ca2aa8febe2abb6661daf602b292984efb 10.87kB / 10.87kB 0.0s
=> => sha256:1a28af7603cdf6004d302424db9853fb489926eababed22 225B / 225B 0.4s
=> => sha256:95876d81a4cbc86f8e2aa49b5c417697092521c9c 10.30kB / 10.30kB 0.0s
=> => sha256:f2731e5164d54ee6e46123f5188c4200070cceb 110.16MB / 110.16MB 2.5s
=> => sha256:b263042dc7dd327e9f48c2e5bf784f51e4a1c866753a34b 224B / 224B 0.8s
=> => extracting sha256:1a28af7603cdf6004d302424db9853fb489926eababed22c 0.0s
=> => sha256:d2b3c84f2838cff64ff8bafbde54f4267231d7835 13.79MB / 13.79MB 1.4s
=> => sha256:2d415c0a35ffcdcd2cdd9cbdfbbe4e8759207ff3dec7e32 488B / 488B 1.3s
=> => sha256:2952f26b621e51373a10b32d1730c92d9adb91d72 13.33MB / 13.33MB 2.0s
=> => sha256:c97ad7844b63e2d81e4e0a4a6356bd62aa4149cbabc 2.45kB / 2.45kB 1.8s
=> => sha256:f7ddcb1ce63088e30d61bf426cef5ce7b8ad1cf0e3cec1b 251B / 251B 2.3s
=> => sha256:15ca1bbcbfd2ecdd1d25a2cb18d209bcd52a86476da3f1d 245B / 245B 2.5s
=> => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d 32B / 32B 2.6s
=> => extracting sha256:f2731e5164d54ee6e46123f5188c4200070cceb2705e6dd4 2.5s
=> => sha256:a59d5459d17e4321f99c6aa9f1f8fc8a0c883b6340a 9.20kB / 9.20kB 2.7s
=> => extracting sha256:b263042dc7dd327e9f48c2e5bf784f51e4a1c866753a34b8 0.0s
=> => extracting sha256:d2b3c84f2838cff64ff8bafbde54f4267231d7835dd6ce8d 0.1s
=> => extracting sha256:2d415c0a35ffcdcd2cdd9cbdfbbe4e8759207ff3dec7e324 0.0s
=> => extracting sha256:2952f26b621e51373a10b32d1730c92d9adb91d72b4c20bd 0.3s
=> => extracting sha256:c97ad7844b63e2d81e4e0a4a6356bd62aa4149cbabc4b043 0.0s
=> => extracting sha256:f7ddcb1ce63088e30d61bf426cef5ce7b8ad1cf0e3cec1bd 0.0s
=> => extracting sha256:15ca1bbcbfd2ecdd1d25a2cb18d209bcd52a86476da3f1d6 0.0s
=> => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6 0.0s
=> => extracting sha256:a59d5459d17e4321f99c6aa9f1f8fc8a0c883b6340a11b01 0.0s
=> [app 2/3] RUN apt-get update && apt-get install -y git curl zip 10.9s
=> [app 3/3] WORKDIR /var/www 0.0s
=> [app] exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:d58d4b10c52cd32b07310adab055df621c3bc5ff164b4 0.0s
=> => naming to docker.io/library/laravel02nginx-app 0.0s
=> [app] resolving provenance for metadata file 0.0s
[+] Running 7/7
✔ mysql Built 0.0s
✔ app Built 0.0s
✔ Network laravel02nginx_default Created 0.0s
✔ Volume "laravel02nginx_mysqlvolume" Created 0.0s
✔ Container laravel_mysql Start... 0.2s
✔ Container laravel_php Started 0.3s
✔ Container nginx Started 0.4s
Laravel02Nginx %
念のため,コンテナの起動状況を確認します.
Laravel02Nginx % docker container ls ⏎
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc701969547f nginx:1.25.5 "/docker-entrypoint.…" 25 seconds ago Up 24 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp nginx
184a54790146 laravel02nginx-app "docker-php-entrypoi…" 25 seconds ago Up 24 seconds 9000/tcp laravel_php
969ddaa17d4b laravel02nginx-mysql "docker-entrypoint.s…" 25 seconds ago Up 24 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp laravel_mysql
Laravel02Nginx %
アプリケーションの初期設定
はじめてコンテナを起動したのでいくつかの初期設定を行う必要があります.これにはアプリケーションサーバのコンテナ(サービス名 app,コンテナ名 laravel_php)に入り以下の作業を行う必要があります.まず,コンテナにログインします.
Laravel02Nginx % docker compose exec app /bin/bash ⏎
root@184a54790146:/var/www#
(1) でディレクトリの一覧を確認し,(2) では html ディレクトリに移動します.(3) では Laravel プロジェクトのソースがあることを確認します.(4) では PHP のバージョン番号を表示して php コマンドが利用できることを確認しています.さらに (5) では artisan のバージョン番号を表示して php artisan コマンドが動作することを確認しています.
root@184a54790146:/var/www# ls ⏎ # (1) html root@184a54790146:/var/www# cd html ⏎ # (2) root@184a54790146:/var/www/html# ls ⏎ # (3) README.md compose.yaml database resources vendor app composer.json package.json routes vite.config.js artisan composer.lock phpunit.xml storage bootstrap config public tests root@184a54790146:/var/www/html# php --version ⏎ # (4) PHP 8.4.14 (cli) (built: Nov 4 2025 01:23:04) (NTS) Copyright (c) The PHP Group Built by https://github.com/docker-library/php Zend Engine v4.4.14, Copyright (c) Zend Technologies with Zend OPcache v8.4.14, Copyright (c), by Zend Technologies root@184a54790146:/var/www/html# php artisan --version ⏎ # (5) Laravel Framework 12.34.0 root@184a54790146:/var/www/html#
次のコマンドで Laravel プロジェクトの .env ファイルの先頭を表示します.ここで,アプリケーションキー (APP_KEY) がまだ設定されていないことを確認します.
root@184a54790146:/var/www/html# cat .env | head ⏎ APP_NAME=Laravel APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost APP_LOCALE=ja APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=ja_JP root@184a54790146:/var/www/html#
次のコマンドでアプリケーションキーを生成します.
root@184a54790146:/var/www/html# php artisan key:generate ⏎
INFO Application key set successfully.
root@184a54790146:/var/www/html#
アプリケーションキーが生成されたことを上と同じコマンドで確認します.
root@184a54790146:/var/www/html# cat .env | head ⏎ APP_NAME=Laravel APP_ENV=local APP_KEY=base64:EMLfrZ3CxpugLAZhmh+UhcQRx/TENF036kUYqW0EKNQ= APP_DEBUG=true APP_URL=http://localhost APP_LOCALE=ja APP_FALLBACK_LOCALE=en APP_FAKER_LOCALE=ja_JP root@184a54790146:/var/www/html#
次に,(1) でデータベースにテーブルを生成し,(2) でテストデータを投入します.(3) ではコンテナからログアウトしています.
root@184a54790146:/var/www/html# php artisan migrate ⏎ # (1) INFO Preparing database. Creating migration table ...................................... 12.62ms DONE INFO Running migrations. 0001_01_01_000000_create_users_table .......................... 35.53ms DONE 0001_01_01_000001_create_cache_table .......................... 11.38ms DONE 0001_01_01_000002_create_jobs_table ........................... 26.42ms DONE 2025_10_19_110214_create_comments_table ........................ 6.17ms DONE root@184a54790146:/var/www/html# php artisan db:seed ⏎ # (2) INFO Seeding database. Database\Seeders\CommentsTableSeeder ............................... RUNNING Database\Seeders\CommentsTableSeeder ............................. 5 ms DONE root@184a54790146:/var/www/html# exit ⏎ # (3) exit Laravel02Nginx %
本番環境の場合,.env は次のとおり変更すると良いでしょう.
laravel/example-laravel-app/.env(抜粋)
APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:EMLfrZ3CxpugLAZhmh+UhcQRx/TENF036kUYqW0EKNQ=
APP_DEBUG=false
APP_URL=http://localhost
動作確認
準備ができたので Web ブラウザで http://localhost/ にアクセスします.
「コメント掲示板」に進むとコメントの一覧が表示されました.
「Title」と「Body」に入力して「投稿」をクリックします.
新たなコメントが投稿できました.
投稿内容の詳細ページにもアクセスできます.
MySQL の利用方法
続いて,MySQL コンテナへの接続と利用方法を確認します.次の一連のコマンドでは (1) で mysql コンテナにログインしたあと,(2) で docker-user というユーザ名で mysql に接続しています.
Laravel02Nginx % docker compose exec mysql /bin/bash ⏎ # (1) bash-5.1# mysql -u docker-user -p ⏎ # (2) Enter password: ⏎ # (3) パスワードの入力内容は表示されません Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 16 Server version: 8.4.7 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW DATABASES; ⏎ # (4) データベースの一覧 +--------------------+ | Database | +--------------------+ | commentsDB | | information_schema | | performance_schema | +--------------------+ 3 rows in set (0.00 sec) mysql> USE commentsDB; ⏎ # (5) データベースの変更(指定) Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> SHOW TABLES; ⏎ # (6) テーブル一覧 +-----------------------+ | Tables_in_commentsDB | +-----------------------+ | cache | | cache_locks | | comments | | failed_jobs | | job_batches | | jobs | | migrations | | password_reset_tokens | | sessions | | users | +-----------------------+ 10 rows in set (0.00 sec) mysql> DESC comments; ⏎ # (7) テーブル定義の確認 +------------+-----------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-----------------+------+-----+---------+----------------+ | id | bigint unsigned | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | body | text | NO | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +------------+-----------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> SELECT * FROM comments; ⏎ # (8) データの表示 +----+----------------------------+--------------------------------------------------------------+---------------------+---------------------+ | id | title | body | created_at | updated_at | +----+----------------------------+--------------------------------------------------------------+---------------------+---------------------+ | 1 | 最初のコメント | 最初のコメントです! | NULL | NULL | | 2 | 2つ目 | 2つ目のコメントです! | NULL | NULL | | 3 | <三個目>のコメント | シーダによってテストデータを設定します. | NULL | NULL | | 4 | docker | Nginx+PHP+MySQLで動いています | 2025-11-13 16:34:14 | 2025-11-13 16:34:14 | +----+----------------------------+--------------------------------------------------------------+---------------------+---------------------+ 4 rows in set (0.00 sec) mysql> exit ⏎ # (9) mysql の終了 Bye bash-5.1# exit ⏎ # (10) コンテナからのログアウト exit Laravel02Nginx %
MySQL には root ユーザ(管理者)でログインすることも可能です.なお,root ユーザのパスワードは .env の MYSQL_ROOT_PASSWORD で指定したものを入力してください.管理者で MySQL にログインした場合は利用可能なデータベースが一般ユーザよりも多いことが分かります.
Laravel02Nginx % docker compose exec mysql /bin/bash ⏎ # (1) bash-5.1# mysql -u root -p ⏎ # (2) Enter password: ⏎ # (3) Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 17 Server version: 8.4.7 MySQL Community Server - GPL Copyright (c) 2000, 2025, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SHOW DATABASES; ⏎ # (4) データベースの一覧 +--------------------+ | Database | +--------------------+ | commentsDB | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec) mysql> exit ⏎ # (5) Bye bash-5.1# exit ⏎ # (6) exit Laravel02Nginx %
コンテナの終了
本番環境ではほとんど利用する機会がないかもしれませんが,コンテナを停止するには docker compose stop,コンテナを停止したうえで破棄する場合は docker compose down を実行します.
Laravel02Nginx % docker compose stop ⏎
[+] Stopping 3/3
✔ Container nginx Stopped 0.2s
✔ Container laravel_php Stopped 0.1s
✔ Container laravel_mysql Stopped 1.7s
Laravel02Nginx %





