学有所记- 探索FastAPI在docker上的部署

发布于:2025-04-01 ⋅ 阅读:(16) ⋅ 点赞:(0)

目标:

学习怎样在docker中安装部署FastAPI,完成项目结构的搭建以及hello world的运行

 

背景:

公司内服务器资源有限,为了共享算力资源,同时又能隔离运行环境,因此采用了docker部署的方式,进行各种开发测试。网上虽然已有集成fastapi+uvicorn+gunicorn,自己动手,可以了解更多细节,以及更深度的定制,从而学习怎样自定义镜像文件以及启动docker。

 

实现过程:

1、安装docker(系统已默认安装,可参照网上教程,以后另外再补记)

2、安装python。选用了3.11版

3、安装pycharm 社区版。

4、建立项目文件夹

project:my_fastapi

====app (目录)

     ----main.py

     ----requirements.txt

====docker (目录)

    ----Dockerfile

    ----docker-compose.yaml

5、编辑 main.py

import os
import sys
from multiprocessing import freeze_support

import uvicorn
from fastapi import FastAPI, UploadFile, File
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager

upload_files_save_path = os.environ["UPLOAD_FILE"] if "UPLOAD_FILE" in os.environ else "/upload"

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 初始化阶段
    print('初始化成功..')
    yield
    # 清理阶段
    print('卸载成功..')


app = FastAPI(root_path="/aiCentre"
              , lifespan=lifespan
              )  # aicentre为nginx中api路由名
# 启用CORS支持
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],  # 或者只列出 ["POST", "GET", "OPTIONS", ...] 等
    allow_headers=["*"],
)


# 路由
@app.get("/")
async def read_root():
    return {"message": "Hello World!"}

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    file_location = f"files/{file.filename}"
    with open(file_location, "wb+") as file_object:
        file_object.write(await file.read())
    return {"info": f"file '{file.filename}' saved at '{file_location}'",}


if __name__ == "__main__":
    freeze_support()

    uvicorn.run('main:app', host="0.0.0.0", port=8080, reload=True, workers=1)
    #current_dir = os.path.dirname(os.path.realpath(__file__))
    # 将项目根目录添加到 Python 路径中
    #sys.path.append(current_dir)
    # print(upload_files_save_path)

6、用pip freeze命令生成python库文件列表,用于移植。

 pip freeze > requirements.txt
annotated-types==0.7.0
anyio==4.9.0
click==8.1.8
colorama==0.4.6
fastapi==0.115.12
h11==0.14.0
idna==3.10
pydantic==2.11.1
pydantic_core==2.33.0
python-multipart==0.0.20
sniffio==1.3.1
starlette==0.46.1
typing-inspection==0.4.0
typing_extensions==4.13.0
uvicorn==0.34.0

7、编写 Dockerfile

# 建立 python3.11 环境
# FROM python:3.11

FROM docker.1ms.run/python:3.11

# 设置pip源为国内源
# COPY pip.conf /root/.pip/pip.conf
 
# 镜像作者云无碍
LABEL maintainer="yunwuai <xxx@yyyy.zzzzz>"

# 在容器内/var/www/html/下创建 mysite1文件夹
# RUN mkdir -p /var/www/html/mysite1
# 将当前目录文件加入到容器工作目录中(. 表示当前宿主机目录)
# ADD . /var/www/html/mysite1
RUN mkdir -p /app
RUN mkdir -p /upload

COPY . /app
# 设置容器内工作目录
WORKDIR /app
# RUN echo $PWD
# 利用 pip 安装依赖
# 设置安装依赖包的镜像以及安装相关的依赖包,需要安装的依赖包以及版本提前在requirements.txt文件里写出来
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
RUN pip install -r /app/requirements.txt
# RUN pip3 install pandas numpy moviepy pydub matplotlib python-multipart uvicorn

# 设置 python 环境变量
ENV PYTHON_ENV_TEST=/app

# Run the start script, it will check for an /app/prestart.sh script (e.g. for migrations)
# And then will start Gunicorn with Uvicorn
# 声明运行时的端口
EXPOSE 8080

# 运行Gunicorn服务器
# docker  build  -t  my_fastapi  .
CMD ["python","/app/main.py"]


  在app目录下运行

docker  build  -t my_fastapi:test -f ..\docker\Dockerfile . 

(最后有一个“.”号,这个很重要,代表当前目录,小白复制网上的代码时,很容易遗漏)

 或在项目目录下运行:

docker  build  -t my_fastapi:test -f docker\Dockerfile app

 

8、编写docker-compose.yaml

services:
  fastapi:
    image: my_fastapi:test
    ports:
      - 8181:8080
    environment:
      ENV_PARAMS: test_param
      MODEL_NAME: fastmodel

启动docker

docker-compose.exe -f docker\docker-compose.yaml up -d 

 

总结:

1、docker 运行时的端口镜像,前后顺序不要写错 是先宿主机再容器 即 -p 宿主机端口:容器内端口

2、docker build 时,最后一个参数为dockerfile中的“当前目录”,当出现文件无法复制或找不到文件时,一般都是当前路径设置有误.

3,启动docker-compose报错,很多时候是因为参数顺序搞错,把up -d放到 -f前面去了。up -d 一般在命令最后

4、fastAPI自带swagger功能,可以通过 http://127.0.0.1:8181/docs 和 http://127.0.0.1:8181/redoc进行访问和测试

 

 

 

 

 


网站公告

今日签到

点亮在社区的每一天
去签到