LOADING...

加載過慢請開啟緩存(瀏覽器默認開啟)

loading

在IIS上部署FastAPI的後端

假設我們的 Python 環境與 uv 都已經安裝完畢,詳細安裝流程可以參考

壹、在可連網的主機上用uv啟用FastAPI網站應用

  • 在可以連網的主機上在任意路徑下,用以下指令啟用一個uv 環境

    uv init FastAPI_Test
  • uv產生的 main.py 並不符合 FastAPI的格式,將資料夾中main.py修改如下

    main.py

    from fastapi import FastAPI
    app = FastAPI()
    
    @app.get("/")
    def read_root():
       return {"Hello": "World"}
    
    @app.get("/greeting/{name}")
    def read_root(name: str):
       return {"Hello": f"{name}"}
    
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: str = None):
       return {"item_id": item_id, "q": q}
  • FastAPI_Test路徑之下,透過uv安裝相關的FastAPI的依賴

    cd FastAPI_Test
    uv add fastapi --extra standard
  • 接下來透過 uvuvicorn將這個後端執行起來

    uv run uvicorn main:app
  • 接著透過curl來測試呼

    curl http://127.0.0.1:8000/greeting/Machiel
  • 回來uvicron 的命令提示字元中,發現後端uvicorn伺服器確實被呼叫到

  • 因為我們想要將FastAPI佈署到 IIS的應用程式FastAPI_Test上,所以需要做root_path的設定,main.py修改如下

    from fastapi import FastAPI
    app = FastAPI(root_path="/FastAPI_Test")
    
    @app.get("/")
    def read_root():
       return {"Hello": "World"}
    
    @app.get("/greeting/{name}")
    def read_root(name: str):
       return {"Hello": f"{name}"}
    
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: str = None):
       return {"item_id": item_id, "q": q}
  • 修改後,需要加上/FastAPI_Test來呼叫

    重新啟動FastAPI

    uv run uvicorn main:app

    測試呼叫

    curl http://127.0.0.1:8000/FastAPI_Test/greeting/Machiel

貳、準備需要移動到離線Server的相關檔案

  • 在連網主機上,執行 uv cache dir 取得 cache 資料夾路徑,將該資料夾完整複製到離線主機對應的路徑。

  • cache 資料夾 內容過多(可能包含其他專案快取),可先清空該資料夾,也可用指令來清除 cache (uv cache clear),並刪除 FastAPI_Test 專案中的 .venv 虛擬環境資料夾,接著用以下指令重新下載依賴:

    uv sync 

    完成後,再將 cache 資料夾 中的所有內容複製出來,並一併搬移至離線主機。

  • 我們總共搬移的資料夾如下

    • uv cache dir 路徑下的檔案
    • FastAPI_Test 資料夾中的檔案

