![見出し画像](https://assets.st-note.com/production/uploads/images/71251961/rectangle_large_type_2_b01b5e2451682946801c9ec6c6565e4b.jpeg?width=1200)
【記録】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 コンテナ・ネットワークの理解を試してみたいと思います。
この記事が気に入ったらサポートをしてみませんか?