見出し画像

【記録】dockerでnginxとFastAPIを動かす

dockerでnginxとFastAPIのふたつを動かします。
何点かつまづいたところがあるので、そこを記録しました。

nginxとFastAPIをつなぐ方法を調べる

まず、目標を確認しておきます。
Nginx+gunicorn構成でFlaskを使う【ローカル環境編】を参考にしました。
参考にしたページではFlaskとなっていますが、先にFastAPIを動かしていたので、今回はFastAPIで進めていきます。

環境と要点をまとめると次のようになります。

・nginxとFastAPI(+WSGIサーバ)が動いていること
・nginx(=webサーバ)はReverse Proxyとしても動かすこと

FastAPIを動かす

FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。

引用元:https://fastapi.tiangolo.com/ja/

このページにはインストール方法も書かれていて、下記で動かすことができると書いてありました。

$ pip install fastapi
$ pip install uvicorn[standard]

このインストールはpip、つまりpythonです。
pythonの環境が必要。

FastAPIをdockerで動かしていた記事がありましたので、こちらを参考にしました。
参考:【コピペOK】DockerfileとbuildでDockerイメージを作成する手順

必要なのは3つ。
・Dockerfile(docker runに使う)
・requirements.txt(pythonのpipインストールに使う)
・main.py(プログラム。これでFastAPIを利用する)


Dockerfile:
【コピペOK】DockerfileとbuildでDockerイメージを作成する手順からコピペ
この中で、requirements.txtとmain.pyのコピー、ポート8000でFastAPIを起動などをしています。

FROM python:3.8-alpine

# コンテナイメージ内において、作業用ディレクトリ(/app)を作成
WORKDIR /app

# 「PythonのFastAPIでREST API(GET)を実現する」プログラムを/appへコピー
COPY requirements.txt .
COPY main.py .

# コンテナイメージ内で必要なパッケージをインストール
RUN apk add --no-cache build-base \
&& pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt \
&& apk del build-base

# コンテナイメージ内で、 「PythonのFastAPIでREST API(GET)を実現する」プログラムを8000ポートで起動
EXPOSE 8000
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]


requirements.txt:

fastapi
uvicorn[standard]


main.py:
https://fastapi.tiangolo.com/ja/にあるアプリケーション例を使用

from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def read_root():
   return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
   return {"item_id": item_id, "q": q}


3つのファイルを同じディレクトリに入れて、docker buildします

$ docker build -t fastapi:1 .

ビルドが成功した、docker imagesで確認。成功していたらfastapiが出てきます。

$ docker images

ここで終わりですが、FastAPIをテストしたときは、以下を行います。

$ docker run -p 8000:8000 -ti fastapi:1

http://127.0.0.1:8000/にアクセスするとレスポンスが返ってきます。

その後dockerコンテナは削除しておきます。
(後半で別の方法で起動するため)


nginxを設定込みで動かす

nginxの設定は、外部ファイルを読み込むことができるらしいので、それを使うことを目標にします。

具体的には、次の2点を目指しました。
・Dockerfileで設定用ディレクトリを作成する(今回は、/home/nginx)
・ディレクトの中に外部ファイルを入れてマウントする

Dockerfileには、「RUN mkdir /home/nginx」の追加と、起動コマンドを書き換えて、「CMD ["nginx", "-c", "/home/nginx/my.conf", "-g", "daemon off;"]」としてあります。
※ nginxの-cオプションは、設定ファイルを指定するためのオプション


Dockerfile:
dockerhub、nginx公式のDockerfileに追記

#(中略)
RUN mkdir /home/nginx
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx", "-c", "/home/nginx/my.conf", "-g", "daemon off;"]


my.confはnginxの設定を書いたファイルです。
「proxy_pass http://ap1:8000;」で転送先を指定しています。
本当なら、http://localhost/やhttp://XXXX.com/みたいな書き方ですが、FastAPIとnginxのコンテナが違うためhttp://localhost/は繋がりませんし、http://XXXX.com/のように別サーバにあるわけでもありません。
このap1はdockerのコマンドでディレクトリをマウントするみたいに繋げます。

my.conf:
docker上のnginxから、別のコンテナのwebへリバースプロキシさせるを参考にしました。

worker_processes 1;
events {
 worker_connections 512;
}
http {
 server {
   listen 80;
   server_name INFRA-PRACTICE-NGINX;
   charset UTF-8;
   proxy_set_header Host $host;
   proxy_set_header X-Forwarded-Host $host;
   location / {
     proxy_pass http://ap1:8000;
   }
 }
}


docker buildします。

$ docker build -t nginx:1 .


FastAPIとnginxを起動する

ここの部分も、docker上のnginxから、別のコンテナのwebへリバースプロキシさせるを参考にしました。

今の状況は、nginxとFastAPIが用意できています。
次はnginxとFastAPIを実際に動かします。

まず、FastAPI。
nginxの設定でhttp://ap1がないので、FastAPIはap1になってもらいます。
参考にしたサイトによると、コンテナ名「--name ap1」を付け、nginxから参照できるようにすることと、「-p 80:80」などしないとのことでした。

$ docker run --name ap1 -ti fastapi:1


次に、nginx。
nginxは設定my.confを指定のフォルダに置くようにしています。
・-v /C/nginx/log:/var/log/nginx/ ⇒ nginxのログがC:\nginx\logに
・-v /C/nginx/nginx:/home/nginx/ ⇒ C:\nginx\nginxにmy.confをおく
・--link ap1:ap1 ⇒ nginxのap1とFastAPをつなぐ

docker run -ti -p 80:80 -v /C/nginx/log:/var/log/nginx/ -v /C/nginx/nginx:/home/nginx/ --link ap1:ap1 nginx:1


http://localhost/に接続するとnginx⇒FastAPIと接続されることを確認しました。


次は?

コンテナ・リンク機能(古い機能)に、--linkフラグは過去の機能と説明されていました。

今度は、Docker コンテナ・ネットワークの理解を試してみたいと思います。




この記事が気に入ったらサポートをしてみませんか?