參、在離線的IIS Server 上配置FastAPI的 python後端

  • 如果我們離線的 windows 主機沒有啟用IIS,可以透過以下步驟啟用

  • IIS 啟用成功之後,在瀏覽器中訪問網址 http://localhost/,會跳出IIS的歡迎頁

  • 接著在連網主機上,執行命令uv cache dir 來得知 uv cache的路徑,將連網主機上的cache路徑下的檔案與 FastAPI_Test 資料夾中的檔案移動到離線的IIS Server上了

  • 離線的IIS Server上我們將檔案放置如下:

    • FastAPI_Test: D:/FastAPI_Test
    • uv cache的路徑下的檔案全部移到離線的IIS Server上的uv cache dir 路徑下
  • 接著我們到離線主機D:/FastAPI_Test路徑下透過 uv 同步虛擬環境與套件

    uv sync --offline
  • 接著離線的IIS Server ,透過CLI 來將FastAPI執行起來,確認uv環境在離線主機都OK

    uv run uvicorn main:app
  • 接著我們打開IIS管理員介面,新增應用程式FastAPI_Test

  • 接著用IIS HttpPlatformHandler 模組,讓IIS Server僅當代理,將APP以 Uvicorn作為ASGI 來佈署 FastAPI,如果IIS沒有安裝 HttpPlatformHandler 先到這裡下載安裝

  • 在處理常式對應中,新增模組對應

    模組對應的名稱取FastAPI_Test,另外也要在要求限制(R)中額外設定

  • 設定完後會應用程式的路徑下D:\FastAPI_Test產生 web.config檔案,如果網站組態檔沒產生,是 httpPlatformHandler 的設定區段在 IIS 父層級(通常是 applicationHost.config)被鎖定

  • 遇到這個情況,需用系統管理員權限開啟命令提示字元,執行以下兩步驟來解鎖:

    1. 先解鎖

    系統管理員權限中 CMD 執行:

    %windir%\System32\inetsrv\appcmd unlock config /section:system.webServer/handlers
    %windir%\System32\inetsrv\appcmd unlock config /section:system.webServer/httpPlatform
    1. 再回收 App Pool
    iisreset

    執行完成如下圖

  • 執行後重開IIS,先將剛剛設定的處理常式對應刪除

  • 另外,也將設定的應用程式FastAPI_Test刪掉

  • 然後,再次依照上述的設定方式,重新再次設定新增模組對應

    這次設定添加常式對應後,web.config就會自動產生了

    web.config 檔案內容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <handlers>
                <remove name="FastAPI_Test" />
                <add name="FastAPI_Test" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
            </handlers>
        </system.webServer>
    </configuration>
  • 產生的 web.config 僅有設定 HttpPlatformHandler相關的代理模式,我們還需詳細設定 uvicorn 後端,還有FastAPI 網頁應用程式的執行方式

    詳細的 web.config 設定組態檔

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
        <handlers>
          <add
            name="FastAPI_TEST"
            path="*"
            verb="*"
            modules="httpPlatformHandler"
            resourceType="Unspecified" />
        </handlers>
    
        <httpPlatform
          processPath="D:\Python\uv-x86_64-pc-windows-msvc\uv.exe"
          arguments="run python -m uvicorn main:app --host 127.0.0.1 --port %HTTP_PLATFORM_PORT%"
          startupTimeLimit="120"
          requestTimeout="12:00:00"
          stdoutLogEnabled="true"
          stdoutLogFile="D:\FastAPI_TEST\logs\python.log">
    
          <environmentVariables>
            <environmentVariable name="UV_CACHE_DIR" value="D:\FastAPI_TEST\uv-cache" />
            <environmentVariable name="UV_OFFLINE" value="true" />
            <environmentVariable name="PYTHONUNBUFFERED" value="1" />
          </environmentVariables>
        </httpPlatform>
    
        <httpErrors errorMode="Detailed" />
      </system.webServer>
    </configuration>

    有幾個地方要注意

    • processPath: 是你Server上的 uv.exe 的路徑
    • stdoutLogFile: 這裡寫的資料夾必須先手動建立 (D:\FastAPI_TEST\logs),否則無法紀錄log
    • UV_CACHE_DIR: 填寫應用程式路徑下的uv-cache資料夾,uv-cache資料夾不需事先建立
  • 全部都設定成功後,重新整理應用程式

  • 現在,我們已經在離線的IIS Server 的應用程式中佈署 FastAPI

    在命令提示字元中用curl來測試使否成功佈署

    curl http://localhost/FastAPI_Test/greeting/Peter
  • Logs資料夾中,確認FastAPI後端有確實被呼叫到

  • 如果遇到以下錯誤,是web.config 中的uv路徑 (processPath) 權限異常

  • uv路徑不能設定成以下樣式

    C:\Users\User\Documents\uv-x86_64-pc-windows-msvc\uv.exe

    需改以下這種路徑才可以

    D:\uv-x86_64-pc-windows-msvc\uv.exe

Reference

  1. getting-started-with-fastapi-using-uv-and-docker-com

  2. FastAPI 轻松上阵:IIS 部署图文教程

img_show