docker-composeを使ってDocker上にLaravelを構築する方法。WebサーバーはNignx + php-fpmを使用。
##目次
- Laravelをローカルに構築
- .envファイルの設定
- dockerにcomposerのデータをコピー
- docker-compose.ymlを作成
- Dockerfileの作成
- PHPの構成
- NginxとPHP-FPM
- Nginxの設定
- MySQLの設定
-
コンテナ起動
11. コンテナの起動状況の確認
12. ブラウザで確認 - (補足)ブラウザ表示でエラーが出た場合の対処法
##1. Laravelをローカルに構築する
###1-1. githubからクローン
git clone https://github.com/laravel/laravel.git <プロジェクト名>
###1-2. composerを使ってバンドルをインストールする。
$ composer update
composer.jsonに書いてあるバンドルがズラーっとインストールされる。
###1-3 .envファイルの設定
まずは.envファイルを作成する。(.env.exampleをコピーする)
cp .env.example .env
次にキーを作成する。
$ php artisan key:generate
MySQLと接続するためにDBの設定を変更する。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=******
DB_DATABASEとDB_PASSWORDは次で作成するdocker-composer.ymlと合わせる。
###(補足)composerでプロジェクトを作成する方法
以下リンクのNo3まででローカルで動くLaravelの環境を構築できる。
##2. dockerにcomposerのデータをコピー プロジェクトのルートディレクトリに移動後、以下を実行。
$ docker run --rm -v $(pwd):/app composer install
- composerイメージからコンテナを作成しinstallを実行。
- 現在のディレクトリをコンテナ内の/appにマウント。
- コンテナ起動後にコンテナを削除する。
composerの必要なデータのみローカルの現在のディレクトリにコピーする。
バンドルが記述されたcomposer.lock
がローカルのルートディレクトリに追加される。
docker runコマンド
・docker run [オプション] イメージ [コマンド] [引数...]
####--rmオプション
コンテナ終了時、自動的に削除。
composerのイメージとコンテナは不要なため。必要なデータのみマウントしたボリュームにコピーしておく。
####-vオプション
ボリュームのマウント。
ローカルのディレクトリをコンテナ内のディレクトリにマウントする。
--volume
の略。
▼ボリュームのマウント方法
-v [ホスト側ソース:]コンテナ側送信先[:<オプション>]
- -v $(pwd):/app
- ホスト側ソースは絶対パスか、ボリューム名で指定。
- $(pwd):ホスト側の現在のディレクトリパス
- /app: コンテナ内のappディレクトリ
####起動するイメージの指定 imageに`composer`を指定。タグを指定していない場合は`latest`。
dockerはまず、localでcomposer:latest
を探す。なければdocker hubから指定のイメージを探す。
####コマンド実行例
$ docker run --rm -v $(pwd):/app composer install
Unable to find image 'composer:latest' locally
latest: Pulling from library/composer
8bb409133b6b: Pull complete
Digest: sha256:447516936298f9f63d0b718d1a21bd70066b6c206e174cd29938c79b8eefe7b1
Status: Downloaded newer image for composer:latest
No lock file found. Updating dependencies instead of installing from lock file. Use composer update over composer install if you do not have a lock file.
Loading composer repositories with package information
Updating dependencies
Lock file operations: 105 installs, 0 updates, 0 removals
- Locking asm89/stack-cors (v2.0.2)
- Locking brick/math (0.9.2)
(省略)
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
77 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/sail
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
74 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
ボリュームをマウントしているので、作成されたファイルがローカルに保存される。
##3. docker-compose.ymlを作成する
$ vim docker-compose.yml
vimエディタでi
をクリックしてinsertモードに入り、以下をコピペ。
コピペ後は、esc
+ :wq
で保存して終了。
(参考)vimの使い方
###docker-compose.yml
version: '3'
services:
#PHP Service
app:
build:
context: .
#dockerfile: Dockerfile
image: app_php-fpm
container_name: appdocker
restart: unless-stopped
tty: true
environment:
SERVICE_NAME: app
SERVICE_TAGS: dev
working_dir: /var/www
volumes:
- ./:/var/www
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
networks:
- app-network
links:
- webserver
- db
#Nginx Service
webserver:
image: nginx:alpine
container_name: webserver
restart: unless-stopped
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./nginx/conf.d/:/etc/nginx/conf.d/
networks:
- app-network
#MySQL Service
db:
image: mysql:5.7.22
container_name: db
restart: unless-stopped
tty: true
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- dbdata:/var/lib/mysql/
- ./mysql/my.cnf:/etc/mysql/my.cnf
networks:
- app-network
#Docker Networks
networks:
app-network:
driver: bridge
#Volumes
volumes:
dbdata:
driver: local
##4. Dockerfileの作成
$ vim Dockerfile
vimエディタでi
をクリックしてinsertモードに入り、以下をコピペ。
コピペ後は、esc
+ :wq
で保存して終了。
FROM php:7.3-fpm
# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/
# Set working directory
WORKDIR /var/www
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libonig-dev \
libzip-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
# Copy and change existing application directory permissions
COPY --chown=www:www . /var/www
# Change current user to www
USER www
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
・FROM php:7.2-fpm
ベースイメージにphp:7.2-fpmを指定。
▼php:7.2-fpm
PHP-FPMがインストールされているDebianベースのイメージ。
###5. PHPの構成 ディレクトリPHPの中にlocal.iniを作成する。
$ mkdir php
$ vim php/local.ini
upload_max_filesize=40M
post_max_size=40M
例として、PHPの構成として、アップロードできるファイルサイズ上限を40Mに設定している。
PHPの構成が完了したら、NginxでFastCGIサーバーとしてPHP-FPMを使用するように設定する。
##NginxとPHP-FPM NignxはApachと異なりPHPを直接処理できない。このため、**PHP-FPMと接続してPHPを処理できるようにする**。
PHP-FPMはFast-CGI。Fast-CGIとは、WEBサーバー上でプログラムを動かすためのCGI(Common Gateway Interface)の改良版。Fastは速いの意味。
次のNginxの設定では、Fast-CGIとしてPHP-FPMを使うための設定を記述する。
##6. Nginxの設定 nginx/conf.dディレクトリにapp.confファイルを作成する。
$ mkdir -p nginx/conf.d
$ vim nginx/conf.d/app.conf
vimエディタでi
をクリックしてinsertモードに入り、以下をコピペ。
コピペ後は、esc
+ :wq
で保存して終了。
server {
listen 80;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
}
・conf.d
.dはディレクトリ名であることを明示。
nginxではconf.d配下にあるすべての.conf
ファイルを読み込む設定がされている。
include /etc/nginx/conf.d/*.conf;
・server
httpのサーバーの設定。
・index
indexディレクティブ。URIが/
で終わる場合(ディレクトリが指定されている)場合にリダイレクトするファイルを指定する。
index index.php index.html;
リクエストされたURIが/hoge/
の場合に、index.phpがあれば、hoge/index.php
にリダイレクトする。ない場合はhoge/index.html
にリダイレクトする。
デフォルトは
index index.html
となっている。
・listen 80
listenディレクティブ。nginxサーバーが使用するポート番号に80を指定。
・error_log
エラーログを書き込むためのファイルを指定。
・access_log
アクセスログを書き込むためのファイルを指定。
・root
ドキュメントルートのディレクトリを指定する。
「/var/www/public」を指定している。
・location
特定のuriでリクエストがきた場合の処理を設定。prefixを使って指定する(完全一致や正規表現など)。
指定したuriに一致したら{ }内の処理を実行する。
location <prefix> <uri> {
処理
}
▼正規表現の指定
prefix | 内容 |
---|---|
なし | 前方一致 |
= | 完全一致 |
~ | 正規表現(大文字・小文字を区別する) |
~* | 正規表現(大文字・小文字を区別しない) |
####実例(PHP-FPMの設定)
以下はNginxをPHP-FPMに接続する設定。
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
正規表現で、\.php$
(末尾が.php)なら処理を実行。
####・try_files
指定したパスの存在確認をする。(if文に似た処理)
上記であれば、.phpにアクセスした場合は404
を返す。
####・fastcgi_split_path_info
リクエストで渡されたURIを2分割する。
fastcgi_split_path_info ^(正規表現1)(正規表現2)$;
▼正規表現1
$fastcgi_script_name
の値になる。
ここでは、(.+.php)なので、「*.php」が該当。
▼正規表現2
$fastcgi_path_info
の値になる。
ここでは、(/.+)なので、*.php/以下が該当。
▼実例
例えばリクエストが/show.php/article/0001
の場合以下のようになる。
$fastcgi_script_name=$document_root/show.php
$fastcgi_path_info=article/0001
####・fastcgi_pass アドレス
Fast-CGIサーバーのアドレスを指定する。
####・include ファイル
指定したファイルを読み込む。
ここでは設定ファイルとしてfastcgi_paramsを読み込んでいる。
DebianやUbuntuの場合設定ファイルはデフォルトで/etc/nginx/fastcgi_paramsにある。
・NGINX PHP FastCGI Example
####・fastcgi_index ファイル
URIのパスがスラッシュ/
で終わる(ディレクトリを指定)場合に開くファイルを指定。
####・fastcgi_param SCRIPT_FILENAME ファイル
実行するファイル名を指定する。
$document_root$fastcgi_script_name
なので、ドキュメントルートの後に、$fastcgi_script_name
の値が続く。
▼$fastcgi_script_name
fastcgi_split_path_infoの一つ目の正規表現が該当する。つまり「*.php」となり、リクエストされたURIと一致するphpファイルが実行される。
####fastcgi_indexとfastcgi_param SCRIPT_FILENAME
渡されたURIによって使用するphpファイルを切り替える処理になる。
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
上記設定に対して、/page.phpが渡された場合、SCRIPT_FILENAMEが処理され、/home/www/scripts/php/page.phpが実行される。
一方、URIの終わりがスラッシュで、/page.php/の場合、fastcgi_indexが処理され、home/www/scripts/php/index.phpが実行される。
####・fastcgi_param PATH_INFO
パスの情報。
ここではリクエストされたパスの.php以降の内容が入る。
・(参考)Nginx http_fastgis_modules
###2つ目のlocationの処理内容
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
リクエストされたURIが/*
(前方一致)の場合、処理を実行する。
####・try_files $uri $uri/ /index.php?
ファイルの存在確認をしあれば実行。なければ次のファイルの存在確認を行う。
存在確認する優先順位は、$uri
, $uri/
, /index.php?
となる。
####・gzip_static on;
gzipで圧縮済みのファイル「.gz」があればそちらを配信する。
##7. MySQLの設定 mysqlディレクトリの中にmy.cnfファイルを作成する。
$ mkdir mysql
$ vim mysql/my.cnf
vimエディタでi
をクリックしてinsertモードに入り、以下をコピペ。
コピペ後は、esc
+ :wq
で保存して終了。
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log
ここではMySQLのログの設定をしている。
####・general_log
値を1(or ON)にするとログを出力する。
0(or OFF or 記述なし)の場合はログ出力をしない。
####・general_log_file
指定したファイルにログを出力する。
##7. コンテナ起動 docker-compose.ymlのあるディレクトリで以下を実行する。
$ docker-compose up -d app
サービスappを起動すれば、linkでwebserver, dbもつながっているため同時に起動する。
-d
は デタッチド・モード。バックグラウンドでコンテナを実行するため、コンテナ起動後もそのターミナルでコマンドが打てる状態になる。
▼(補足)サービスを指定しない場合
サービスの指定がなければ、docker-composeに記述されたすべてのサービスが起動する。
###コンテナの起動状況の確認
$ docker ps
コマンドで起動中のコンテナ一覧を表示できる。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04012cd50d18 mysql:5.7.22 "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 3306/tcp, 0.0.0.0:3306->3306/tcp db
6d0cd9138856 app_php-fpm "docker-php-entrypoi…" 6 minutes ago Up 6 minutes 9000/tcp app
f02cf8788728 nginx:alpine "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp webserver
docker-composeのサービスで定義した、app, webserver, dbが起動している。
###ブラウザで確認
localhost:80
を入力するとLaravelのwelcome.blade.phpが表示される。
##(補足)ブラウザ表示でエラーが出た場合の対処法 以下のようなエラーが出たらPHPのバージョンを上げ、インストールするバンドルやエクステンションを変更することで解決できる。
Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= x.x.x". You are running y.y.y. in /var/www/vendor/composer/platform_check.php on line 24
以上。