私が歌川です

@utgwkk が書いている

HacobuneでCGIを動かす

www.sakura.ad.jp

ということで、CGIを動かしましょう。Monkey Bananaがいいと思います。

CGIスクリプトを用意する

ダウンロードしてunzipしてリポジトリに含めるなり、docker build時にダウンロードしてくるなり、なんでもいいと思います。permissionとshebangの設定は忘れないようにしましょう。

Dockerfileを用意する

httpdイメージをベースにちょっと書きます。 monkey ディレクトリ以下にCGIスクリプトがあるものとします。

  • CGIスクリプトを設置する
  • デフォルトの index.html を消す (index.cgi を出したいので)
  • 独自の httpd.conf を設置する
FROM httpd:2.4

COPY --chown=daemon:daemon ./monkey /usr/local/apache2/htdocs

# remove default index.html
RUN rm /usr/local/apache2/htdocs/index.html

COPY ./httpd.conf /usr/local/apache2/conf/httpd.conf

monkey/dataディレクトリを .dockerignore で無視するようにしておきましょう。

httpd.confを用意する

CGIを動かすための設定項目については Docker上でApacheコンテナを作成しCGIのコンテンツを走らせるまで - ワタナベ書店 などの記事が参考になります。それに加えて設定しておくとよいものだけ抜粋して書きます。

データを記録するディレクトリは永続化したいのでボリュームをマウントすることになりますが、単にマウントするだけだと全データが丸見えなので明示的にdenyしておきます。.htaccessをボリュームに送り込むのでもよい?

<Directory "/usr/local/apache2/htdocs/data">
    Deny from all
</Directory>

正しいリクエスト元のIPアドレスをCGIから取得できるようにするために Apache と Nginx で接続元 IP を取得する方法 | Wedding Park CREATORS Blog に沿って設定を書き足しましょう。 LoadModule remoteip_module modules/mod_remoteip.so の行のコメントアウトを外して RemoteIPHeader x-forwarded-for を足せばよいです。

管理用のパスワードを環境変数経由で渡す

Twelve-Factor Appに則って、秘匿情報をコードにベタ書きせずに環境変数経由で渡すことを考えます。

httpd.confに PassEnv ディレクティブ でCGIに渡したい環境変数を指定してやれば、いつも通り $ENV{FOO} という形で参照できます。あとはアプリケーションの設定で環境変数を渡すなりなんなりすればよいです。

初期データを用意する

ボリュームは最初は空なので、このままだとCGIがうまく動きません。空データを用意する必要があります。

手っ取り早くやる、ということで以下のようなCGIを用意して一度リクエストする作戦を取りました。リクエストした後はこのCGIを消しておきましょう。

#!/usr/bin/perl
use strict;

# 設定ファイル認識
require "./init.cgi";
my %cf = set_init();

# 空ファイルを作る
system("touch $cf{logfile}");

# TODO: 初期化が完了したらこのファイルは消す
print "Content-Type: text/plain\n\n";
print "ok";

CGIをちょっと改修する

Monkey BananaではCGI::Carpというモジュールをuseしていますが、このモジュールは非推奨になってコアモジュールから外されています。新しめのPerlだとuseできないのでコメントアウトしておきましょう。

できました

ここまで来れば、あとはコンソールからぽちぽち設定してデプロイできます。GitHubリポジトリと連携すると、pushするだけで自動でデプロイされて便利です。

monkey-banana.c1.hacobuneapp.com

Hacobune特有の話題よりも、コンテナ化された環境でCGIを動かす場合の話題のほうが多かった気がします。しかしコンテナだとだいたいなんでも動かせて便利ですね。