docker-compose部署fastapi+nginx+mysql

薛博赡
2023-12-01

docker-compose部署fastapi+nginx+mysql

概述

整个部署逻辑和django的部署比较相似,不过还是有一些不同的地方。
首先,使用的python镜像不是官方的,而是fastapi作者准备的一个镜像,这个镜像可以自动读取服务器的cpu数量确认启动的workers数,这个镜像仅适合但服务器的docker部署,不适合k8s使用。
整个项目结构如下:

.
├── docker-compose.yaml
├── Dockerfile
├── nginx
│   └── conf.d
│       └── default.conf
├── poetry.lock
├── pyproject.toml
└── src
    ├── amis_field.py
    ├── conftest.py
    ├── fast_store_backend
    │   ├── admin.py
    │   ├── depends.py
    │   ├── __init__.py
    │   ├── models.py
    │   ├── responses.py
    │   ├── router.py
    │   └── settings.py
    └── main.py

准备镜像

默认的镜像使用方式请参考:https://hub.docker.com/r/tiangolo/uvicorn-gunicorn-fastapi
这里我提供一个根据该镜像写的自己的服务(默认镜像是不能直接使用的,只是提供一个模板):

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8-slim-2022-12-12 # 其他的python版本或者tag去我给的地址查看
MAINTAINER Chise1
ENV POETRY_VIRTUALENVS_CREATE=false # poetry安装包时不创建虚拟机
RUN pip3 install poetry -i https://pypi.tuna.tsinghua.edu.cn/simple # 我是用了poetry管理环境,所以要单独安装这个
RUN mkdir -p /app # 这是固定的
WORKDIR /app
COPY pyproject.toml poetry.lock /app/
RUN poetry install # 类似于pip install -r requirements.txt
COPY ./src /app # 启动的根文件必须是/app/main.py,里面必须有app类

准备docker-compose

需要在docker-ompose.yaml准备一个.env文件,存储需要的环境变量,供docker-compose读取

version: '3'
services:
  web:
    build: .
    volumes:
      - ./static/:/app/static
      - ./media/:/app/media
    container_name: web
    depends_on:
      - mysql
    environment:
      DB_URL: mysql://root:${MYSQL_ROOT_PASSWORD}@mysql:3306/fast_store_backend # 类似:mysql://root:123@mysql:3306/fast_store_backend
      DOMAIN_NAME: ${DOMAIN_NAME} # 服务器地址,
  mysql:
    image: mysql:8.0
    volumes:
      - ./mysql/db:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf
    restart: always
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} #访问密码
  nginx:
    image: nginx:1.21.6-alpine
    restart: always
    container_name: nginx
    depends_on:
      - web
    environment:
      TZ: Asia/Shanghai
    ports:
      - "443:443"
    volumes:
      - ./nginx/conf.d/:/etc/nginx/conf.d/ # nginx的代理配置
      - ./nginx/logs:/var/log/nginx
      - ./nginx/ssl:/etc/nginx/ssl # ssl需要的crt和key 这个主要在各种云服务里面申请

nginx的其他配置

默认的反向代理文件(conf.d/default.conf),主要配置反向代理服务的:

server {
  #SSL 默认访问端口号为 443
  listen 443 ssl;
  #请填写绑定证书的域名
  server_name www.example.vip;
  #请填写证书文件的相对路径或绝对路径
  ssl_certificate /etc/nginx/ssl/www.example.vip.crt;
  #请填写私钥文件的相对路径或绝对路径
  ssl_certificate_key /etc/nginx/ssl/www.example.vip.key;
  ssl_session_timeout 5m;
  #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
   ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  #请按照以下协议配置
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  location /meida/ {
    root /app/;
  }
  location /static/ {
    root /app/;
  }
  location / {
    proxy_pass http://web:80;
    proxy_redirect http://web/ /; # 使URL_FOR函数能够正常执行 
    proxy_set_header Host $proxy_host;    #捕获客户端真实IP
    proxy_set_header X-Real-IP $remote_addr;     #$remote_addr 代表客户端IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

server {
  listen 80;
  #请填写绑定证书的域名
  server_name www.example.vip;
  #把http的域名请求转成https
  return 301 https://$host$request_uri;
}

如果出现反向代理静态文件403找不到的话,需要配置/etc/nginx/nginx.conf的用户信息(在这个文件的头部:)

user  root;
...
 类似资料: