本記事は、サムザップ Advent Calendar 2020 #1 の 12/5 の記事です。
スマホゲームの企画・運営事業を行っているサムザップで、エンジニアをしています森本です
サムザップでは、local 環境を docker を用いて構築しているプロジェクトが多いです
その一例として、私の関わっているプロジェクトでの local 環境を紹介したいと思います
使用している docker コンテナは以下等です
- nginx
- php-fpm
- MySQL
- memcache
- Redis
- phpmyadmin
また、DB マイグレーションに
- phinx migration
を使用しています
#フォルダ構成
local/
├ application/
│ ├ mysql/
│ │ ├ 1_initial_mysql.sh
│ │ └ 2_initial_mysql.sql
│ └ web/
│ └ initial_web.sh
├ docker/
│ ├ gatling/
│ │ └ Dockerfile
│ ├ misc/
│ │ └ data/
│ │ └ DB実態
│ ├ nginx/
│ │ ├ 鍵回り省略
│ │ ├ Dockerfile
│ │ ├ fastcgi.conf
│ │ ├ nginx.conf
│ │ └ server.conf
│ ├ php-fpm/
│ │ ├ Dockerfile
│ │ ├ php.ini
│ │ └ www.conf
│ └ docker-compose.yml
├ dump/
│ └ 移行前のDB,テーブル定義
├ mysql/
│ └ custom.cnf
└ phpmyadmin/
├ conf/
│ └ config.user.inc.php
└ sessions/
└ 省略
#local/application/
###local/application/mysql/
docker の MySQL image では /docker-entrypoint-initdb.d/ というディレクトリ内に初期化用の SQL やスクリプトを置くことで、最初に image を起動したときにデータの初期化を自動的に行う仕組みがあります
- 1_initial_mysql.sh
cd /dump/
zcat 過去DB_table.gz | mysql -uroot -p*****
...
phinx 導入前の DB、テーブルを作成しています
- 2_initial_mysql.sql
grant all on *.* to user1@'%' identified by '*****';
grant all on *.* to user2@'%' identified by '*****';
...
insert ...
mysql ユーザー作成、管理画面初期データ作成 しています
実行順は、ファイル名順のため、ファイル名の頭に「1_」「2_」がついています
###local/application/web/
- initial_web.sh
cd .../PhinxMigration
if [ ! -e vendor ]; then
リンク作成(省略)
cd .../PhinxMigration
composer install
else
until mysqladmin ping -h mysql --silent; do
echo ""
echo 'waiting for mysqld to be connectable...'
echo ""
sleep 3
done
cd .../phinx_migration/
make migrate ENV=localhost
fi
web 起動時
初回起動の場合
(という切り分けができなかったので、composer install に実行時に作成される vender フォルダがない場合)
cd .../PhinxMigration
composer install 実行
初回起動ではない場合
(vender フォルダがある場合)
mysql サーバが立ち上がるまでループ
DB マイグレーション同期実行
を実行しています
docker 起動時(=web 起動時) に、毎回、DB マイグレーション同期実行 するようにしています
composer install 実行後、DB マイグレーション同期実行 する方法(else の削除)
は、課題として残っています
#local/docker/
###local/application/nginx/
- Dockerfile
FROM nginx
ADD nginx.conf /etc/nginx/nginx.conf
ADD fastcgi.conf /etc/nginx/fastcgi.conf
ADD server.conf /etc/nginx/conf.d/default.conf
ADD localhost.key /etc/ssl/private/localhost.key
ADD localhost.crt /etc/ssl/certs/localhost.crt
ADD dhparam.pem /etc/nginx/ssl/dhparam.pem
nginx イメージに各設定ファイルをaddしています
- fastcgi.conf
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
...
一般的な検索結果サイトから取得したもの
+
プロジェクトで使用しているものを追加しています
- nginx.conf
user www-data;
pid /var/run/nginx.pid;
# coreモジュールの設定
http{
# httpモジュールの設定
}
...
一般的な検索結果サイトから取得したもの
+
ソケット通信に変更しています
user www-data;
pid /var/run/nginx.pid;
- server.conf
server {
listen 80;
...
}
server {
listen 443 ssl http2;
...
location / {
# other
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php7-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
...
}
server {
listen 80;
server_name ~^(?<user>.+)\.local\.jp$;
root /var/www/$user/;
...
}
一般的な検索結果サイトから取得したもの
+
プロジェクトで使用している設定(記述変更、削除しています)
+
ソケット通信に変更しています
fastcgi_pass unix:/var/run/php7-fpm.sock;
また、ローカルに複数ソースを git clone している人のために
例
test.local.jp
にアクセスすると
/var/www/test/
以下のソースを見に行くようにしています
###local/application/php-fpm/
- Dockerfile
FROM php:7.4-fpm
ADD php.ini /usr/local/etc/php/conf.d/php.ini
ADD www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
RUN apt-get update && apt-get install -y libmcrypt-dev mariadb-client bc zlib1g-dev libmemcached-dev procps curl unzip git libonig-dev \
&& docker-php-ext-install pdo_mysql mysqli mbstring opcache bcmath
RUN pecl install memcached-3.1.3 \
&& docker-php-ext-enable memcached
RUN mkdir -p /usr/src/php/ext/redis \
&& curl -L https://github.com/phpredis/phpredis/archive/5.1.1.tar.gz | tar xvz -C /usr/src/php/ext/redis --strip 1 \
&& echo 'redis' >> /usr/src/php-available-exts \
&& docker-php-ext-install redis
RUN pecl install timecop-beta \
&& docker-php-ext-enable timecop
RUN pecl install apcu \
&& docker-php-ext-enable apcu
# install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
ソケット通信の設定ファイルは、「zzz-」をつける必要があります
PHPの公式DockerイメージでUNIXソケット通信しようとして罠にハマるの巻
ADD www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
- www.conf
ソケット回りの設定等
[www]
listen = /var/run/php7-fpm.sock
listen.owner = www-data
listen.group = www-data
request_terminate_timeout = 30s
###local/application/docker-compose.yml
version: '3.7'
volumes:
php_sockert:
services:
memcached:
image: memcached
container_name: memcached
redis:
image: redis
container_name: redis
mysql:
image: mysql:5.7.31
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --max_allowed_packet=32M
environment:
MYSQL_ROOT_PASSWORD: ********
MYSQL_DATABASE: mysql_database
MYSQL_USER: user
MYSQL_PASSWORD: ********
TZ: "Asia/Tokyo"
ports:
- "3306:3306"
volumes:
- ../application/mysql/:/docker-entrypoint-initdb.d/
- ../dump/:/dump/
- ../mysql/:/etc/mysql/conf.d/
- ./misc/data:/var/lib/mysql
container_name: mysql
nginx:
build: ./nginx
ports:
- "80:80"
- "443:443"
environment:
TZ: "Asia/Tokyo"
volumes:
- ../../local/:/var/www/local
# local複数環境用 - ../../test/:/var/www/test
- php_sockert:/var/run
depends_on:
- web
container_name: nginx
web:
build: ./php-fpm
tty: true
privileged: true
ulimits:
core: -1
volumes:
- ../application/web/initial_web.sh:/tmp/initial_web.sh
- ../../local/:/var/www/local
# local複数環境用 - ../../test/:/var/www/test
- php_sockert:/var/run
depends_on:
- mysql
- memcached
- redis
- rabbitmq
environment:
DATABASE_HOST: 'mysql'
DATABASE_NAME: 'mysql_database'
DATABASE_USER: 'user'
DATABASE_PASSWORD: '********'
TZ: "Asia/Tokyo"
command: bash -c "bash /tmp/initial_web.sh && php-fpm"
container_name: web
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=********
links:
- mysql
ports:
- 8080:80
volumes:
- ../phpmyadmin/sessions:/sessions
- ../phpmyadmin/conf/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php
image: memcached
docker hub から落としてくるイメージです
image: mysql:5.7.31
等「:」でバージョン指定可能です
nginx:
build: ./nginx
のように記述すると、./nginx/Dockerfile を読みにいきます
Dockerfile 内で image を指定したり
command を指定したりしています
container_name: memcached
etc/hosts に上記名称が追加されます
volumes:
- ./misc/data:/var/lib/mysql
ホストの /misc/data 以下と
ゲストの /var/lib/mysql 以下が共有されます
mysql 上記データをホストとゲストを共有していないと、docker の mysql を落とすとデータが削除されます
volumes:
php_sockert:
nginx:
volumes:
- php_sockert:/var/run
web:
volumes:
- php_sockert:/var/run
nginx と web の /var/run が共有されます
ソケットで使用しています
command:
イメージが作られた時点で、記述内容が実行されます
ports:
ホストのポートとゲストのポートが結びつきます
nginx:depends_on:
- web
nginx コンテナからwebコンテナへ通信するため web 起動してから、nginx 起動するように設定
#最後に
私の関わっているプロジェクトでの local 環境を紹介いたしました
今後は
- 本文中に記述した問題の改修
- jenkins 導入
などを改修、導入できればと思っています!!
明日は @shirai_suguru です。お楽しみに!!
サムザップのアドベントカレンダーは人数の関係上2つあります。
こちらもよろしくお願いいたします!
サムザップ #2 Advent Calendar 2020 - Qiita