Google Compute Engine + Let's EncryptでRedash構築

RedashをGoogle Cloud Platformにホストする上で、Redashの公式ドキュメントの通り行かなかったことがあるので備忘録として残します。

Redashインスタンスの生成

Redashイメージのインストール

Setting up a Redash Instance | Redashにある通り、google cloud shellにアクセスして以下のコマンドを実行する。

$ gcloud compute images create "redash-5-0-2" --source-uri gs://redash-images/redash.5.0.2-b5486-build2.tar.gz

これで、GCEにRedashのイメージが作成される。

Redashインスタンスの生成

続いて、google cloud shellから同様に以下のコマンドを実行する。

$ gcloud compute instances create redash --image redash-5-0-2 --zone asia-northeast1-a

今回は東京リージョンにインスタンスを作りたかったので、--zone asia-northeast1-aをオプションとしてつけた。

Redashの公式ドキュメントではこの後すぐにRedashの管理者作成を行なっているが、

インスタンスファイアウォールの編集から「HTTP トラフィックを許可する」にチェックを入れる必要があった。

Google CloudからSSHしてみると、/opt/redash以下にdocker-compose.ymlPostgreSQLのデータディレクトリが存在していた。

IPアドレスの固定

Google CloudではIPアドレスが2種類存在する。

エフェメラルは「束の間の」「儚い」という意味らしい。

その名の通り、インスタンス実行中のみ割り当てられるIPアドレスで、インスタンス終了と同時にインスタンスから解放されてしまう。

SSL化したいのでドメイン名を設定するつもりだし、ドメインを設定するには変化しない静的外部IPアドレスが適している。

GCP公式ドキュメントに沿ってエフェメラル外部IPアドレスを静的外部IPアドレスに変更した。

ドメイン名は諸々の事情でそのIPアドレスに対して、AWSのRoute 53で設定した。

Let's Encrypt(Certbot)

Redashはアカウント情報があり、ユーザーはログインのために、ユーザー名とパスワードを入力する必要がある。

暗号化せずにその情報を垂れ流すのは嫌だったので、Let's Encryptを使ってSSL化することにした。

インストール

RedashのインスタンスSSHして(今度はgoogle cloud shellではない)、

Let's Encryptの公式ドキュメント通りに以下のコマンドを叩いた。

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot

SSL証明書の発行

Let's Encryptのcertbotコマンドには色々なオプションが存在して、迷ってしまった。

今回は、設定ファイルの自動生成などには頼りたくなかったので、certbotスタンドアローンモードで起動することにした。

certbotスタンドアローンモードで起動するには、ドメイン検証のために80番ポートを使う必要があるので、もしRedashが80番ポートを使っているなら一旦サーバーを落とす必要がある。

$ cd /opt/redash
$ sudo docker-compose down

RedashのNGINXが落ちたのを確認して、certbotにオプションをつけてSSL関連のファイルを取得した。

$ sudo certbot certonly --standalone -d redash.example.com -m email@example.com --agree-tos -n

以上のコマンドを実行すると、/etc/letsencrypt以下にSSLの関連ファイルが生成される。

SSL

certbotで生成した鍵ファイルを使ってnginxをSSLに対応させるため、設定ファイルを変更する必要がある。

今回は、設定ファイルを/opt/redash/nginx/nginx.confに作って、Dockerでその設定ファイルをマウントすることにした。

NGINXの設定

/opt/redash/nginx/nginx.conf

upstream redash {
  server redash:5000;
}
 
server {
  listen 80 default;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;

  ssl_certificate     /etc/nginx/conf.d/redash.example.com/fullchain.pem;
  ssl_certificate_key /etc/nginx/conf.d/redash.example.com/privkey.pem;
 
  gzip on;
  gzip_types *;
  gzip_proxied any;
 
  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_pass       http://redash;
  }
}

docker-composeの設定

/opt/redash/docker-compose.yml

version: '2'
x-redash-service: &redash-service
  image: redash/redash:5.0.2.b5486
  depends_on:
    - postgres
    - redis
  env_file: /opt/redash/env
  restart: always
services:
  server:
    <<: *redash-service
    command: server
    ports:
      - "5000:5000"
    environment:
      REDASH_WEB_WORKERS: 4
  scheduler:
    <<: *redash-service
    command: scheduler
    environment:
      QUEUES: "celery"
      WORKERS_COUNT: 1
  scheduled_worker:
    <<: *redash-service
    command: worker
    environment:
      QUEUES: "scheduled_queries"
      WORKERS_COUNT: 1
  adhoc_worker:
    <<: *redash-service
    command: worker
    environment:
      QUEUES: "queries"
      WORKERS_COUNT: 2
  redis:
    image: redis:3.0-alpine
    restart: always
  postgres:
    image: postgres:9.5.6-alpine
    env_file: /opt/redash/env
    volumes:
      - /opt/redash/postgres-data:/var/lib/postgresql/data
    restart: always
  nginx:
    image: redash/nginx:latest
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - server
    links:
      - server:redash
    volumes:       # SSL化のためNGINXの設定ファイルと鍵ファイルをマウント
      - /opt/redash/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - /etc/letsencrypt/live/redash.example.com/fullchain.pem:/etc/nginx/conf.d/redash.example.com/fullchain.pem
      - /etc/letsencrypt/live/redash.example.com/privkey.pem:/etc/nginx/conf.d/redash.example.com/privkey.pem
    restart: always

Redashの起動

以上で、SSL化用の鍵ファイルと各種設定ファイルが完成した。

GCPファイアウォールの編集で「HTTP トラフィックを許可する」にチェックを入れて、

$ sudo docker-compose up -d

でRedashを起動。

無事、https://redash.example.comにアクセスできることが確認できた。