tDiaryをDocker Composeで動かす

nogajun
nogajun

_ tDiaryのDockerイメージはあるけど、ドキュメントは無いしDocker Hubのページにもなんにも書いていないので動かし方を書いておきます。 この時代に新規にtDiaryを使う変わり者はいないと思うので既存データを持ってくる前提です。

ディレクトリを作成して、その中に既存tDiaryの日記データフォルダ、公開フォルダ、tdiary.confをコピーします。

 tDiary/
 ├ data/ tDiaryの日記データフォルダ
 ├ public/ 公開フォルダ
 ├ tdiary.conf tDiaryの設定
 └ docker-compose.yml 以下を参照して作成

以下のようにdocker-compose.ymlを作成します。設定は自分の環境に合わせて適宜変更してください。 このdocker-copose.ymlでは、tDiaryコンテナに直下にあるdataとpublicフォルダ、tdiary.confをバインドマウントしています。

 version: "3"

 services:
     tdiary:
         image: tdiary/tdiary
         volumes:
             - "./data:/usr/src/app/data"
             - "./public:/usr/src/app/public"
             - "./tdiary.conf:/usr/src/app/tdiary.conf"
         ports:
             - "80:9292"

これで docker-compose up -d と入力すれば動きます。

_ ローカル環境でhttpsのテストするためにmkcertを使って証明書を作る

上のtDiaryを動かす例ではhttpそのままですが、本番で動かすにはhttpsにする必要があるので前段にnginxのリバースプロキシを置いています。

SSLのテストには証明書が必要になりますが、ローカルでLet's Encryptを使ったり、OpenSSLでオレオレ証明書を作るのも面倒です。mkcertを使うと手元で手軽に証明書が生成できます。

mkcertを使ってみる

mkcertのgithubリリースページにLinux用バイナリがあるのでダウンロードします。

ダウンロードしたらバイナリに実行権限を付けておいてください。あと、ファイル名が「mkcert-v1.4.3-linux-amd64」と長いので、mkcertにリネームしておきましょう。

そして、mkcertが使うlibnss3-toolsパッケージをインストールします。

 $ sudo apt install libnss3-tools

これで準備ができたのでmkcertを使って認証局をインストールします。mkcertを使わなくなった場合は、オプションに-uninstallを指定すればアンインストールできます。

 $ ./mkcert -install

利用するドメインを列挙して証明書を発行します。

 $ ./mkcert www.example.com.localhsot foo.example.com.localhost

これで、www.example.com.localhost+3-key.pemとwww.example.com.localhost+3.pemが生成されたので、適当なディレクトリに置いておきます。

あとは、nginxの設定ファイルなどに証明書を指定します。こんな感じです。

 server {
     server_name www.example.com.localhost;

     listen 443 ssl;
     ssl_certificate /etc/letsencrypt/live/www.example.com.localhost/www.example.com.localhost+1.pem; ← これ
     ssl_certificate_key /etc/letsencrypt/live/www.example.com.localhost/www.example.com.localhost+1-key.pem; ← これ

     ssl_session_cache shared:le_nginx_SSL:10m;
     ssl_session_timeout 1440m;
     ssl_session_tickets off;

     ssl_protocols TLSv1.2 TLSv1.3;
     ssl_prefer_server_ciphers off;

     ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

     後略
 }

_ Docker Compose同士のネットワークをつなぐにはどうしたらいい?

Docker Composeは、デフォルトでcomposeファイルだけの閉じたネットワークを自動作成するので他のネットワークとはつながりません。ネットワークは、 docker network ls で確認できます。何も指定していない場合「 _(サービス名)default 」というbridgeネットワークが確認できます。

共通のネットワークを作成するには、docker networkで作ります。

 $ docker network create (ネットワーク名)

作成したら、composeファイルのservicesとnetworkにネットワークに参加する設定を追記します。

 services:
     hoge:
             (中略)
         networks:
             - (ネットワーク名)

 networks:
     (ネットワーク名):
         external: true

_ Docker環境でLet's EncryptのHTTPSに対応したnginxリバースプロキシを使うには何を選ぶといい?

  • nofuture.tvでの答え: 素のnginxコンテナとホスト側(Debian)のcertbotで証明書取得と更新にした。

Let's Encryptしつつ単純にバックエンドに流すだけなら、https-portalコンテナを使うのが楽です。

ほかにも便利機能を持ったコンテナもありますが、このnofuture.tvでは「rewriteを使ってサービスごとにURLのマッピングをしなければいけない」という条件がありました。これが、便利コンテナだけで対応は難しいので最終的には素のnginxコンテナに自分で設定を追加することにしました。

そしてLet's Encryptは、certbotコンテナもありますが、Debianパッケージのcertbotを使えば証明書の取得はもちろん更新のcronも設定されているので、それを使うことにしました。

検索をしているとリバースプロキシの振り分けもLet's Encryptの取得、更新も全部コンテナだけで済まそうとして、めちゃくちゃ複雑になっている人を多く見かけました。コンテナにとらわれず自分の環境で楽に設定できる方法を考えるのがいいんじゃないでしょうか。