VPS+Cloudflare+DockerでMisskeyサーバーを立てる(その1)- Nginx ProxyとLet’s Encrypt

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のコンテナを立ち上げていきます。

コメント

タイトルとURLをコピーしました