概要
Qiita初投稿です。
*こちらの方法は古いので今使っている方法でのノートを近く公開する予定です。
WEBサイトの開発環境を簡単に用意できるようなテンプレートを作成した時の手順メモです。
年末にDocker-compose upで開発環境作れたらとても楽なのではとやり始めたのですが、DockerやLinuxの知識不足で手こずりました。
開発は主にMacで行なっているのでMac向けの設定で書いています。
SSLの設定は、自己認証局を一から作るととても面倒なので、「mkcert」を使うことにしました。
https://github.com/FiloSottile/mkcert
メール送信テストも行いたいですね。
Postfixとか設定大変です。
なのでこれも便利な「mailCatcher」を使います。
https://mailcatcher.me/
便利な時代になりましたね。
node.jsに関して。
最初、PHPのコンテナとNodeのコンテナを分けて構築する方法を考えていましたが、browser-sync関連で上手く行きませんでした。
仕方がないので PHPのコンテナにnode.jsをインストールする方法で無理やり解決させました。
(開発環境なのでこれでよしとしました)
また、Debianのatp-getでインストール出来るnode.jsは更新が滞っていて古かったりします。
nodebrew経由でのインストールでは最新も使えるそうなので、nodebrewをコンテナ内にインストールすることで解決させました。
参考)
https://shioleap.github.io/blog/Linux/Debian/install-nodejs-on-nodebrew/
追記2019/01/22 : なんかgulp.watchが遅いから調べた
さらに追記 20190123 : docker-syncで高速になって幸せに。
構成
root
└・dataディレクトリ
└・dockerディレクトリ
└・web
├・Dockerfile
├・php.ini
├・ssl.conf
└.ssmp.conf
└・public_html
└・src
└・scss
├・index.html
├・npm_nodule_list.txt
└・npm.sh
├・.env
└・docker-compose.yml
自己認証局が作れるmkcertを使うための下準備
https://github.com/FiloSottile/mkcert
Homebrewを使ってインストールしていきます。
ちなみにWindowsではChocolateyでインストールが出来るそうです。
mkcertのインストール
#Homebrewのインストール
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
#mkcertのインストール
$ brew install mkcert
自己認証局の設置
#自己認証局のインストール
$ mkcert -install
開発用ドメインの登録
WEBサーバービルド用のDockerfileと同じディレクトリに移動してから実行すします。
今回は、localhostと開発マシンのローカルIPでの設定例にします。
例)
$ cd ./docker/web/
$ mkcert localhost 192.168.XXX.1XXX
そうするとlocalhost+1-key.pemとlocalhost+1.pemとキーペアが作られます。
ちなみにmkcertは、複数のドメインやワイルドカードの設定なども出来るようです。
#ドメイン固定の場合
$ mkcert local.hogehoge.dev
#ワイルドカードで全部のsub含める場合
$ mkcert *.hogehoge.dev
#自マシンのIPアドレスを使う場合
$ mkcert 192.168.3.100
#複数いっぺんにも可能
$ mkcert local.hogehoge.dev 192.168.3.100
Dockerfileの作成(WEBサーバー用)
公式のApache+PHPイーメージを使って、そこに必要なモジュールをインストールしていく方法にしました。
webディレクトリ内のDockerfileに読み込むイメージを指定します。
FROM php:7.2-apache
PHPのセッティング+α
7.2-apacheのイメージではOSがDebianになる様子です。
以下インストールなどはDebianのやり方で記載していきます。
まずは、WEBサイトで使うであろうPHPの各モジュールのインストールと設定をします。
ついでにここで、ssmptとvimとcurlをインストールする設定も記述していきます。
PHP辺りの設定は、docker公式のWordpressのイメージなどを参考に追加しています。
案件ごとに本番サーバーの設定が変わると思われるので、モジュールは本番環境と同じにするとよいと思います。
# install the PHP extensions we need
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libwebp-dev \
libjpeg62-turbo-dev \
libpng-dev libxpm-dev \
libfreetype6-dev \
; \
#mail送信のみのパッケージのインストール
apt-get install -y ssmtp mailutils; \
#vimのインストール
apt-get install -y vim; \
#curlのインストール
apt-get install curl; \
#php gdの設定
\
docker-php-ext-configure gd \
--with-webp-dir \
--with-jpeg-dir \
--with-png-dir \
--with-zlib-dir \
--with-xpm-dir \
--with-freetype-dir \
--enable-gd-native-ttf \
--with-png-dir=/usr \
--with-jpeg-dir=/usr; \
docker-php-ext-install gd mysqli opcache zip; \
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
| awk '/=>/ { print $3 }' \
| sort -u \
| xargs -r dpkg-query -S \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*
# set recommended PHP.ini settings
# see https://secure.php.net/manual/en/opcache.installation.php
RUN { \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.interned_strings_buffer=8'; \
echo 'opcache.max_accelerated_files=4000'; \
echo 'opcache.revalidate_freq=2'; \
echo 'opcache.fast_shutdown=1'; \
echo 'opcache.enable_cli=1'; \
} > /usr/local/etc/php/conf.d/opcache-recommended.ini
RUN a2enmod rewrite expires
ドキュメントルートの変更設定
本番環境によってはドキュメントルートが変わります。
デフォルトの/var/www/htmlのままでもいいのですが、合わせておくと何かと手間が省けるケースもあるので、ドキュメントルートを変更する設定も追加します。
#change document root
#ドキュメントルートを変更する設定
#ここは任意のディレクトリを指定します(本番環境に合わせてもOK)
#docker-compose.ymlとssl.confにもDocument Rootを設定する箇所あり
ENV APACHE_DOCUMENT_ROOT /home/XXXX/public_html/www
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
VOLUME APACHE_DOCUMENT_ROOT
sSMTPの設定
sendmail pathをssmtpで使えるようにphp.iniにて設定
[Date]
date.timezone = "Asia/Tokyo"
[Mail]
sendmail_path = "/usr/sbin/ssmtp -t"
mailcatcherがstmpのポート1025を使うので、ssmp.confにて設定
#
# Config file for sSMTP sendmail
#
mailhub=smtp:1025
FromLineOverride=YES
SSLの設定
ssl.confの設定
#SSLのキーペアを設定する
SSLCertificateFile /etc/apache2/ssl_keys/localhost+1.pem
SSLCertificateKeyFile /etc/apache2/ssl_keys/localhost+1-key.pem
Dockerfileに追加
#SSL設定
ADD ./ssl.conf /etc/apache2/sites-available/ssl.conf
ADD ./localhost+2-key.pem /etc/apache2/ssl_keys/localhost+2-key.pem
ADD ./localhost+2.pem /etc/apache2/ssl_keys/localhost+2.pem
nodebrewのインストール設定
参考URL
https://shioleap.github.io/blog/Linux/Debian/install-nodejs-on-nodebrew/
nodebrewインストール時に以下のメッセージが表示されるそうです。
参考URLの言う通りにコマンドを打つときに面倒なので、この設定をしたいと思いました。
Dockerfileに追加
#nodebrewのインストール
RUN curl -L git.io/nodebrew | perl - setup
RUN echo 'export PATH="$HOME/.nodebrew/current/bin:$PATH"' >> ~/.bashrc && . ~/.bashrc
Apacheの起動設定
最後にDockerfileにApacheをフォアグランドで起動する命令を書きます。
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
docker-compose.ymlファイルの作成
ざっくりこんな感じで設定
version: '2'
services:
db:
image: mysql:5.7
# ./data/db(ホストOS)にデータが保持される
volumes:
- "./data/db:/var/lib/mysql"
env_file: .env
httpd:
build: ./docker/web
depends_on:
- db
ports:
- "80:80"
- "443:443"
- "3000:3000"#browser-sync用
- "3001:3001"#browser-sync用
privileged: true
#ドキュメントルートを変更する設定
#左はローカルマシンのディレクトリ
#右はコンテナ内のディレクトリ
#ここは任意のディレクトリを指定します(本番環境に合わせてもOK)
#Dockerfileとssl.confにもDocument Rootを設定する箇所あり
volumes:
- "./public_html:/home/XXXX/public_html/www"
smtp:
image: schickling/mailcatcher
ports:
- "1080:1080"#MailCatcher
- "1025:1025"#smtp用
phpmyadmin:
image: phpmyadmin/phpmyadmin
env_file: .env
links:
- db
ports:
- 8080:80
volumes:
- "./phpmyadmin/sessions:/sessions"
.envはデータベース用の設定ファイル
MYSQL_RANDOM_ROOT_PASSWORD=yes
MYSQL_DATABASE=[データベースの名前]
MYSQL_USER=[ユーザー]
MYSQL_PASSWORD=[パスワード]
docker-syncで高速になって幸せに - docker-syncの設定
- docker for macはホスト側のvolumeをマウントしていると劇的に遅い
- docker toolboxをゴニョゴニョすればできるらしい。
- docke-syncを使うと劇速になるらしい。しかも割と簡単。
ということで、docker-syncを採用してみました。
参考URL
https://qiita.com/Satoshi_Numasawa/items/278a143aa41735e1b0da
https://github.com/EugenMayer/docker-sync
https://github.com/EugenMayer/homebrew-dockersync
まずはインストールします。
$ sudo gem install docker-sync
brew install eugenmayer/dockersync/unox
brew install fswatch unison rsync
Macに初めから入っているrubyだと権限のからみでsudoでインストールしないとpermission deniedで怒られることがあります。
*sudoでインストールしても問題なく動きました。
docker-sync.ymlにてシンクするホストのディレクトリと同期方法を指定する
「sync_strategy」にて同期の方向を決めます。
- rsync : ホスト→コンテナへの同期
- unison : 双方向の同期
version: '2'
syncs:
sync-volume:
src: './public_html'
sync_strategy: 'unison'
docker-compose-dev.yml
docker-sync.ymlの設定内容をdocker-compose.ymlを上書き設定するためのファイルの設定
version: '2'
volumes:
sync-volume:
external: true
services:
httpd:
volumes:
- sync-volume:/home/webmaster/public_html/www
まずは、imageをBuildします
$ docker-compose pull
$ docker-compose build --no-cache
docker-syncを起動してからコンテナを作成します
$ docker-sync start
$ docker-compose -f ./docker-compose.yml -f ./docker-compose-dev.yml up -d
これでやっとLAMP+ssl+メールテスト環境の出来上がりました。
mailCatcherでメール内容を確認する場合は、 "http://localhost:1080" とすると確認できます。
参考URL
https://mailcatcher.me/
node.jsのインストール
全部Dockerfileに書いてしまおうかと思っていましが、開発の環境によって色々かわるかもと思ったのでとりあえず手動でいいかなと。
あとあまり突っ込みすぎると up --buildの時に時間がかかりすぎるかななど。
*単に面倒になってきただけかも。
もしDockerfileに記述してup --buildでnode.jsのインストールまで行いたい場合はこちらが参考になるかと思います。
https://qiita.com/kenshiroh/items/f8702086e3ae29cfc350
OSが違いますが、最後の2行が参考になります。
コンテナへのログイン
コンテナへのログインは、
$ docker exec -it {コンテナ名} /bin/bash
でできます。
例として
#まずコンテナ名を調べます
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------------------------------------
php-node_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
php-node_httpd_1 docker-php-entrypoint /usr ... Up 0.0.0.0:3000->3000/tcp, 0.0.0.0:3001->3001/tcp, 0.0.0.0:443->443/tcp,
0.0.0.0:80->80/tcp
php-node_phpmyadmin_1 /run.sh supervisord -n -j ... Up 0.0.0.0:8080->80/tcp, 9000/tcp
php-node_smtp_1 mailcatcher --no-quit --fo ... Up 0.0.0.0:1025->1025/tcp, 0.0.0.0:1080->1080/tcp
#↑こんなのでます。
$ docker exec -it php-node_httpd_1 /bin/bash #return
ログインしたらディレクトリは初期設定の/var/www/htmlになっています。
まずはnode.jsのリモートの一覧を表示
$ nodebrew ls-remote
使いたいバージョンのnode.jsをインストール
#v10.15.0での例
$ nodebrew install-binary v10.15.0
# 10.15.0を使うように指示
$ nodebrew use v10.15.0
Gulpの設定
作業ディレクトリでnpmの初期化
#もし設定でドキュメントルートを変更していましたら、そちらに移動します。
$ cd /home/XXXX/public_html/www
$ npm init -y
package.jsonにrepositoryのエラーが出ないようにするために記述を追加
$ vi package.json
{
"name": "www",
"version": "1.0.0",
"main": "gulpfile.js",
"dependencies": {},
"private": true,←これ
"devDependencies": {
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"keywords": [],
"description": ""
}
Gulpをインストールする
$ npm istall —save-dev gulp
gulpへのパスが通らない場合があるので、パスを通す
$ npm link gulp
#これ一発でOK!簡単!
その他のパッケージもインストールする
npm install —save-dev gulp-sass
などなど。
インストールの時にこんなエラーが出ます。
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
これは、MacOS限定のモジュールだそうで、このエラーはそれほど気にしなくていいかもしれません。
もし気になるようでしたら、
npm install --no-optional XXXX
と--no-optionalをつけるといいそうです。
*個人的にはこのエラーは気にならなかったので、試してみてないです。
参考URL
https://mimirswell.ggnet.co.jp/blog-221
####一発でパッケージをインストールする方法
シェルスクリプトを書いて一発でインストールしちゃいます。
npm.shに以下を記述します。
#!/bin/sh
for i in `cat npm_module_list.txt`
do
npm install --save-dev $i
done
npm_module_list.txtファイルに必要なパッケージを書いていきます。
例)
gulp
gulp-sass
browser-sync
gulp-notify
gulp-plumber
gulp-sourcemaps
gulp-group-css-media-queries
gulp-autoprefixer
gulp-clean-css
gulp-uglify-es
gulp-rename
gulp-inline-source
$ bash npm.sh
browser-syncについて
proxyの設定でlocalhostを指定したら上手くいきました。
あとはdocker-compose.ymlにてポート3000と3001の設定をしてあればOK
gulp.task('browser-sync',function(done){//browser-syncのタスク設定
browserSync({
proxy:"localhost",
open: false
});
done();
});
gulp.watchについて
Gulpのその他の設定は参考文献がたくさんあるので、そちらを参照してgulpfile.jsを作っていけば良いかと思います。
ただDockerコンテナのDebianなどでbrowser-syncを使うと、指定したファイルが更新しても、browser-syncの方で認識しないようです。
その場合はポーリングの設定をするといいとの情報がありました。
具体的には、gulpfile.jsで記述する際に
gulp.watch(paths.scss + '**/*.scss',{ usePolling: true }, gulp.series('scss'));
とするといいようです。
参考URL
https://github.com/floatdrop/gulp-watch/issues/213
https://www.kimurak.net/wordpress/angularjs/2372/
これで、快適開発環境が作れました!!
追記 : 思ったらなんか"gulp.watchが遅い!!!ので調べた
https://blog.hanhans.net/2017/05/23/docker-for-mac-slow/
ホスト側のディレクトリのマウントに関して前から問題が出ていたんですね。
なんか方法があるようですが、ちょっとハードルが高い。
しばらくはコンテナ内でgulp.watchは避けた方がいいかも…。
せっかくまとめましたが、node.jsをコンテナに入れてという方法はしばらく封印します。
とても快適です。