Docker上のリバースプロキシで静的コンテンツを複数コンテナ間と共有
リバースプロキシをたてて複数サイトをマルチドメインで運用しているため 、静的コンテンツの配信をちょっと考える必要があった。
場当たり的に、リバースプロキシの配下にstaticフォルダを作成して、別コンテナのファイルをコピーして置いておいたけど、全く関係のないコンテナに資産をおいて管理上問題がある。
特によくないと感じたのは、1サービスで変更をおこなっても、全サービスに影響のあるリバースプロキシをdocker-compose up -d –buildし直す必要がある点です。
何かあってからでは遅いと考え、構成を見直しました。

共有ボリュームの作成
ターミナルを開いて以下のコマンドを実行します。
以下のコマンドで共有のボリュームを作成します。
docker volume create static_file_share
作成結果を確認します。
docker volume ls
Nginxとginx側の見直し
docker-comopose.ymlの修正
まずは、リバースプロキシのnginx側のdocker-compose.yml
作成したボリュームを追記します。
Compose の外ですでに作成済みの volume を指定するため、externalには ture を設定します。 これにより、 docker-compose up 時に Compose は volume を作成しません。
version: '3'
services:
proxy:
build: ./proxy
tty: true
image: dc_proxy
container_name: dc_proxy
ports:
- "80:80"
- "443:443"
volumes:
- '/etc/letsencrypt:/etc/letsencrypt'
- /var/run/docker.sock:/tmp/docker.sock:ro
restart: always
networks:
default:
external:
name: dc_proxy_nw
# volumes を定義
volumes:
static_file_share:
external: true
Nginxのconfigファイル
nginxのconfigファイルは変更しません。アプリケーション側で静的コンテンツをコピーする際に、現状と同じ構成になるようにします。
...
# staticfiles
location /static/ {
alias /static/mt/static/;
}
location / {
root /static/mt/html/;
index index.html;
}
location /api/ {
proxy_pass http://mt:8000;
}
}
アプリケーション側の修正
アプリケーションはDjangoのRest Api Frameworkです。
リバースプロキシ側の設定は変更しなかったので、アプリケーション側のファイル配置を見直します。

docker-compose.ymlの修正
先ほどと同様、 作成したボリュームを追記します。
...
volumes:
static_file_share:
external: true
また、静的ファイルが格納されているフォルダを、共有フォルダにマウントします。
...
web:
# Dockerfile が存在するディレクトリの相対パスを指定する
build: .
# コンテナ実行時に実行するコマンド
command: uwsgi --ini ./app/app.ini
# コンテナの /code を、ホストのカレントディレクトリにマウントする
volumes:
- .:/code
- "static_file_share:/static"
ちなみに、Djangoの場合、静的コンテンツは、以下のコマンドで収集します。
python manage.py collectstatic
Dockerfileの修正
静的コンテンツをコピーする処理を追加します。が、もともと、カレントディレクトリ配下をすべてコピーしていたので、今回は修正不要です。
# カレントディレクトリ配下を /code 配下にコピーする ADD . /code/
動作確認
それでは、それぞれ起動しなおし、動作確認をおこないます。
docker-compose up -d --build
無事、index.htmlが参照され動きました。
