DockerのRedmineをHTTPS対応！NginxをリバースプロキシにしてLet’s Encryptを簡単導入

## はじめに
レンタルサーバーへDockerでRedmineをインストールしましたが、このままではHTTP通信で暗号化による保護なしとなってしまいます。
暗号化通信対応にする方法として、個人利用でよく使われる、Let’s Encryptを使って設定してみました。

おそらく一般的にはDocer-Composeの設定でLet's Encryptを設定するかと思いますが、情報が得られず設定できませんでした。
そこで、レンタルサーバーに直接NginXとcertbotをインストールして暗号化通信用のウェブサーバーを起動し、特定のURLの際にDockerのウェブアプリケーションへリダイレクトすることにします。

この方法であれば、一般的なcertbotの設定を使うことができ、オンプレ/クラウド、Dockerを利用しているかどうか、ウェブアプリケーションの種類... などに関係なく汎用的に設定可能かと思いますので、参考にしてください。

:::note tip
このようなウェブサーバーの使い方をリバースプロキシと言います。クライアント側でユーザーの代理でウェブサーバーに接続するのがプロキシ、サーバー側でサーバーの代理でクライアントへ応答するのがリバースプロキシとのことです。
:::

## 構成イメージ
ユーザーからサーバーまでのインターネット上の通信を暗号化します。ウェブアプリケーションに対応したウェブサーバーと、暗号化通信を行うウェブサーバーがそれぞれ起動されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281116/a3b65e20-e4ed-366d-b41c-36dc9d6d9ee3.png)

今回は、redmine.example.com のようにサブドメインを設定します。
www.example.com/redmine/のような方法でも設定できるはずですが、未確認です。

## 前提
- サーバーにドメイン名が設定されていること（NoIPなどのDDNSのサブドメインでもOK）
- HTTPで動作しているウェブアプリケーションがあること
- サーバーにroot権限またはsudo権限があること

紹介する手順は以下の環境で行っています。
- Kagoya cloud VPS
- ubuntu22.04

:::note info
Kagoyaの場合、ウェブブラウザ上の設定でLet's Encryptの設定も可能のようです。
https://support.kagoya.jp/kir/manual/ssl_letsencrypt/
今回はKagoya以外でも利用可能なより一般的な手順で設定します。
:::

## 設定手順
※ "example.com"はあなたの管理しているドメインネームに読み替えてください。
1. 既存のウェブサーバーのポートの設定を変更
    これまでHTTP通信標準の80番ポートを使っている場合、80番ポートはLet's Encryptの設定で使うため、使用しているサービスを当該ポートから別のポートへ変更します。
    今回は、既存のNginxが使用していたので、docker-compose.ymlのポートの設定部分を変更します。
    ```yml:docker-compose.yml
    services:
      redmine:
        ports:
          - '8080:3000'
    ```
1. サーバーへ直接Nginxをインストール
    ```bash
    sudo apt update
    sudo apt install nginx
    ```
2. Nginxを動作させる
    ```bash
    sudo systemctl start nginx
    sudo systemctl status nginx
    ```
    active (running) と表示されていれば正常に動作してます。
    http://example.com/ にブラウザでアクセスし、動作を確認します。
    
3. ファイアウォールの設定（必要に応じて）
    Ubuntu22.04の場合、UFW(Uncomplicated Firewall)が一般的に使われているようです。Nginxをインストールした後、ファイアウォールの設定を行い、HTTP(80), HTTPS(443)の各ポートを許可します。
    ```bash
    sudo ufw allow 'Nginx Full'
    sudo ufw enable
    sudo ufw status
    sudo systemctl restart nginx
    ```
3. HTTPS暗号化通信を設定するためのツール、Certbotをインストール
    ```bash
    sudo apt install certbot python3-certbot-nginx
    ```
4. Nginxの設定ファイルを確認
    Certbotが正しく証明書を取得できるよう、Nginxの設定ファイルに"server_name"ディレクティブにドメイン名を指定しておきます。設定ファイルは/etc/nginx/sites-available/defaultです。以下は「example.com」と「www.example.com」に設定する例です。
    ```bash:/etc/nginx/sites-available/default
    server {
    	listen 80 default_server;
    	listen [::]:80 default_server;
    	server_name example.com www.example.com; #使用するドメイン名を追記
     以下略
    ```
    
4. Certbotで証明書を取得
    ```bash
    sudo certbot --nginx -d example.com -d www.example.com
    sudo systemctl restart nginx
    ```
    証明書を取得できたら、Nginxを再起動し、ブラウザで接続してみましょう。HTTPS通信ができるようになっているはずです。
    ※接続できない場合、ファイアウォールのポートの設定や、ルータを通している場合はポートフォワーディングの設定を確認します。

5. 証明書の自動更新の設定
    Let's Encryptは証明書の定期的な更新が必要ですが、Certbotは証明書を自動で更新することができます。
    ```bash
    sudo systemctl status certbot.timer
    ```

6. DNSサーバーの設定
    DNSサーバーのDNSレコード設定を行います。redmine.example.com にAレコードで設定中のサーバーのIPアドレスを登録、有効化しておきます。

7. Nginxの設定を追加
    HTTPからHTTPSへのリダイレクトの設定と、HTTPS通信を行うための設定を行います。
    ```:/etc/nginx/sites-available/redmine.example.com
    server {
        listen 80;
        listen [::]:80;
        server_name redmine.example.com;
    
        # HTTPからHTTPSへリダイレクト
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name redmine.example.com;
    
        # Let's EncryptのSSL証明書のパス
        ssl_certificate /etc/letsencrypt/live/redmine.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/redmine.example.com/privkey.pem;
    
        # SSLに関する推奨設定 (Let's Encryptのスクリプトで生成される場合あり)
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
        # / にアクセスがあった場合、DockerのRedmineコンテナにプロキシ
        location / {
            proxy_pass http://localhost:8080;
            proxy_set_header Host $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 $scheme;
        }
    }
    ```
    設定を有効化するには、sites-available の設定ファイルのシンボリックリンクを sites-enabled に作成します。
    ```bash
    sudo ln -s /etc/nginx/sites-available/redmine.example.com /etc/nginx/sites-enabled/redmine.example.com
    ```
    設定のテスト・リロード
    ```bash
    sudo nginx -t
    sudo systemctl restart nginx
    ```

これでブラウザから https://redmine.example.com に接続することができるようになったはずです。お疲れさまでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281116/eb91e9d0-030d-3ee6-eb51-13cdfa88917a.png)