LightsailにDockerでMetabaseを建てて、nginxでhttps化する


モチベーション

  • BigQueryとかPostgresに色々ため込んでいるので楽にクエリーしたい。
  • どこからでもアクセスできると嬉しい。(ので、ローカルではない場所を求めた)
  • なるべく安くしたい。(RasPiで自宅サーバーやる初期投資等から投資のNPVを考えたら、月千円くらいならいいか、と)
  • 独自ドメインかつhttps化したい(.devだと必須だし) → 本文中 YOUR-DOMAIN.HERE を自分のドメインに置き換えてね。

やったこと

Lightsailの設定

  • グローバルIPを設定しておく。
  • ネットワークの設定で、httpsで使うポート443だけを空ける。
  • (SSHの22は必要に応じて。自分の場合は別のLightsailインスタンスにVPNで繋いで作業しているので閉じたままにした。)

独自ドメインを使うということで、サブドメイン metabase.YOUR-DOMAIN.HERE をAレコードでLightsailインスタンスのグローバルIPに向けた。

コンテナ内のデータを永続化するためのディレクトリを作る

mkdir -p ~/Docker/Metabase ~/Docker/LetsEncrypt ~/Docker/nginx

Let's Encryptで独自ドメインの証明書を手配

  • Certbotの公式イメージを使った。
  • DNS認証にしているのは、複数ドメイン手配するときにやりやすかったから。
  • 発行した証明書類は/etc/letsencryptに書き出され、ホスト側で永続化される。
docker run -it --rm \
--name certbot \
-v ~/Docker/LetsEncrypt/cert:/etc/letsencrypt \
certbot/certbot certonly \
--no-self-upgrade \
--manual \
-d metabase.YOUR-DOMAIN.HERE \
-m [email protected] \
--agree-tos \
--preferred-challenges dns-01

Metabaseを立ち上げる

  • Metabaseの公式イメージを使った。
  • ulimitはいらなそうだけど癖で付けていた。
  • Metabaseの設定値を保存する先をデフォルトのH2にしていて、ファイルの作成先を/metabase-dataにした上でホスト側のディレクトリにマッピングして永続化している。
  • ホストがもう少しパワフルなら、H2の代わりにMySQLかPostgresを横に立ててもよさそう。
docker run --name Metabase -d \
--restart=always \
-v ~/Docker/Metabase:/metabase-data \
-e "MB_DB_FILE=/metabase-data/metabase.db" \
-p 3000:3000 \
--ulimit nproc=4096:4096 \
--ulimit memlock=256000:256000 \
--ulimit nofile=65536:65536 \
metabase/metabase

nginxでリバースプロキシを構成する

まず作業用のディレクトリへ移動。

cd ~/Docker/nginx

TLS対応とリバースプロキシとしての動作を定義したhttps.confファイルを作成する。

ssl_protocols TLSv1.2;
server {
    listen 443;
    ssl on;
    server_name metabase.YOUR-DOMAIN.HERE;
    ssl_certificate /etc/cert/fullchain1.pem;
    ssl_certificate_key /etc/cert/privkey1.pem;
    location / {
        proxy_pass http://metabase:3000;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;
    }
}

Dockerfile dockerfile-nginx を作成する。

FROM nginx:latest
EXPOSE 443/tcp
ADD https.conf /etc/nginx/conf.d/default.conf

イメージをビルドする。

docker build -f dockerfile-nginx -t nginx-tls .

ビルドした設定済みnginxを、証明書を指定して立ち上げる。

docker run --name nginx -d \
--restart=always \
--link Metabase:metabase \
-v ~/Docker/LetsEncrypt/cert/archive/metabase.YOUR-DOMAIN.HERE:/etc/cert \
-p 443:443 \
nginx-tls

Metabaseの書設定をする

ブラウザで https://metabase.YOUR-DOMAIN.HERE/ にアクセスして、初期設定を行う。

証明書の更新に際して

Let's Encryptの証明書は3ヶ月で期限を迎えるので、その前に更新が必要。
更新もCertbotで行う。これをcronで自動化してもいい。

docker run -it --rm \
--name certbot \
-v ~/Docker/LetsEncrypt/cert:/etc/letsencrypt \
certbot/certbot renew

メモ

  • なぜDockerかというと…
    • LightsailインスタンスでCertbotを直接動かすのが面倒
    • 試行錯誤するのにホストを汚したくない
    • 必要に応じてメモリー制限をかけたい
  • 業務用だったらこうはしない
    • ELBでhttps化してしまう

Enjoy!