Apache でリバースプロキシとリダイレクトを一緒に設定する

まだまだ Apache は現役なわけです。

社内で稼働している GitBucket サーバーの一部リポジトリーを、別サーバー (別ドメイン) に移行する事になりました。
ただし、設計書などのリンクが旧サーバーを指しているため、新サーバーへリダイレクトする必要がありました。

これまで Apache にてリバースプロキシ設定していたものにリダイレクト設定を追加しましたが、それだけでは設定が有効とならなかったため、まとめました。

## 1. 構成

サーバー構成は次のとおりです。

```text
             +--------+                       +-----------+
(Client) --> | Apache | ---(reverse proxy)--> | GitBucket |
             +--------+                       +-----------+
```

上記の構成のうち、一部グループ (GitBucket のグループ) 宛のアクセスを別 GitBucket サーバーにリダイレクトするように設定します。

```text
             +--------+                       +-----------+
(Client) --> | Apache | ---(reverse proxy)--> | GitBucket |
             +--------+           |           +-----------+
                                  |
                                  |                                        +-------------+
                                  +---(グループ `test` のみリダイレクト)---> | 別 GitBucket |
                                                                           +-------------+
```

サーバーと、今回移行するリポジトリーの情報は次のとおりです。

* 移行元サーバー: `sv1.example.com`
* 移行先サーバー: `sv2.example.com`
* 移行対象グループ: `test`

グループ配下のリポジトリーをすべて移行するため、グループ以下の URL をすべてリダイレクトします。


## 2. Apache 設定

はじめに、次のとおり `Redirect` ディレクティブを設定しました。

```apache
### Version 1: リダイレクトが効かない設定
<VirtualHost *:443>
    ServerName sv1.example.com

    # (中略)

    # グループ test 宛のアクセスを sv2 にリダイレクトする
    Redirect temp /test https://sv2.example.com/test

    # リバースプロキシ設定
    ProxyPass / http://localhost:58080/
    ProxyPassReverse / http://localhost:58080/
</VirtualHost>
```

上記の設定後 Apache のサービスを再起動しましたが、リダイレクトされませんでした。

「リダイレクトとリバースプロキシは相性が悪いのか・・？」と思いぐぐってみると、ズバリの記事がありました。

[Can you use Redirect and Proxypass at the same time - Server Fault](https://serverfault.com/questions/605931/can-you-use-redirect-and-proxypass-at-the-same-time)

こちらのベストアンサーを見てみると、リダイレクト対象のパスに対して、リバースプロキシを無効化する必要があるようです。
ということで、次のとおり変更します。

```apache
### Version 2: プロキシ無効化設定
<VirtualHost *:443>
    ServerName sv1.example.com

    # (中略)

    # グループ test 宛のアクセスを sv2 にリダイレクトする
    Redirect temp /test https://sv2.example.com/test

    # グループ test 宛のアクセスをリバースプロキシ対象外とする (追加)
    ProxyPass /test !

    # リバースプロキシ設定
    ProxyPass / http://localhost:58080/
    ProxyPassReverse / http://localhost:58080/
</VirtualHost>
```

上記の設定後、リダイレクトされることを確認しました。


## おまけ

リダイレクト設定後、試しに `git clone` と `git push` してみたところ、ワーニングが出力されますが Git 操作できることが確認できました。

リダイレクトされる環境では Git 操作ができないと思っていたので、意外な結果でした。
(操作は PowerShell)

```
# git clone
PS D:\> git clone https://sv1.example.com/test/migration-test.git
Cloning into 'migration-test'...
warning: redirecting to https://sv2.example.com/git/test/migration-test.git/
remote: Counting objects: 3, done
remote: Finding sources: 100% (3/3)
remote: Getting sizes: 100% (2/2)
remote: Compressing objects: 100% (68/68)
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
```

```
# git push
PS D:\migration-test> git push origin master
warning: redirecting to https://sv2.example.com/git/test/migration-test.git/
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 265 bytes | 265.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Updating references: 100% (1/1)
To https://sv1.example.com/test/migration-test.git
   e6f3470..a9e017c  master -> master
```