1年経ち,Redashもバージョンアップして構成も変わり使えなくなってきたので書き直し.
RedashのGithubリポジトリにあがってるdocker-compose.ymlをそのまま使いつつ,SSLで運用できるような内容にしてみます.
準備物
version: '3'
services:
server:
image: redash/redash:${REDASH_VERSION:-latest}
command: server
depends_on:
- postgres
- redis
ports:
- "5000:5000"
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
REDASH_COOKIE_SECRET: e6f7212a1b469019f1a526d59c6c52bc9a803c20a54ed17988b9145a615e1631
REDASH_GOOGLE_APPS_DOMAIN: foobar.com
REDASH_GOOGLE_CLIENT_ID: 000000000000-bmexamplee1vklsnexamp1emm0hkl4ga.apps.googleusercontent.com
REDASH_GOOGLE_CLIENT_SECRET: 6PExamPLEbQ4dMPexAmpLenh
REDASH_HOST: redash.foobar.com
REDASH_PASSWORD_LOGIN_ENABLED: "false"
REDASH_ALLOW_SCRIPTS_IN_USER_INPUT: "true"
REDASH_DATE_FORMAT: YY/MM/DD
volumes:
- /opt/redash/redash_version:/opt/redash/current:ro
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
worker:
image: redash/redash:${REDASH_VERSION:-latest}
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: "INFO"
REDASH_REDIS_URL: "redis://redis:6379/0"
REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
QUEUES: "queries,scheduled_queries,celery"
WORKERS_COUNT: 2
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
redis:
image: redis:3.0-alpine
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
postgres:
image: postgres:9.5.6-alpine
volumes:
- /opt/redash/postgres-data:/var/lib/postgresql/data
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
letsencrypt:
image: certbot/certbot:latest
command: renew -n
tty: true
volumes:
- ssl:/etc/letsencrypt
- ssl:/var/log/letsencrypt
- ssl:/var/lib/letsencrypt
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
nginx:
image: redash/nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- /opt/redash/redash_ssl.conf:/etc/nginx/conf.d/default.conf
- ssl:/etc/letsencrypt
#- /opt/letsencrypt/etc/letsencrypt:/etc/letsencrypt
depends_on:
- server
links:
- server:redash
- letsencrypt
logging:
driver: "json-file"
options:
max-size: 3m
max-file: "5"
# 最初に1度だけ実行してSSL証明書をゲットする
# letsencrypt-certonly:
# image: certbot/certbot:latest
# ports:
# - "443:443"
# command: certonly -n -d redash.foobar.com --agree-tos -m ✉️ --standalone
# volumes:
# - ssl:/etc/letsencrypt
# - ssl:/var/log/letsencrypt
# - ssl:/var/lib/letsencrypt
volumes:
ssl:
docker-composeは.env
ファイルが存在すればそれを読みこんでくれるので,使用したいRedashのバージョン(Dockerイメージのタグ)を書いておきます.
REDASH_VERSION=2.0.0.b2963
最新を攻めていくスタイル😶
公式のredash/nginxはhttpでの設定しかないため,SSLの設定を入れたnginx.confを用意し,docker-compose.ymlでマウントして差し替えるようにしておきます.
upstream redash {
server redash:5000;
}
server {
listen 80;
server_name redash.foobar.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/redash.foobar.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/redash.foobar.com/privkey.pem;
gzip on;
gzip_types *;
gzip_proxied any;
location ^~ /.well-known/acme-challenge/ {
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;
set $le letsencrypt;
proxy_pass http://$le:80;
break;
}
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;
}
}
SSLの証明書はletsencryptで取得するので,その場所を指定.
また,証明書を更新するときはcertbotをstandaloneで起動してそこへアクセスを流すために~/.well-known/acme-challenge/
へのアクセスはcertbotへ流れるようにしました.
set $le letsencrypt;
proxy_pass http://$le:80;
になっているのは,nginxがconfigを読むときに記述されてるホストが存在するか確認するため.certbotは更新の時しか起動しないため,普通に書いてしまうとそのチェックにひっかかってconfigtest
に失敗してしまいます.
ワークアラウンドとして変数に代入しておくと,このチェックはされなくなります.
やること
1.SSL証明書を取得する
docker-compose.ymlの下のほうのコメントになっている部分を戻します.
uraura@rosemary$ docker-compose run --rm letsencrypt-certonly
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for redash.foobar.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/redash.foobar.com/fullchain.pem. Your cert
will expire on 2017-10-05. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
成功すればこんな感じ.
失敗したら気合で...ドメインが間違ってるとか,ポートが開いてないとか,そのへんはletsencryptの解説を読んでなんとかしましょう.
成功すると,dockerの名前付きボリュームssl
にSSLの証明書が保存されます.もうletsencrypt-certonly
に用は無いのでコメントアウトしてしまいましょう.
2.SSL証明書を確認する
uraura@rosemary$ docker-compose run --rm letsencrypt certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
openssl not installed, can't check revocation
-------------------------------------------------------------------------------
Found the following certs:
Certificate Name: redash.foobar.com
Domains: redash.foobar.com
Expiry Date: 2017-10-05 04:24:00+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/redash.foobar.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/redash.foobar.com/privkey.pem
-------------------------------------------------------------------------------
3.Redashを起動する
uraura@rosemary$ docker-compose up -d
Creating redash_worker_1 ...
Creating redash_letsencrypt_1 ...
Creating redash_redis_1 ...
Creating redash_worker_1
Creating redash_postgres_1 ...
Creating redash_letsencrypt_1
Creating redash_postgres_1
Creating redash_redis_1 ... done
Creating redash_server_1 ...
Creating redash_server_1 ... done
Creating redash_nginx_1 ...
Creating redash_nginx_1 ... done
uraura@rosemary$ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------------------
redash_letsencrypt_1 certbot renew -n Exit 0
redash_nginx_1 nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
redash_postgres_1 docker-entrypoint.sh postgres Up 5432/tcp
redash_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
redash_server_1 /app/bin/docker-entrypoint ... Up 0.0.0.0:5000->5000/tcp
redash_worker_1 /app/bin/docker-entrypoint ... Up 5000/tcp
redash_letsencrypt_1
は終了した状態になっていますが問題ありません.他がUPであればRedashは起動しているはずです.
4.SSL証明書を更新する
uraura@rosemary$ docker-compose start letsencrypt
Starting letsencrypt ... done
uraura@rosemary$ docker-compose logs letsencrypt
Attaching to redash_letsencrypt_1
letsencrypt_1 | Saving debug log to /var/log/letsencrypt/letsencrypt.log
letsencrypt_1 |
letsencrypt_1 | -------------------------------------------------------------------------------
letsencrypt_1 | Processing /etc/letsencrypt/renewal/redash.foobar.com.conf
letsencrypt_1 | -------------------------------------------------------------------------------
letsencrypt_1 | Cert not yet due for renewal
letsencrypt_1 |
letsencrypt_1 | The following certs are not due for renewal yet:
letsencrypt_1 | /etc/letsencrypt/live/redash.foobar.com/fullchain.pem (skipped)
letsencrypt_1 | No renewals were attempted.
さっき作ったばっかりなんで更新が無いですが...
renew
は更新期限が近くなければ勝手にスキップしてくれるので,何回実行しても問題ありません.
5.SSL証明書の更新を自動化
#!/bin/bash
pushd /opt/redash
/usr/local/bin/docker-compose start letsencrypt
/usr/local/bin/docker-compose logs -t -f letsencrypt
/usr/local/bin/docker-compose exec nginx nginx -s reload
popd
こんな感じのやつをcronとかにセットして毎日動かしておけばいい感じにSSL証明書が更新されていってくれるはずです.(作ったばっかりなので実績なし😶)
※--force-reneal
とかやれば強制的に更新かけられますが,確認やらでやりすぎたらしくRateLimitで怒られてしまいログが取れず...
まとめ
ちゃんとやるならEC2に立ててELBかましてACM..とかがお手軽かも.Redashはバージョンアップが早いのでお手軽に運用できるようにしとくのがよさそうな気がするので,あまりお金もかけたくないのでEC2単騎でがんばろうかなと思ったのでした.
あと,certbotコマンドのオプションいろいろ指定しなければならず覚えられないので,docker-compose化しておくのはこれに限らず良いなと思いました.