FastAPI(62)- FastAPI 部署在 Docker
- 2021 年 10 月 8 日
- 筆記
- FastAPI, 測試高級進階技能系列 - FastAPI
Docker 學習
//www.cnblogs.com/poloyy/p/15257059.html
項目結構
. ├── app │ ├── __init__.py │ └── main.py ├── Dockerfile └── requirements.txt
FastAPI 應用程式 main.py 程式碼
from typing import Optional 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: Optional[str] = None): return {"item_id": item_id, "q": q}
Dockerfile
# 1、從官方 Python 基礎鏡像開始 FROM python:3.9 # 2、將當前工作目錄設置為 /code # 這是放置 requirements.txt 文件和應用程式目錄的地方 WORKDIR /code # 3、先複製 requirements.txt 文件 # 由於這個文件不經常更改,Docker 會檢測它並在這一步使用快取,也為下一步啟用快取 COPY ./requirements.txt /code/requirements.txt # 4、運行 pip 命令安裝依賴項 RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt # 5、複製 FastAPI 項目程式碼 COPY ./app /code/app # 6、運行服務 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
第四步:運行 pip 命令解析
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
- –no-cache-dir 選項告訴 pip 不要將下載的包保存在本地,因為只有當 pip 將再次運行以安裝相同的包時才會這樣,但在使用容器時情況並非如此
- –no-cache-dir 只與pip有關,與 Docker 或容器無關
- –upgrade 選項告訴 pip 升級已經安裝的軟體包
- 因為上一步複製文件可能會被 Docker 快取檢測到,所以這一步也會在 Docker 快取可用時使用
- 在這一步中使用快取會在開發過程中一次又一次地構建鏡像時節省大量時間,而不是每次都下載並安裝所有依賴項
Docker 快取
這裡有一個重要的技巧 Dockerfile,首先只複製依賴項的文件,而不是 FastAPI 應用程式程式碼
COPY ./requirements.txt /code/requirements.txt
- Docker 和其他工具以增量方式構建這些容器映像,在另一層之上添加一層
- 從 Dockerfile 的頂部(首行)開始,由 Dockerfile 的每個指令來創建任何文件
- Docker 和其他工具在構建鏡像時也是用內部快取
- 如果文件自上次構建容器鏡像後沒有更改,則它將重用上次創建的同一層,而不是再次複製文件並從頭開始創建一個新的層
- 僅僅避免文件副本並不一定會改善太多,但是因為它在該步驟中使用了快取,所以它可以在下一步中使用快取
- 例如,它可以將快取用於安裝依賴項的指令
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
- requirements.txt 不會經常改變,所以通過複製該文件,Docker 可以在該步驟中使用快取
- Docker 將能夠使用快取進行下一步下載和安裝這些依賴項,這就是節省大量時間的地方
- 下載並安裝該軟體包的依賴關係可能需要幾分鐘,但使用的快取將只需要幾秒
- 由於在開發過程中一次又一次地構建容器鏡像以檢查程式碼更改是否有效,因此可以節省大量累積時間
COPY ./app /code/app
- 在 Dockerfile 尾部,複製 FastAPI 應用程式程式碼
- 由於這是最常更改的內容,因此將其放在最後,在此步驟之後的任何內容都將無法使用快取
構建 Docker Image
在 Dockerfile 打開命令行
docker build -t myimage .
查看鏡像
docker images
啟動 docker 容器
docker run -d --name mycontainer -p 80:80 myimage
查看容器
docker ps
訪問 127.0.0.1/
訪問 127.0.0.1/docs
帶有 Gunicorn 的官方 Docker 鏡像 – Uvicorn
- 此鏡像包含一個自動調整機制,可根據可用的 CPU 內核設置工作進程的數量
- 它具有合理的默認值,但仍然可以使用環境變數或配置文件更新所有配置
- 此鏡像上的進程數是根據可用的 CPU 內核自動計算的,它將嘗試從 CPU 中榨取儘可能多的性能
- 但這也意味著,由於進程數取決於容器運行的 CPU,消耗的記憶體量也將取決於此
- 因此,如果應用程式消耗大量記憶體(例如使用機器學習模型),並且伺服器有很多 CPU 內核但記憶體很少,容器最終可能會使用比可用記憶體更多的記憶體,這會大大降低性能(甚至崩潰)
官方栗子
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 COPY ./requirements.txt /app/requirements.txt RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt COPY ./app /app
應用場景
- 如果正在使用 Kubernetes,並且已經設置了集群級別的複製,就不應該使用此鏡像,最好從頭開始構建鏡像
- 如果應用程式足夠簡單,以至於根據 CPU 設置默認進程數效果很好,不想費心在集群級別手動配置複製,並且運行的容器不會超過一個應用程式
- 或者如果使用 Docker Compose 進行部署,在單個伺服器上運行等
使用 poetry 的 docker image
# 第一階段:將僅用於安裝 Poetry 並從 Poetry 的 pyproject.toml 文件生成帶有項目依賴項的 requirements.txt。 FROM tiangolo/uvicorn-gunicorn:python3.9 as requirements-stage # 將 /tmp 設置為當前工作目錄;這是我們將生成文件requirements.txt的地方 WORKDIR /tmp # 安裝 poetry RUN pip install poetry # 複製 COPY ./pyproject.toml ./poetry.lock* /tmp/ # 生成 requirements.txt RUN poetry export -f requirements.txt --output requirements.txt --without-hashes # 這是最後階段,在這往後的任何內容都將保留在最終容器映像中 FROM python:3.9 # 將當前工作目錄設置為 /code WORKDIR /code # 複製 requirements.txt;這個文件只存在於前一個 Docker 階段,這就是使用 --from-requirements-stage 複製它的原因 COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt # 運行命令 RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt # 複製 COPY ./app /code/app # 運行服務 CMD ["uvicorn", "app.1_快速入門:app", "--host", "0.0.0.0", "--port", "80"]
- 第一階段 Docker 是 Dockerfile 的一部分,它作為一個臨時容器的鏡像是僅用於生成一些文件供後面階段使用
- 使用 Poetry 時,使用 Docker 多階段構建是有意義的
- 因為實際上並不需要在最終容器鏡像中安裝 Poetry 及其依賴項,只需要生成的 requirements.txt 文件來安裝項目依賴項
poetry 詳細教程
//www.cnblogs.com/poloyy/p/15267494.html