2018年秋にリリースされたEC−CUBE4の開発環境をdocker-composeで作成してみました。
タイトルにある通り開発環境の「速度改善」が今回のメインですが、一応環境構築するまでの手順から載せておきます。
※不要な方は飛ばしてください
開発環境
- MacBook Pro(macOS Mojave 10.14.2)
$ git --version
git version 2.18.0
$ docker --version
Docker version 18.09.1, build 4c52b90
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
※インストールされていない方はこちら
http://i-yusuke.com/entry/macbook-pro-setting/#Docker
開発環境の構築手順
構築手順はこちらの記事を参考にさせて頂きました。
docker-composeでEC-CUBE4の開発環境構築 – Qiita
今後は本番環境とできるだけ近い環境を作ることもあると思うでの、一般的(?)な下記環境を作成します。
- PHP:7.1
- MySQL:5.7
- Apache
※初学者のためになるべく丁寧に解説していますので多少冗長的な部分もあります。
適当なディレクトリに移動
EC−CUBE4のファイルを取得する前準備として「ターミナル」を立ち上げます。
開発環境を作る前に適当なディレクトリを作成するなり移動しましょう。
$ cd ~/
$ mkdir eccube-dev # eccube-devディレクトリを作成
$ cd eccube-dev # 作成したディレクトリに移動
$ pwd
# カレントディレクトリを確認
/Users/yusuke/eccube-dev
EC−CUBE4のファイル取得
EC−CUBE4のファイルをGitHubから取得します。
EC-CUBE/ec-cube: EC-CUBE is the most popular e-commerce solution in Japan – GitHub
2019/01/19時点で最新のver4.0.1を指定しましょう。
$ git clone -b 4.0.1 https://github.com/EC-CUBE/ec-cube.git
Cloning into 'ec-cube'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 257555 (delta 1), reused 5 (delta 1), pack-reused 257548
Receiving objects: 100% (257555/257555), 108.10 MiB | 298.00 KiB/s, done.
Resolving deltas: 100% (187966/187966), done.
Note: checking out 'd8f189cce78e5cca9d4a3478931bae61901c504e'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
git clone
する際に「-b」オプションでブランチやタグを指定してcloneすることができます。
dockerの設定ファイルを追加
取得したらDockerを立ち上げるために設定ファイルを新規作成します。
$ cd ec-cube/
Dockerfileを作成
$ vim Dockerfile
# 下記内容を入力し保存
FROM php:7.1-apache
RUN set -x
RUN sed -i.bak -e "s%http://deb.debian.org/debian%http://ftp.riken.jp/pub/Linux/debian/debian%g" /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y --no-install-recommends \
sudo \
git \
libxml2-dev \
unzip \
wget \
zlib1g-dev \
iproute \
libsqlite3-dev \
libpq-dev \
libicu-dev \
gnupg2
RUN wget -qO- https://deb.nodesource.com/setup_10.x | bash -
RUN apt-get install -y --no-install-recommends nodejs
RUN docker-php-ext-install \
intl \
mbstring \
pdo \
pdo_sqlite \
pdo_mysql \
pdo_pgsql \
soap \
xml \
zip
RUN pecl install xdebug
RUN pecl install apcu
RUN docker-php-ext-enable \
xdebug \
apcu \
opcache \
&& a2enmod rewrite \
&& apt-get clean \
&& rm -rf /tmp/*
RUN curl -sS https://getcomposer.org/installer \
| php -- \
--filename=composer \
--install-dir=/usr/local/bin \
# composerの高速化
&& COMPOSER_ALLOW_SUPERUSER=1 composer global require --optimize-autoloader "hirak/prestissimo" \
&& chown www-data /var/www \
&& chmod g+s /var/www/html
COPY ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["apache2-foreground"]
docker-compose.ymlを作成
※今回の完成形はこれではないので、手っ取り早く完成させたい方はこちら
$ vim docker-compose.yml
# 下記内容を入力し保存
version: '3'
services:
db:
image: mysql:5.7
container_name: eccube_db
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- eccube-db-data:/var/lib/mysql
ports:
- 3306:3306
app:
build: .
container_name: eccube
volumes:
- .:/var/www/html
ports:
- 8080:80
stdin_open: true
tty: true
depends_on:
- db
volumes:
eccube-db-data:
driver: local
entrypoint.shを作成
$ vim entrypoint.sh
# 下記内容を入力し保存
#!/bin/sh
set -e
# www-dataのUIDを変更する
if [ -n "${HOST_UID}" -a "${HOST_UID}" != "$(id -u www-data)" ]; then
usermod -u "${HOST_UID}" www-data
fi
if [ -e "composer.json" ]; then
composer install
fi
if [ -e "package.json" ]; then
npm install
fi
exec "$@"
確認
追加した3ファイルがあるか確認します。
$ tree -L 1
.
├── COPYING
├── Dockerfile # 1
├── LICENSE.txt
├── Procfile
├── README.md
├── app
├── app.json
├── appveyor.yml
├── bin
├── codeception
├── codeception.sh
├── codeception.yml
├── composer.json
├── composer.lock
├── docker-compose.yml # 2
├── entrypoint.sh # 3
├── gulpfile.js
├── html
├── index.php
├── maintenance.php
├── package-lock.json
├── package.json
├── phpunit.xml.dist
├── robots.txt
├── src
├── symfony.lock
├── tests
├── var
└── web.config
7 directories, 22 files
サービス開始(起動)
下記コマンドを実行しサービスを開始します。
$ HOST_UID=$(id -u) docker-compose up -d --build
Creating network "ec-cube_default" with the default driver
Creating volume "ec-cube_eccube-db-data" with local driver
Building app
Step 1/16 : FROM php:7.1-apache
---> 21aea3c944f5
Step 2/16 : RUN set -x
---> Using cache
---> f84886341760
Step 3/16 : RUN sed -i.bak -e "s%http://deb.debian.org/debian%http://ftp.riken.jp/pub/Linux/debian/debian%g" /etc/apt/sources.list
---> Using cache
---> 5846d0ea485b
Step 4/16 : RUN apt-get update
---> Using cache
---> 252de8ddc99b
Step 5/16 : RUN apt-get install -y --no-install-recommends sudo git libxml2-dev unzip wget zlib1g-dev iproute libsqlite3-dev libpq-dev libicu-dev gnupg2
---> Using cache
---> 675f76441831
Step 6/16 : RUN wget -qO- https://deb.nodesource.com/setup_10.x | bash -
---> Using cache
---> 75ec6412e7bc
Step 7/16 : RUN apt-get install -y --no-install-recommends nodejs
---> Using cache
---> 8b47d9e4f85b
Step 8/16 : RUN docker-php-ext-install intl mbstring pdo pdo_sqlite pdo_mysql pdo_pgsql soap xml zip
---> Using cache
---> b72cae5fb92e
Step 9/16 : RUN pecl install xdebug
---> Using cache
---> 995115352947
Step 10/16 : RUN pecl install apcu
---> Using cache
---> cd6e0f33a66c
Step 11/16 : RUN docker-php-ext-enable xdebug apcu opcache && a2enmod rewrite && apt-get clean && rm -rf /tmp/*
---> Using cache
---> a7d0fa89697b
Step 12/16 : RUN curl -sS https://getcomposer.org/installer | php -- --filename=composer --install-dir=/usr/local/bin && COMPOSER_ALLOW_SUPERUSER=1 composer global require --optimize-autoloader "hirak/prestissimo" && chown www-data /var/www && chmod g+s /var/www/html
---> Using cache
---> 82b5e334a3ce
Step 13/16 : COPY ./entrypoint.sh /entrypoint.sh
---> Using cache
---> 584029ed2d46
Step 14/16 : RUN chmod +x /entrypoint.sh
---> Using cache
---> 35fc277edb3d
Step 15/16 : ENTRYPOINT ["/entrypoint.sh"]
---> Using cache
---> d835e1d01f23
Step 16/16 : CMD ["apache2-foreground"]
---> Using cache
---> eac545a091ac
Successfully built eac545a091ac
Successfully tagged ec-cube_app:latest
Creating eccube_db ... done
Creating eccube ... done
立ち上がるまでにちょっと時間がかかります。
ログを確認してDockerfile
の最後に記載しているコマンドが実行されるまで待ちましょう。
$ docker-compose logs
:
:
eccube | [Sat Jan 19 02:03:02.922063 2019] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
docker-compose.yml
で定義しているコンテナが起動していることを確認してみます。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
19ebbba83330 ec-cube_app "/entrypoint.sh apac…" 23 minutes ago Up 23 minutes 0.0.0.0:8080->80/tcp eccube
6c0512d5c76a mysql:5.7 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp eccube_db
大丈夫そうですね。
次にeccube
コンテナにアタッチしインストール処理を行います。
MySQL環境を利用するためDatabase Url
の入力だけ必要です。
※入力値は「mysql://root:password@eccube_db/eccube」
$ docker container exec -it eccube bin/console eccube:install
EC-CUBE Installer Interactive Wizard
====================================
If you prefer to not use this interactive wizard, define the environment valiables as follows:
$ export APP_ENV=dev
$ export APP_DEBUG=1
$ export DATABASE_URL=database_url
$ export DATABASE_SERVER_VERSION=server_version
$ export MAILER_URL=mailer_url
$ export ECCUBE_AUTH_MAGIC=auth_magic
... and more
$ php bin/console eccube:install --no-interaction
Database Url [sqlite:///var/eccube.db]:
> mysql://root:password@eccube_db/eccube # DBの接続設定を入力
Database Server version [auto]:
>
Mailer Url [null://localhost]:
>
Auth Magic [VB1E2b9UFTVBW7xr]:
>
!
! [CAUTION] Execute the installation process. All data is initialized.
!
Is it OK? (yes/no) [yes]:
>
Run doctrine:database:create --if-not-exists...
Created database `eccube` for connection named default
Run doctrine:schema:drop --force...
Dropping database schema...
[OK] Database schema dropped successfully!
Run doctrine:schema:create...
! [CAUTION] This operation should not be executed in a production environment!
Creating database schema...
[OK] Database schema created successfully!
Run eccube:fixtures:load...
> Finished Successful!
Run cache:clear --no-warmup...
// Clearing the cache for the dev environment with debug
// true
[OK] Cache for the "dev" environment (debug=true) was successfully cleared.
[OK] EC-CUBE installation successful.
インストールが無事に完了したら早速アクセスしてみましょう。
長い間待たされタイムアウトとなりました・・・。
ようやくここからが本題です。
現状把握
レスポンスが遅い原因はホスト側とコンテナ側のファイル共有にあります。
現状把握のためレスポンスタイムを計測してみましょう。
.htaccess
に下記記述を追加しタイムアウトを3分まで延ばしてみます。
$ vim .htaccess
# 下記記述を追加
php_value max_execution_time 180
初回アクセスの結果です。
90秒もかかってしまいました。。。
ただ初回はキャッシュ生成に時間かかるので2回目以降は早くなります。
と言っても10秒くらいかかりますね。
これで開発するのはストレスフルなので改善方法を探します。
docker-syncの導入とキャッシュを共有しない
EC−CUBE4に限らずDocker for Mac
やSymfony
全般に言える問題と判断しこちらの記事にたどり着きました。
3 ways to get Docker for Mac faster on your Symfony app.
記事で紹介されている手順を一通り試しました結果、結論としては「docker-sync
を導入し、キャッシュディレクトリは除外する」です。
docker-sync
の概要やインストールはこちらの記事が参考になります。
docker-syncでホスト-コンテナ間を爆速で同期する – Qiita
インストールが完了したらdocker-sync.yml
を新規作成します。
$ docker-compose down # 一旦サービス停止
Stopping eccube ... done
Stopping eccube_db ... done
Removing eccube ... done
Removing eccube_db ... done
Removing network ec-cube_default
$ vim docker-sync.yml # 新規作成
# 下記内容を入力し保存
version: '2'
syncs:
eccube-sync:
src: '.'
sync_host_ip: '127.0.0.1'
sync_host_port: '5000'
sync_strategy: 'native_osx'
sync_excludes: ['.git', '.gitignore', 'node_modules', 'var']
docker-compose.yml
のvolumes
部分を修正します。
version: '3'
services:
db:
image: mysql:5.7
container_name: eccube_db
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- eccube-db-data:/var/lib/mysql
ports:
- 3306:3306
app:
build: .
container_name: eccube
volumes:
- eccube-sync:/var/www/html # 修正
ports:
- 8080:80
stdin_open: true
tty: true
depends_on:
- db
volumes:
# 追加
eccube-sync:
external: true
eccube-db-data:
driver: local
準備が出来たので実行します。
$ docker-sync start
ok Starting native_osx for sync eccube-sync
doing initial sync with unison
Unison 2.51.2 (ocaml 4.06.1): Contacting server...
Looking for changes
Reconciling changes
Propagating updates
UNISON 2.51.2 (OCAML 4.06.1) started propagating changes at 15:01:46.59 on 19 Jan 2019
[BGN] Copying .coveralls.yml from /host_sync to /app_sync
:
:
real 1m 8.25s
user 0m 1.94s
sys 0m 5.72s
chown ing file to uid 0
5f56df335f9ea35ee561f51e8e23324d0c4dc4c36db47c9fd8e0bf69973f881a
success Sync container started
success Starting Docker-Sync in the background
サービスを再度開始します。
$ HOST_UID=$(id -u) docker-compose up -d --build
:
:
Successfully tagged ec-cube_app:latest
Creating eccube_db ... done
Creating eccube ... done
無事立ち上がったらアクセスしてみましょう。
初回アクセスは2〜3秒ほどかかりましたが、2回目以降は0.5秒ほどと決して早くはないですが実用に耐えるレベルにまで改善されました。
それでも改善しないなら?
前述のdocker-sync
導入後も改善しない、使っているうちに遅くなっているケースが何度ありました。(4〜5秒くらいかかりました)
その場合Docker for Mac
に割り当てるリソースを増やす、Docker for Mac
を再起動することで改善しました。
メニューバーのアイコンから設定や再起動ができます。
歴史が浅くまだ成熟していない技術なので今後に期待ですね。ではまた。