こんにちは。先日娘を保育園に迎えに行ったら、パズルの取り合いをしてる友達のところに娘が飛んでいって「最初はグー、最初はグーして!」とジャンケンで順番を決めるように仲裁し、勝った子に「終わったらちゃんと〇〇ちゃんに貸してあげてね!」と話しかけて負けた子のフォローまでしているのを見てビックリした木村です。
Webアプリケーションを開発したとき、本番環境にデプロイして動作確認をしている間はBASIC認証をかけておき、運用開始時に認証を外して公開するというケースはよくあると思いますが、今回はそんなときに使えるTIPSを紹介したいと思います。
対象はコンテナで動かしているApacheの場合ですが、コンテナで無くても応用は可能です。
よくあるやり方
設定していたBASIC認証を本番運用開始時に変更するには、
- サーバにログインして
httpd.confの設定を変更してhttpdを再起動する - サーバにログインして
.htaccessを直接修正する .htaccessを変更してソースツリーにコミットし、再デプロイをする
といった対処をされているケースは多いかと思いますが、サーバーの台数が増えてくると作業ミスも起こりがちです。
ミスを無くすために構成管理ツールやバッチを使ってこれらの作業を自動化してるケースもあるかと思いますが、もう少し手軽にできないかと考えました。
環境変数で制御する
Webアプリケーションでは、開発モードと本番運用モードを起動時の環境変数で切り替えて動作を変更するというのはよくあると思います。 ここでは、同様に環境変数の内容に応じてApache HTTP Serverの動作を変更できるようにしてみます。
Apache HTTP Serverの起動コマンドには-D{文字列}という引数があり、設定の中で<IfDefine 文字列>...</IfDefine>と書いておくと引数を渡したときだけこの<IfDefine>で括られた中の設定が有効になるというのを利用します。つまり、ここでは例としてBASIC認証の有無を取り扱っていますが、ほとんどの設定について切り替えることができます。
コンテナイメージの作成
例として、Apache HTTP Serverの公式コンテナイメージをベースイメージ使い、デフォルトのコンテンツ(/usr/local/apache2/htdocs/index.html)にBASIC認証をかけてそれを制御するコンテナイメージを作成します。
まずはDockerfileを準備します。
FROM httpd:latest
COPY .htpasswd /usr/local/apache2/htdocs/
COPY .htaccess /usr/local/apache2/htdocs/
COPY httpd.conf /usr/local/apache2/conf/
ENV AUTHTYPE="AUTH"
EXPOSE 80
ENTRYPOINT httpd -DFOREGROUND -D${AUTHTYPE}
コンテナイメージのビルド時に、BASIC認証をかける設定をした.htaccessならびに認証情報を書いた.htpasswdファイルをコピーし、さらに.htaccessでの設定が有効になるようにしたhttpd.confをコピーします。
コピーする.htpasswdを作ります。opensslコマンドを使って作る場合は以下のようにしますが、htpasswdコマンドなどで作成しても問題ありません。
echo "test:$(openssl passwd -apr1 1234)" > .htpasswd
コピーする.htaccessファイルを作ります。
Satisfy Any Order deny,allow Deny from all <IfDefine NOAUTH> Allow from all </IfDefine> AuthType Basic AuthName "Please enter your basic auth password" AuthUserFile /usr/local/apache/htdocs2/.htpasswd Require valid-user
NOAUTHが定義されていたら「全ての接続を許可」とします。これに加えてSatisfy Anyと書くことで、BASIC認証の設定があってもAllow from allがあれば接続が許可されるようになります。
コピーするhttpd.confは、ドキュメントルートである/usr/local/apache2/htdocsディレクトリで.htaccessファイルによる設定の上書きを許可するように設定してください。
例えば
<Directory "/usr/local/apache2/htdocs">
AllowOverride All
</Directory>
などとします。
ここまでできたらコンテナをビルドします。ここでは以下のコマンドを使い、コンテナにmyhttpdという名前を付け、latestというタグを付けてビルドします。
docker build -t myhttpd:latest ./
コンテナの起動と動作確認
では、早速起動してみましょう。最初は環境変数を追加せずに動かしてみます。
docker run --rm -it --name myhttpd -p 80:80 myhttpd:latest
http://localhost/に接続してみましょう。

BASIC認証がかかってますね。
では、今度は環境変数にAUTHTYPE=NOAUTHを渡して動かしてみます。
docker run --rm -it --name myhttpd -p 80:80 -e AUTHTYPE=NOAUTH myhttpd:latest
先ほど接続したhttp://localhost/をリロードしてみます。

BASIC認証無しでアクセスできました。
念の為、AUTHTYPEに別の文字列を設定して動かしてみます。
docker run --rm -it --name myhttpd -p 80:80 -e AUTHTYPE=AUTH myhttpd:latest

先ほどアクセスできた画面をリロードしてみると、今度はBASIC認証がかかっていることが分かります。
Azure AppService for Containerで動かす場合
このコンテナをAzure AppService for Containerで動かす場合、設定は「構成」→「アプリケーション設定」で行えます。

なお、AppServiceでは設定を変更するとアプリケーションが自動で再起動しますが、それだけではこの設定は反映されません。コンテナ自体を再起動する必要があるので、「概要」から「再起動」をしましょう。

AppServiceには「デプロイスロット」という機能もあるので、これと組み合わせるとステージングだけはBASIC認証をかけるといったようにさらに便利に使えると思います。
他のコンテナ実行サービスで実行する場合も、コンテナ起動時に渡す環境変数を設定する方法があると思いますのでそちらで設定してください。
まとめ
今回は、環境変数を使ってDockerで動かすApache HTTP Serverの設定を切り替える方法を紹介しました。BASIC認証の有無を変えるだけでなく、IPアドレスでのアクセス制限やRewriteの設定、キャッシュヘッダーの制御など多くの設定が同じ方法で簡単に切り替えができます。
皆さんの参考になれば幸いです。


