なぜこの記事を書いているか?
以前はMovable Typeを生業にしていたのですが、最近全く触っておらず「そろそろやり直そうかな」と思いたったものの開発環境が手元にないため「ならQiitaに投稿するか」と。手順を追ってどの様にDocker環境を作ったかのメモとなります。トライアンドエラーを含んだ作業ログなので無駄に長いです。どこかで改めてまとめたいなと思ってます。
手元の環境
- macOS Mojave 10.14.6
- Docker Desktop 2.1.0.3 (38240)
そもそも行き当たった壁
環境を確認するべくSix Apart公式サイトにて動作環境を確認。
- OS
- Linux
- Solaris / Unix
- BSD
- Mac OS X
- Windows Server 2012 R2 / 2016
- Webサーバ
- nginx 1.2.0+ (要 CGI or PSGI 環境)
- Apache HTTPD 2.0+
- IIS 8.5+
- DB
- MySQL 5.1+ (5.7.x 推奨)
- MariaDB 5.5+ (10.1.x 推奨)
- Perl
- 5.10.1+ (5.18.x 推奨、5.26.x 以上未検証)
今回は初めからDockerで構築する予定なので、OSはLinux一択(といってもどのディストリビューションやコアイメージにするかは選択肢は多いですが)。
WebサーバはまずスモールスタートするためにApache HTTPD 2.4 + cgidで行きたいと思います(今後方針変わるかもしれないけど)。
DBはMySQL 5.7で。
最後が問題でPerlのバージョンを何にするか。これは以前からずっと変わって無くて、どのバージョンにするかでLinuxの場合どのディストリビューションやリリースバージョンを選択するか決まってきてしまいます。
Perlのバージョン選択
コアイメージ探しの旅に出る(1)「Perl公式イメージ編」
まず考えたのが「推奨が5.18.xなんだからDocker HubからPerl公式イメージ使えば早いんじゃない?」というもの。結論から言うと駄目だったんですが。
まずはmt
というディレクトリを掘って、その下にdocker-compose.yml
を作ります。
version: "3"
services:
perl:
image: perl:5.18.4
まずは起動。
$ docker-compose run --rm perl bash
まずはディストロを確認。Debian GNU/Linux 8 (jessie)
でした。
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="https://bugs.debian.org/"
この状態でPerlのバージョンを確認。
# perl -v
This is perl 5, version 18, subversion 4 (v5.18.4) built for x86_64-linux
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2013, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
どこにインストールされているのか確認。
# which perl
/usr/local/bin/perl
おっと/usr/local/bin/
以下ですね。MTのCGIはデフォルトで/usr/bin/perl
を見に行くので、そちらのバージョンも見て見ます。
# /usr/bin/perl -v
This is perl 5, version 20, subversion 2 (v5.20.2) built for x86_64-linux-gnu-thread-multi
(with 40 registered patches, see perl -V for more detail)
Copyright 1987-2015, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
あ、v5.20.2
、、、MTのCGIのシェバン(CGIの1行目)を全部書き換えるのは避けたいので、この方法はお蔵入り候補。とはいえDebian GNU/Linux 8 (jessie)
のPerlのバージョンが5.20.2(対応バージョン)
らしいという事がわかっただけ良しとしましょう。
コアイメージ探しの旅に出る(2)「Apache HTTPD公式イメージ編」
Perl公式イメージが駄目なんだから、Apache HTTPD公式イメージも駄目っぽいですが、一個ずつ潰していきましょう。
docker-compose.yml
を書き換え。
version: "3"
services:
apache:
image: httpd:2.4.41
起動してディストリビューションを確認します。Debian GNU/Linux 10 (buster)
ですね。
$ docker-compose run --rm apache bash
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
Perlの場所とバージョンを確認します。v5.28.1
ですね。そっと閉じます。
# which perl
/usr/bin/perl
# perl -v
This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-linux-gnu-thread-multi
(with 61 registered patches, see perl -V for more detail)
Copyright 1987-2018, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
コアイメージ探しの旅に出る(3)「Six Apart公式ホームページ漁り編」
この時点で「最近のOSに標準で入ってるPerlって軒並みv5.26.x以上なんじゃない?MTクラウドってどうしてるの?」と思ったので、Six Apartのホームページを漁ります。こんな記事を見つけました。
読んでみると、、、さらっと書いてあるPerl 5.28
!!これはSix Apartがお墨付きを付けてると勝手に解釈して、無理してv5.18.x
にこだわらない事にしました(いや無理だし)。
Movable Type クラウド版の Perl と PHP のバージョンを変更しました。
・ Perl 5.28
・ PHP 7.3
コアイメージ探しの旅に出る(4)「Apache HTTPD公式イメージ(Alpine Linux)編」
順当に言ったらubuntu
あたりなのかもしれませんが、まずはAlpine Linux
を調べてみます。折角なのでApache HTTPD公式イメージ
のAlpine Linux
版を使ってみます。
先ほどのdocker-compose.yml
を一部書き換えます。
version: "3"
services:
apache:
image: httpd:2.4.41-alpine
起動してディストリビューションを確認します。Alpine Linux v3.10
ですね。
$ docker-compose run --rm apache bash
# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.10.2
PRETTY_NAME="Alpine Linux v3.10"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
perlの場所とバージョンを確認します。/usr/bin/perl
、v5.28.2
ですね。このイメージを基本に構築していくことに決めました。
bash-5.0# which perl
/usr/bin/perl
bash-5.0# perl -v
This is perl 5, version 28, subversion 2 (v5.28.2) built for x86_64-linux-thread-multi
Copyright 1987-2019, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Docker環境の構築開始
Apache HTTPD公式イメージ(Alpine Linux)上にCGI環境を準備する(失敗)
まず基本となるdocker-compose.yml
とDockerfile
を作ります。
自分はDockerfile
などはdocker_file
ディレクトリ内にサービス名のディレクトリを掘って置く癖があるので、そのままやってみます。
mt/
+- docker-compose.yml
+- docker_files/
+- apache/
+- Dockerfile
$ mkdir -p docker_files/apache
version: "3"
services:
apache:
build: ./docker_files/apache/
ports:
- 80:80
volumes:
- ./:/src/
FROM httpd:2.4.41-alpine
起動します。
$ docker-compose up
http://localhost/
にアクセスするとIt works!
と表示されます。ひとまずOK。
別のターミナルを開いてコンテナに入ってhttpdの場所を確認します。/usr/local/apache2/bin/httpd
にあるみたいです。/usr/local/apache2/
に色々インストールされてそうなのを確認。
$ docker-compose exec apache bash
bash-5.0# which httpd
/usr/local/apache2/bin/httpd
basg-5.0# ls /usr/local/apache2/
bin build cgi-bin conf error htdocs icons include logs modules
ひとまずhttpd.conf
をホスト側にコピーします。今回./
を/src/
にマウントしてあるので、そこにコピーする事にします(簡便のため)。
bash-5.0# cd /usr/local/apache2/conf/
bash-5.0# cp httpd.conf /src/docker_files/apache/.
ホスト側で(なくても良いのですが)、httpd.conf
を書き換えます。
<IfModule !mpm_prefork_module>
- #LoadModule cgid_module modules/mod_cgid.so
+ LoadModule cgid_module modules/mod_cgid.so
</IfModule>
Movable Type
のソース一式をmovabletype
というディレクトリ名で以下に配置します。
mt/
+- docker-compose.yml
+- docker_files/
| +- apache/
| +- Dockerfile
| +- httpd.conf
+- movabletype/
+- mt-check.cgi
+- ...
docker-compose.yml
を以下のように修正します。
version: "3"
services:
apache:
build: ./docker_files/apache/
ports:
- 80:80
volumes:
- ./movabletype/:/usr/local/apache2/cgi-bin/mt/
- ./docker_files/apache/httpd.conf:/usr/local/apache2/conf/httpd.conf
この状態でMovable Type
に必要な情報が取得できるmt-check.cgi
(http://localhost/cgi-bin/mt/mt-check.cgi
)にアクセスしてみると、、、白紙です。dockerのログには以下のように出ています。
Can't locate HTML/Entities.pm in @INC (you may need to install the HTML::Entities module)
はい、出ました。まっさらの状態でmt-check.cgi
が動作しない問題です。くじけずにcpanm
経由で入れて見ます。
bash-5.0# curl -L https://cpanmin.us | perl - App::cpanminus
bash: curl: command not found
curl
はAlpine Linux
の配布イメージには最初からは入って無いのでインストールします。
bash-5.0# apk upgrade && apk add curl
bash-5.0# curl -L https://cpanmin.us | perl - App::cpanminus
wget
のオプションが間違っていると怒られるので、--no-wget
オプションを試してみます。
bash-5.0# curl -L https://cpanmin.us | perl - App::cpanminus --no-wget
今度はmake
が無いと怒られて止まってしまいました。ついでなのでgcc
もインストールしておきます。もう一度cpanminusをインストールするとインストールできました。
bash-5.0# apk add make gcc
bash-5.0# curl -L https://cpanmin.us | perl - App::cpanminus --no-wget
HTML::Entities
をインストールします。
bash-5.0# cpanm HTML::Entities --no-wget
すると今度はEXTERN.h
がインクルードできないとエラーになります。HTML::Parser
のインストールでこけているので、apkでインストールしてしまいます。これでHTML::Entities
も一緒にインストールされます。
bash-5.0# apk add perl-html-parser
http://localhost/cgi-bin/mt/mt-check.cgi
にアクセスすると、いい感じに黄色(未インストール)のモジュールがあります。よく見るとHTML::Entities
すら黄色です。インストールしてあるはずなのに内部でエラーが出ています。根本の部分なので「まぁ動いているからいいよね」と言うわけにいかず、、、ここは戦略的撤退です。
Apache HTTPD公式イメージ(Debian GNU/Linux 10 (buster))上にCGI環境を準備する
ここで先ほどの知見が生きてきます(前向き)、Debian GNU/Linux 10 (buster)
はv5.28.1
でした。Docker HUB
で確認するとdebian:buster-slim
というイメージがあります。念のため、jessieからbusterまでのperlのバージョンを調べたので載せておきます。調べ方は以前書いた通りなので省略。
OS Version | Perl Version |
---|---|
jessie | v5.20.2 |
stretch | v5.24.1 |
buster | v5.28.1 |
基本となるdocker-compose.yml
とDockerfile
を前回のAlpine Linux
の時を参考に配置します。
mt/
+- docker-compose.yml
+- docker_files/
| +- apache/
| +- Dockerfile
| +- httpd.conf
+- movabletype/
+- mt-check.cgi
+- ...
version: "3"
services:
apache:
build: ./docker_files/apache/
ports:
- 80:80
volumes:
- ./movabletype/:/usr/local/apache2/cgi-bin/mt/
- ./docker_files/apache/httpd.conf:/usr/local/apache2/conf/httpd.conf
FROM httpd:2.4.41
<IfModule !mpm_prefork_module>
- #LoadModule cgid_module modules/mod_cgid.so
+ LoadModule cgid_module modules/mod_cgid.so
</IfModule>
この状態で起動してmt-check.cgi
にアクセスするとCan't locate Encode.pm in @INC
とDockerログにエラーが出た状態でInternal Server Error
で落ちます。apt-get
でcpanm
などを入れて様子を見ます。
# apt-get update
# apt-get upgrade -y
# apt-get install -y vim cpanminus make gcc
その後mt-check.cgi
にアクセスすると表示されました。ひとまず良しとしましょう。ただまたもやHTML::Entities
のエラーが出ています。先ほどは撤退しましたが、今回はもう少し先に進んでみます。
まずapt-get
でインストールが可能なモジュールを入れます。
# apt-get install -y \
libdbi-perl libclass-dbi-mysql-perl libclass-dbi-pg-perl \
libyaml-syck-perl libcrypt-ssleay-perl libxmlrpc-lite-perl \
libgd-perl libarchive-zip-perl perlmagick libcrypt-dsa-perl \
libipc-run-perl libcgi-psgi-perl libimager-perl \
libcache-memcached-perl libplack-perl libxml-sax-expat-perl \
libxml-sax-expatxs-perl
この時点でHTML::Entities
の黄色が消えました。ひょっとしたらAlpine Linux
でも大丈夫だったのかもしれません。心折れたのでこれ以上は追いませんが、、、
まだインストール出来ない物は以下です。cpanm
コマンドでインストールしていきます。
- Cache::File
- DBD::SQLite
- DBD::SQLite2
- Digest::SHA1
- Mozilla::CA
- XML::LibXML::SAX
- XMLRPC::Transport::HTTP::Plack
# cpanm Cache::File DBD::SQLite DBD::SQLite2 Digest::SHA1 \
Mozilla::CA XML::LibXML::SAX XMLRPC::Transport::HTTP::Plack
インストールが終わると全てのモジュールがインストールされました。勢いでPSGI関連もインストールしてしまいましたが、今後生きてくるかもしれないのでそのままの方向で。
この作業をDockerfile
にまとめると以下のようになります。
FROM httpd:2.4.41
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
vim cpanminus make gcc \
libdbi-perl libclass-dbi-mysql-perl libclass-dbi-pg-perl \
libyaml-syck-perl libcrypt-ssleay-perl libxmlrpc-lite-perl \
libgd-perl libarchive-zip-perl perlmagick libcrypt-dsa-perl \
libipc-run-perl libcgi-psgi-perl libimager-perl \
libcache-memcached-perl libplack-perl libxml-sax-expat-perl \
libxml-sax-expatxs-perl \
&& cpanm Cache::File DBD::SQLite DBD::SQLite2 Digest::SHA1 \
Mozilla::CA XML::LibXML::SAX XMLRPC::Transport::HTTP::Plack \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
docker-compose build
した上でコンテナを再起動しmt-check.cgi
にアクセスして先ほどと同じく全てのモジュールがインストールされている事を確認します。問題無いようなのでイメージ作成は一段落として次に進みます。
docker-compose.ymlを更新してMovable Typeが動作する所まで持って行く
mt-check.cgi
が動作するようになりましたがDBを用意していないので、まだMovable Type
は動作しません(SQLite使うとかいうのはここではなしで)。
またDB含め以下のコンテナを起動するようにします。
- apache
- Apache HTTPD, Perl CGIの動作するコンテナ(メイン)
- mysql
- MySQLの動作するコンテナ
- mailhog
- SMTPの設定が面倒なのでMailHogを使ってテストメールを受けられるようにします
- memcached
- 今は使いませんが後々キャッシュのテストなどに使うかも知れないので一緒に準備しておきます
色々書く事はあるのですが、上記を踏まえて以下のようにdocker-compose.yml
を書き換えます。
version: "3"
services:
apache:
build: ./docker_files/apache/
ports:
- 80:80
volumes:
- ./docker_files/apache/htdocs/:/usr/local/apache2/htdocs/
- ./docker_files/apache/httpd.conf:/usr/local/apache2/conf/httpd.conf
- ./movabletype/:/usr/local/apache2/cgi-bin/mt/
- ./movabletype/mt-static/:/usr/local/apache2/htdocs/mt-static/
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_USER: admin
MYSQL_PASSWORD: pass
MYSQL_DATABASE: mt
TZ: "Asia/Tokyo"
ports:
- 13306:3306
volumes:
- ./docker_files/mysql/mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
- ./docker_files/mysql/mysql_data:/var/lib/mysql
tty: true
stdin_open: true
restart: always
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025"
memcached:
image: memcached:1.5.19-alpine
./docker_files/mysql/mysqld.cnf
に以下のファイルを置いておきます。
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
#log-error = /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address = 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
skip-character-set-client-handshake
character-set-server=utf8
collation-server=utf8_general_ci
innodb-file-format=Barracuda
innodb-file-per-table=1
# slow-query-log=1
# slow-query-log-file=/var/log/mysql/slow-log
# long-query-time=2
[client]
default-character-set=utf8
起動して初期設定用のCGImt-wizard.cgi
にアクセスします。設定が必要な所だけ以下に列挙します。
- 使用言語
- ここでは「日本語」を選択した物として進めます
- スタティックウェブパスの設定
- スタティックウェブパス
- /mt-static
- スタティックファイルパス
- /usr/local/apache2/htdocs/mt-static
- スタティックウェブパス
- データベース設定
- データベースの種類
- MySQLデータベース(推奨)
- データベースサーバ
- mysql
- データベース名
- mt
- ユーザー名
- root
- パスワード
- pass
- データベースの種類
- メール設定
- システムメールアドレス
- (ご自分のメールアドレスを記入してください)
- メール送信プログラム
- SMTPサーバー
- 送信メールサーバー(SMTP)
- mailhog
- SMTPサーバのポート番号
- 1025
- SMTP認証を利用する
- チェックしない
- テストメールを送信し、
http://localhost:8025/
でMailHogの画面でメールが届いているか確認します- 現時点では文字化けしていますが後で修正するのでそのままで問題ありません
- システムメールアドレス
- アカウントの作成
- ユーザー名
- (ログインユーザー名)
- 表示名
- (CMSの画面上などに表示される名前です)
- 電子メール
- (ユーザーに紐付くメールアドレスです)
- 使用言語
- (ここでも「日本語」を選択したものとします)
- パスワード
- (ログインに必要なパスワードです)
- パスワード確認
- (「パスワード」欄に入力したのと同じ文字を入力します)
- ユーザー名
アカウントの作成が終わるとサイトの作成をする必要があります。「メニュー」>「システム」>「サイト」>「新規」からサイトを作成します。まずぱっと見サイトが出来た事を確認するために、ここではサイトテーマとして「クラシックウェブサイト」を使ったサイトを作成してみます。
- サイトの作成
- サイトテーマ
- クラシックウェブサイト
- サイト名
- (サイト名を自由に付けてください)
- サイトURL
- サイトパス
- /usr/local/apache2/htdocs
- タイムゾーン
- UTC+9(日本標準時)
- 使用言語
- 日本語
- サイトテーマ
サイトを作成すると「(前略)設定を反映するために再構築してください」と書いてあるので、「メニュー」の「再構築」から再構築を行います。サイトを表示すると見慣れた「ブログっぽいサイト」が表示されます。これでMovable Type
の基本的な設定は完了です。
MailHogの文字化けを解消する
MailHogの受信画面で文字化けしているのは、MailHogが日本語エンコードに対応していないからのようです。UTF-8で送って見ます。設定項目の説明ページを探したんですが英語サイトにありました。MailEncoding UTF-8
をmt-config.cgi
に追加します。
#======== MAIL =======================
EmailAddressMain mt-user@example.com
MailTransfer smtp
SMTPServer mailhog
SMTPPort 1025
MailEncoding UTF-8
一旦Movable Type
をサインアウトし、サインイン画面の「パスワードをお忘れですか?」からメールアドレスを入力してリマインダーメールを飛ばしてみます。Subjectと本文が日本語になっていれば成功です。
Mamcachedサーバの設定をする
折角コンテナを立ち上げているので、mt-config.cgi
に設定を追加してMemcached
によるキャッシュの設定を有効にしてみます(使うかどうかは別として)。
#======== Memcached ==================
MemcachedDriver Cache::Memcached
MemcachedNamespace MT
MemcachedServers memcached:11211
この設定を保存して「メニュー」>「システム」>「設定」>「システム情報」を開き、ページの上の方に「Memcachedの状態: Memcachedは設定済みです。 Memcachedサーバーは利用可能です。」と書いてあればOKです。
今回作成した設定ファイル群
以下のリポジトリで公開しています。現時点ではイメージの配布は考えていないので、イメージのスリム化などは行っていません。自分の開発に必要になったら、その時に色々とやるかも知れません。
最後に
右往左往しているのをそのまま書いてあるので、ああこういう風にやってるのねという実況的な部分が伝わるでしょうか?まとまってないので、プラグイン作成の知見など戻ってきたらそれも含めてちゃんとまとめるのもいいかもしれませんね。