既存LaravelプロジェクトをDocker(Alpine Linux)で動かす

ローカル環境がVagrantで動いているLaravelの既存プロジェクトがある。今回はその既存プロジェクトをローカルの開発環境Dockerでも動くようにした。ネット上ではいろいろな、docker-compose.ymlがあるが、今回は自分のローカルで動作する内容を記載しておく。

また既存プロジェクトでは、ファイルを扱うライブラリ「libreoffice」やメール受信のための「imap」も使用しているためそれに対応した。

既存プロジェクト環境

  • composer 1.8.0

  • PHP 7.2.34 / Laravel 5.7

  • Mysql 5.7.24

  • nginx 1.12.2

各ミドルウェアのバージョンは保ち動作させるように配慮した。
(ローカル環境と本番環境は動作の整合性を保つために合わせる)

※今回はPHP7.2のDocker Imageがないっぽいので、PHP7.4を使用する。

前準備

ローカルで環境構築のための各ツール「git」「docker」「docker-compose」をインストールしておく。

  • git

$ git --version
git version 2.17.1.windows.2
  • docker

$ docker --version
Docker version 19.03.1, build 74b1e89e8a
  • docker-compose

$ docker-compose --version
docker-compose version 1.24.1, build 4667896b

プロジェクトのディレクトリ構造

今回のディレクトリ構造は下記のとおり。「アプリ」「DB」「WEB」の3つのイメージを動かす。

.
├── www [アプリ]
├── Dockerfile [本番環境デプロイ用]
├── Vagrantfile
├── docker-compose.yml [開発環境デプロイ用]
├── infra [開発環境デプロイ用]
└── docker
├── mysql
├── nginx
└── php

docker-compose.yml

まずはdocker-compose.ymlは下記のとおり。

version: "3.8"
volumes:
php-fpm-socket:
db-store:
services:
db:
image: mysql:5.7
container_name: db
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-secret}
MYSQL_DATABASE: ${DB_DATABASE:-db}
MYSQL_USER: ${DB_USERNAME:-db_user}
MYSQL_PASSWORD: ${DB_PASS:-password}
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./infra/docker/mysql/db-store:/var/lib/mysql
- ./infra/docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./infra/docker/mysql/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
web:
build:
context: .
dockerfile: ./infra/docker/nginx/Dockerfile
ports:
- ${WEB_PORT:-80}:80
volumes:
- php-fpm-socket:/var/run/php-fpm
- ./www:/work/www
app:
build:
context: .
dockerfile: ./infra/docker/php/Dockerfile
volumes:
- php-fpm-socket:/var/run/php-fpm
- ./www:/work/www
environment:
DB_CONNECTION: mysql
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: ${DB_DATABASE:-db}
DB_USERNAME: ${DB_USERNAME:-db_user}
DB_PASSWORD: ${DB_PASSWORD:-password}
links:
- db

db

mysql:5.7を指定した。
./infra/docker/mysql/my.cnf

[mysqld]
character_set_server = utf8mb4
# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM
# Error Log
log-error = mysql-error.log
# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0
# General Log
general_log = 1
general_log_file = mysql-general.log
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4

web

nginx:1.12-alpineを指定した。
./infra/docker/nginx/Dockerfile

FROM node:14.2-alpine as node
FROM nginx:1.12-alpine
SHELL ["/bin/ash", "-oeux", "pipefail", "-c"]
ENV TZ=Asia/Tokyo
RUN apk update && \
apk add --update --no-cache --virtual=.build-dependencies g++
# node command
COPY --from=node /usr/local/bin /usr/local/bin
# npm command
COPY --from=node /usr/local/lib /usr/local/lib
# yarn command
COPY --from=node /opt /opt
# nginx config file
COPY ./infra/docker/nginx/default.conf /etc/nginx/conf.d/default.conf
WORKDIR /work/www

./infra/docker/nginx/default.conf
nginxの設定ファイルは以下。

access_log /dev/stdout main;
error_log /dev/stderr warn;
server {
listen 80;
root /work/www/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm 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 unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}

app

php:7.4-fpm-alpineを指定した。
./infra/docker/php/Dockerfile

FROM php:7.4-fpm-alpine
COPY ./.env.example ./www/.env
COPY ./www /work/www
COPY ./infra/docker/php/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf
COPY ./infra/docker/php/php.ini /usr/local/etc/php/php.ini
# timezone environment
ENV TZ=Asia/Tokyo
# locale
ENV LANG=ja_JP.UTF-8
# JSTに変更
RUN apk add tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN apk upgrade --update && \
apk --no-cache add icu-dev autoconf make g++ gcc ca-certificates wget curl
# for gd
RUN apk add --no-cache \
freetype-dev \
libjpeg-turbo-dev \
libpng-dev
# for imap
RUN apk add imap-dev krb5-dev libressl-dev
# 使用するモジュール追加
RUN apk add --no-cache php7-bcmath php7-pecl-memcached unzip libzip-dev
RUN docker-php-ext-install gd intl pdo_mysql opcache zip bcmath
# for imap
RUN PHP_OPENSSL=yes \
docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& docker-php-ext-install imap \
&& docker-php-ext-enable imap
# for libreoffice
RUN mkdir -p /usr/share/man/man1
RUN apk add --no-cache libreoffice
# for composer
ENV COMPOSER_VERSION 1.8.0
RUN curl -L -O https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar && \
chmod +x composer.phar && mv composer.phar /usr/local/bin/composer
WORKDIR /work/www

./infra/docker/php/php.ini
phpの設定ファイルは以下。

zend.exception_ignore_args = off
expose_php = on
max_execution_time = 30
max_input_vars = 1000
upload_max_filesize = 64M
post_max_size = 128M
memory_limit = 256M
error_reporting = E_ALL
display_errors = on
display_startup_errors = on
log_errors = on
error_log = /dev/stderr
default_charset = UTF-8
[Date]
date.timezone = "Asia/Tokyo"
[mysqlnd]
mysqlnd.collect_memory_statistics = on
[Assertion]
zend.assertions = 1
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = "UTF-8"

./infra/docker/php/php-fpm.d/www.conf

[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666

ビルド

$ docker-compose up --build

動作確認

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

http://localhostでアクセスできるはず。
できなければ docker-machine envなどでIPアドレスを確認してそこにアクセスするといいかも。

また、何回か試している過程で下記エラーがあった場合

Illuminate\Database\QueryException : SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name does not resolve

いったんイメージを削除してビルドするとなおった。

$ docker-compose down --rmi all --volumes
[Sponsored Links]







  • このエントリーをはてなブックマークに追加
[Sponsored Links]