Files
FastapiAdmin/devops/README.md
T
2025-01-22 11:08:40 +08:00

7.5 KiB
Executable File
Raw Blame History

部署文档

工具介绍

1. Docker

# 使用官方的 Python 3.10 镜像作为基础镜像
FROM python:3.10
# 使用 LABEL 替代 MAINTAINER
LABEL maintainer="管理员"
# 设置 python 环境变量
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
# 设置时区
ENV TZ Asia/Shanghai

# 升级pip版本
# RUN python -m pip install --upgrade pip

# 创建容器工作目录
RUN mkdir -p /opt/fastapi_project
# 设置容器内工作目录
WORKDIR /opt/fastapi_project
# 将当前主机目录全部文件复制至容器工作目录
COPY ./requirements.txt /code/requirements.txt
# 安装依赖
RUN pip install --no-cache-dir --upgrade -r /opt/fastapiproject/backend/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 部署 nginx
RUN apt-get update && apt-get install -y nginx
RUN rm /etc/nginx/sites-enabled/default
COPY nginx.conf /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-available/nginx.conf /etc/nginx/sites-enabled/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf

# # 部署mysql
# RUN apt-get install -y mysql-server

# # 部署redis
# RUN apt-get install -y redis-server

# # 部署mongo
# RUN apt-get install -y mongodb


#CMD 运行以下命令,daemon off后台运行,否则启动完就自动关闭
CMD ["nginx", "-g", "daemon off;"]  

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
# 暴露端口
EXPOSE 8000
# python main.py run 或者 uvicorn main:create_app --host 0.0.0.0 --port 8000 --workers 4
ENTRYPOINT ["uvicorn", "backend.main:create_app", "--host", "0.0.0.0", "--port", "8000", "--workers", 4]
# ENTRYPOINT ["gunicorn", "-c", "gunicorn.py", "main:create_app"]

2. Docker-Compose

version: "3.10.11"

# 应用服务
services:
  # 应用服务
  fastapi_getway:
    # 容器名称
    container_name: fastapi
    # 镜像名称
    image: fastapi
    env_file: .env
    networks:
      - db_network
      - web_network
    # 构建镜像
    build:
      context: ./
      dockerfile: Dockerfile
    #build: .
    # 将容器运行在特权模式下,意味着容器内的进程将具
    # 有访问宿主机的权限,包括文件系统、设备和系统功能等
    privileged: true
    # 指定容器中运行的用户
    user: root
    # 启动策略为始终重启
    restart: always
    # 设置网络模式为host模式
    network_mode: host
    # 端口映射
    ports:
      - 8020:8020
    # 文件挂载
    volumes:
      - ./:/data/apps
      - ./uploads:/data/apps/uploads
    # 执行命令
    command: python app.py runserver 0.0.0.0:8020 --noreload
    # 日志配置
    logging:
      driver: "json-file"
      options:
        max-size: "500m"
        max-file: "10"
  # nginx服务
  nginx:
    container_name: nginx
    restart: always
    image: "nginx:latest"
    ports:
      - "5000:5000"
    volumes:
      - ./nginx:/etc/nginx/conf.d
    networks:
      - web_network
    depends_on:
      - flask_api

  # 中间件服务
  mysql:
    container_name: mysql
    image: mysql:latest
    restart: always
    ports:
      - "3306:3306"
        # 数据卷挂载
        
networks:
  db_network:
    driver: bridge
  web_network:
    driver: bridge

3. Nginx

########### 每个指令必须有分号结束。#################
user administrator administrators; # 配置用户或组,默认为nobody nobody
worker_processes 2; # 允许生成的进程数,默认为1
pid /nginx/pid/nginx.pid; # 指定 Nginx 进程运行文件存放地址
error_log log/error.log debug; # 制定日志路径,级别。这个设置可以放入全局块、http块、server块,级别依次为:debug|info|notice|warn|error|crit|alert|emerg

events {
    accept_mutex on; # 设置网络连接序列化,防止惊群现象发生,默认为on
    multi_accept on; # 设置一个进程是否同时接受多个网络连接,默认为off
    use epoll; # 事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections 1024; # 最大连接数,默认为512
}

http {
    include mime.types; # 文件扩展名与文件类型映射表
    default_type application/octet-stream; # 默认文件类型,默认为text/plain

    # 取消服务日志
    access_log off;

    # 自定义日志格式
    log_format access '$remote_addr$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for';

    # 启用访问日志
    access_log log/access.log access; # combined为日志格式的默认值

    sendfile on; # 允许sendfile方式传输文件,默认为off,可以在http块、server块、location块
    sendfile_max_chunk 100k; # 每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限
    keepalive_timeout 65; # 连接超时时间,默认为75秒,可以在http、server、location块

    # 定义上游服务器
    upstream mysvr {
        server 127.0.0.1:7878;
        server 192.168.10.121:3333 backup; # 热备
    }

    # 错误页
    error_page 404 https://www.baidu.com;

    # 定义一个 server 块
    server {
        # 单连接请求上限次数
        keepalive_requests 120;

        # 监听端口
        listen 4545;

        # 监听地址
        server_name 127.0.0.1;

        # 前端代理
        location / {
				proxy_set_header Host $host;
				root /web/front/;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
				try_files $uri $uri/ /index.html;
				index /index.html;
        }

        # 后端代理
        location  /api/ {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                add_header Access-Control-Allow-Methods *;
                add_header Access-Control-Allow-Origin $http_origin;
                proxy_pass http://127.0.0.1:8010/;
        }
    }
}

4. Shell

#!/bin/bash

# 检查是否已经处于虚拟环境中
if [[ ":$VIRTUAL_ENV:" != *":/opt/model-ai/backend/venv:"* ]]; then
    # 切换到目标目录
    cd /opt/ || { echo "切换 /opt 目录失败"; exit 1; }
    
    # 替换现有仓库
    if [ -d "/opt/model-ai" ]; then
        rm -rf /opt/model-ai
    fi
    
    # 克隆仓库
    git clone git@gitee.com:tao__tao/model-ai.git || { echo "克隆仓库失败"; exit 1; }
    
    # 进入后端目录
    cd /opt/model-ai/backend || { echo "进入后端目录失败"; exit 1; }
    
    # 创建虚拟环境
    python3 -m venv venv || { echo "创建虚拟环境失败"; exit 1; }
    
    # 激活虚拟环境
    source ./venv/bin/activate || { echo "激活虚拟环境失败"; exit 1; }
fi

# 安装依赖
pip install -r requirements.txt || { echo "安装依赖失败"; exit 1; }

# 初始化应用
echo "开始初始化应用"
python main.py init || { echo "初始化应用失败"; exit 1; }
echo "应用初始化完成"

# 使用 nohup 在后台运行应用,并将输出重定向到日志文件
echo "开始启动应用"
nohup python main.py run > /opt/logs/main.log 2>&1 &

# 获取 nohup 的进程 ID
NOHUP_PID=$!

# 检查后台进程是否成功启动
if [ $? -eq 0 ]; then
    # 将后台进程从当前 shell 会话中分离出来
    echo "应用已启动,进程 ID: $NOHUP_PID"

    # 等待一段时间,确保日志文件中有内容
    sleep 3
    
    # 打印日志文件的内容
    cat /opt/logs/main.log

    echo "应用已启动"
else
    echo "启动应用失败"
    exit 1
fi