1. VPS上にnginx proxy + Let’s Encrypt のコンテナを立てる
その0に記載の通りCloudflareとVPS間の通信はLet’s Encryptを使用してSSL化したいのと、VPS内では複数サービスが動いているのでリバースプロキシによる振り分けを行いたいです。
使用するのは以下の2つ。有名だと思うので使い方はいっぱい見つかると思います。
nginxproxy/nginx-proxy – Docker Image | Docker Hub
nginxproxy/acme-companion – Docker Image | Docker Hub
実際に設定した内容はこんな感じ。
$ cat docker/proxy/docker-compose.yml
version: '3.8'
services:
nginx-proxy:
image: nginxproxy/nginx-proxy
container_name: nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./nginx-proxy/certs:/etc/nginx/certs:ro
- ./nginx-proxy/vhost:/etc/nginx/vhost.d
- ./nginx-proxy/html:/usr/share/nginx/html
- ./nginx-proxy/conf.d:/etc/nginx/conf.d
- proxy-dhparam:/etc/nginx/dhparam
networks:
- proxy-nw
restart: always
environment:
TZ: Asia/Tokyo
DHPARAM_GENERATION: "false"
# letsencrypt-nginx-proxy-companion:
nginx-letsencrypt:
image: nginxproxy/acme-companion
container_name: nginx-letsencrypt
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./nginx-proxy/certs:/etc/nginx/certs
- ./nginx-proxy/vhost:/etc/nginx/vhost.d
- ./nginx-proxy/html:/usr/share/nginx/html
- proxy-acme:/etc/acme.sh
networks:
- proxy-nw
restart: always
depends_on:
- nginx-proxy
environment:
TZ: Asia/Tokyo
DEFAULT_EMAIL: "[email protected]"
NGINX_PROXY_CONTAINER: nginx-proxy
volumes:
proxy-dhparam:
proxy-acme:
networks:
proxy-nw:
name: proxy-nw.shared
こんな感じで作ったら sudo
docker compose up -d
でコンテナを立ち上げましょう。
ちゃんとSSL化できてるかなってことで1つ別のコンテナサービスを立ち上げてみます。
ここではPortainerというDocker環境の管理に使えるサービスを上げてみましょう。
こんな感じでdocker-compose.ymlを作成し、立ち上げてみてください。
$ cat docker/portainer/docker-compose.yml
version: "3"
services:
portainer:
image: portainer/portainer-ce:latest
# ports:
# - 9443:9443
networks:
- proxy-nw
environment:
VIRTUAL_HOST: "portainer.fullstuckengineer.com"
VIRTUAL_PORT: "9000"
LETSENCRYPT_HOST: "portainer.fullstuckengineer.com"
LETSENCRYPT_TEST: "true"
CERT_NAME: "default"
volumes:
- data:/data
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
volumes:
data:
networks:
proxy-nw:
name: proxy-nw.shared
external: true
いくつかポイントがあるのでかい摘んで補足すると…
以下の内容ではコンテナが接続するネットワークを指定しています。
リバースプロキシであるnginx-proxyからつながる必要があるため同じネットワークを指定します。
networks:
- proxy-nw
...
networks:
proxy-nw:
name: proxy-nw.shared
external: true
以下の内容ではリバースプロキシで使用されるホスト名とリバースプロキシが内部(proxy-nw)でPortainerに接続するために使用するポートを指定しています。リバースプロキシとPortainer間の通信はHTTPで行うためHTTPS用の “9443” ではなくHTTP用の “9000” を指定します。
VIRTUAL_HOST: "portainer.fullstuckengineer.com"
VIRTUAL_PORT: "9000"
以下の内容ではLet’s Encryptに記載されるホスト名を指定しています。また、下の2行はテスト中の環境では記載し、問題なく運用できることを確認できたらコメントアウトすることをおすすめします。
LETSENCRYPT_HOST: "portainer.fullstuckengineer.com"
LETSENCRYPT_TEST: "true"
CERT_NAME: "default"
あとはCloudflare等のドメイン管理側から portainer.fullstuckengineer.com
へのDNSを設定してあげればアクセスできるようになるはずです。今回はnginx-proxyによるリバースプロキシとLet’s EncryptによるSSL化ができているかを確認したいため、Cloudflareの場合は「プロキシ ステータス」を「DNSのみ」で登録します。
DNSが浸透するまでに時間がかかる場合もあります。Portainerは初回アクセス時にAdminユーザの登録が必要で、一定時間アクセスがないと下図のような失敗状態になります。その場合はPortainerを sudo docker compose restart
で再起動してあげればOKです。
今回はPortainerを使用したいわけではないのでタイムアウト状態でも構いません。ブラウザからアクセスし、Portainerのページが表示され、ブラウザのURL部分から下図のような証明書を確認できればnginx-proxy/Let’s Encryptの構成はOKです。
ここまで確認できたらPortainerはいったん停止しておきましょう。管理用のサービスが外に公開されっぱなしはよろしくないです。でも便利なので外部に公開しない方法などで使用するか、必要なときだけ立ち上げるかして使用していくといいのかなと思います。
お疲れさまでした。次は実際にMisskeyのコンテナを立ち上げていきます。
コメント