2024年の秋ごろにProxmoxを我が家に導入しました。これまでラズパイ内でDockerコンテナを管理していたのも全てProxmox内のVMに移行して、これでやっとx86でDockerを管理できるようになってウハウハしとりました。

ただDockerで複数のサービスを立ち上げてアクセスする際に厄介なのがポート番号。例えばmoodleは8080番、Docmostは3000番だったりと、デフォルトでアクセスを受け付けるポート番号が違います。

普通に使う分にはどうせブックマークするのでそこまで気にしませんが、外からアクセスする場合にはサービスの数分だけポートをフォワーディングしなければならなくなります。これが結構厄介でね。そうなると自宅に引いたドメインはすべて同じで、サービスごとにポート番号を覚える必要が出てきます。

せっかくドメインという、人間にとって分かりやすく名前を付けるシステムを使っておきながら、実際にはポート番号でサービスを覚えなければならないというのは本末転倒です。

これを解決するのがリバースプロキシです。リバースプロキシ用のVMなどを用意すれば、サブドメインやサブディレクトリへのアクセスごとに内部のIPアドレスやポート番号にパケットを割り振ることができるようになります。外からのアクセスは80番(http)や443番(https)だけに限定することができて、穴ぼこだらけになることを防げるわけですね。

2025年現在ではWebサーバの代表格であるApache2やnginxにもリバースプロキシの機能が備わっています。僕は最初、nginxでリバースプロキシを構築してDocmostを運用していましたが、今回の導入先では既にApache2でリバースプロキシが組んであったので、Apache2でDocmostを動かすためのconfigを書くことになりました。

これがめちゃくちゃ困った。資料もないし、そもそもDocmostをDockerで使っている人がほぼおらん。資料なしで生成AIにあーでもないこーでもないとさせて、やっと吐き出したconfigに手を加えたら無事動作しました。

Docmost用のApache2のconfig

<IfModule mod_ssl.c>

<VirtualHost *:443>

    ServerName example.com

  

    # SSL設定

    SSLEngine on

    SSLProxyEngine On

    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem

    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    Include /etc/letsencrypt/options-ssl-apache.conf

  

    # ログレベル(詳細なデバッグ用)

    LogLevel debug

    LogLevel proxy:trace5

    LogLevel proxy_wstunnel:trace5

  

    # タイムアウト設定

    ProxyTimeout 3600

    TimeOut 3600

    KeepAliveTimeout 3600

    ProxyBadHeader ignore

    ProxyPreserveHost On

    ProxyRequests Off

  

    # 必要なヘッダー

    RequestHeader set X-Forwarded-Proto https

    RequestHeader set X-Forwarded-Port 443

  

    # 通常トラフィック

    ProxyPass "/" "http://192.168.0.XX:3000/"

    ProxyPassReverse "/" "http://192.168.0.XX:3000/"

  

    # WebSocketトラフィック - socket.io

    RewriteEngine On

    RewriteCond %{HTTP:Upgrade} websocket [NC]

    RewriteCond %{HTTP:Connection} upgrade [NC]

    RewriteRule /socket.io/(.*) ws://192.168.0.XX:3000/socket.io/$1 [P,L]

    ProxyPass "/socket.io/" "ws://192.168.0.XX:3000/socket.io/"

    ProxyPassReverse "/socket.io/" "ws://192.168.0.XX:3000/socket.io/"

  

    # WebSocket専用の設定 - collab

    <Location /collab>

        ProxyPass ws://192.168.0.XX:3000/collab

        ProxyPassReverse ws://192.168.0.XX:3000/collab

        ProxyPreserveHost On

        RequestHeader set X-Forwarded-Proto https

        RequestHeader set X-Forwarded-Port 443

    </Location>

  

</VirtualHost>

</IfModule>

GitHubにもアップしたので、さくっと使いたい方はこちらからどうぞ。 jun3010me/Apache2_ReverseProxy_config_for_Docmost

沼ったのはWebSocket関連のリダイレクト関係の設定でした。ws://IPアドレス:3000/collabにアクセスするための記述を別で追記しないといけなかった。いやいや既存の設定で全部ドメインに変換してるんだから、なんでわざわざ追記しなかんのって思うんですけどね。これがないとWebSocketの通信が疎通しませんでした。

80番の設定はこちらのファイルには記述していませんが、443にリダイレクトしているだけですので割愛します。ドメイン名やIPアドレスの値は環境に合わせて変更してください。

同じ悩みを抱えている方、これからリバースプロキシを導入したい方の助けになれば幸いです。