Docker

DockerでStreamlit+Nginxを動かす

前回はDocker上でStreamlitのデモアプリを動かしました。
今回は、NginxをStreamlitのリバースプロキシとして動作するようにしてみたいと思います。

環境

Windows 10 Pro
Docker Desktop 4.1.1
Visual Studio Code 1.62.2 + Docker extension

フォルダ構成

作業用のフォルダとしてD:\StreamlitNginxを作成し、前回作ったStreamlitフォルダをこのフォルダの下に移動します。
また、Nginx用のフォルダもこのフォルダ下に作ります。以下のような構成になります。

Nginxの設定

Nginxフォルダには、Nginx用のDockerfileと設定ファイルを用意します。

Dockerfileは以下のように、ベースイメージに対して設定ファイルをコピーするだけのシンプルなものになります。

FROM nginx

COPY ./nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

一方、設定ファイルはnginx.confという名前にします。
こちらの記事を参考にして以下のようにしました。

events {
    worker_connections  16;
}
http {
    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://streamlit:8501/;
        }
        location ^~ /static {
            proxy_pass http://streamlit:8501/static/;
        }
        location ^~ /healthz {
            proxy_pass http://streamlit:8501/healthz;
        }
        location ^~ /vendor {
            proxy_pass http://streamlit:8501/vendor;
        }
        location /stream {
            proxy_pass http://streamlit:8501/stream;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        }        
    }
}

worker_connectionsは同時接続数ですが、あまり少ないとエラーになります。
とりあえずデモアプリを動かすだけであれば、16程度あれば大丈夫かと思います。

あとはhttpのlocation設定でstrteamlitに転送しています。
後ほど触れますが、同じコンテナネットワーク内であればstreamlitという名前で接続できます。

docker-compose.ymlファイルの作成

今回は複数のコンテナを連携させますので、docker-compose.ymlファイルを用意します。
docker-compose.ymlという名前のファイルをD:\StreamlitNginxフォルダ直下に作ります。
中身は以下のようにします。

version: '3.8'

services:
  streamlit:
    build:
      context: ./Streamlit
    networks:
      shared-nw:
    ports:
      - 8501:8501
    command: hello
  nginx:
    build:
      context: ./Nginx
    ports:
      - 80:80
    networks:
      shared-nw:
networks:
  shared-nw:
    driver: bridge

ポイントはshared-nwという名前のブリッジネットワークを作成している点です。
streamlitとnginxの各サービスのnetworksに同じネットワークを設定することで、お互いに名前で接続することができるようになります。
Dockerネットワークについては、こちらの記事が大変わかりやすく解説されているかと思います。

コンテナを起動

最後にコンテナを起動します。
Dockerエクステンションがインストールされていれば、コマンドを打たなくても起動できます。

docker-compose.ymlファイルを選択、右クリックし、Compose Upを選択するだけで、イメージのビルドとコンテナの起動を行えます。

コンテナが起動したら、ブラウザでhttp://localhostにアクセスします。
Streamlitのデモ画面が見れればリバースプロキシはきちんと動いています。