Docker-compose部署Fastapi项目

Docker-compose部署Fastapi、postgres、Redis、Nginx


之前有写过使用容器部署的方式,这次尝试使用Docker-compose试一次大胆的尝试

使用容器的方式部署只是掌握这项技能的基础,在使用Docker-compose的过程中会有些稍许的不同。毕竟踩过的坑才算是跨过去的坎。具体会使用到Supervisor、Gunicorn、Postgres等


所有的文件目录结构如下

project/

├── construction/
│ ├── gunicorn
│ │ └── gunicorn.conf
│ │ └── gunicorn.py

│ ├── nginx
│ │ ├──conf
│ │ │ └──nginx.conf
│ │ └── Dockerfile

│ ├── postgres
│ │ ├──data

│ │── redis
│ │ ├──data
│ │ ├──conf
│ │ │ └──redis.conf

│ │── superviosr
│ │ └── supervisord.conf

│ │── log
│ │ │── gunicorn
│ │ │ └──success.log
│ │ │ └──error.log

│ │ │── nginx
│ │ │ └──success.log
│ │ │ └──error.log

│ │ │── supervisor
│ │ │ └──supervisor.log

│ └── docker-compose.yml

│ └──Dockefile

在这里插入图片描述

这里有我配置好的可以做一个参考

在这里插入图片描述


Docker-compose基础文件搭建

  • yml文件: 放在项目的根目录下,名字就叫docker-compose.yml
  • Dockerfile文件:放在项目的根目录下,文件名字叫Dockerfile,这个文件是项目的Dockerfile文件
  • **log文件夹:**放在项目的根目录下,这里会放入日志文件
  • **construction文件夹:**在项目中创建这样一个文件夹,里面会放入一些配置文件

这里重点说下construction文件夹,里面放入的东西比较多,我们先从这个文件夹中的配置文件开始说起。在该文件夹中创建五个文件夹:gunicorn、nginx、postgres、redis、superviosr


Construction文件夹的各种文件创建及说明

gunicorn:在该文件夹下创建两个配置文件gunicorn.py、gunicorn.conf

  • gunicorn.py文件
debug = False
daemon = False
bind = '0.0.0.0:8003'  # 绑定ip和端口号
backlog = 512       # 监听队列
timeout = 180      # 超时
# worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
worker_class = 'uvicorn.workers.UvicornWorker'

workers = 2    # 进程数
threads = 4 #指定每个进程开启的线程数
loglevel = 'debug'  # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'    # 设置gunicorn访问日志格式,错误日志无法设置
chdir = '/project'

accesslog = "/project/log/gunicorn/success.log"      # 访问日志文件
errorlog = "/project/log/gunicorn/error.log"        # 错误日志文件
  • gunicorn.conf配置文件
[program:gunicorn]  # 这里的gunicorn就是告诉supervisor我们的应用名称叫做什么
process_name=%(program_name)s
command=gunicorn -c /project/construction/gunicorn/gunicorn.py main:app
# 如果上面的命令不起作用,可以使用下面的
# gunicorn main:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
directory=/project
user=root
autostart=true
autorestart=true

nginx文件夹:在该文件夹下创建Doclerfile文件和conf文件夹,在conf文件夹中创建nginx.conf文件

  • Nginx的Dockerfile文件
# nginx镜像
FROM nginx
# 镜像作者
LABEL maintainer="Alfred"
# 换软件源
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

# 更新依赖
RUN apt-get update -y && \
    # 安装vim编辑器,方便调试,熟练后可不装
    apt-get install -y vim && \
    # 删除原有的配置文件
    rm /etc/nginx/nginx.conf && \
    # 创建log文件夹和两个日志文件,这里是为Docker-compose.yml中的数据卷对应
    mkdir /log && \
    touch /log/success.log && \
    touch /log/error.log

# 添加配置文件
ADD ./conf/nginx.conf /etc/nginx/nginx.conf
  • Nginx.conf配置文件
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
}

# 后端项目
http {
    # 客户端上传文件的限制
    client_max_body_size 1024m;

    # 开启GZIP压缩功能
	gzip on;
	gzip_min_length 1024;
	gzip_buffers 4 16k;
	gzip_comp_level 2;
	gzip_types *;
	gzip_vary on;

	# 日志文件,这里的log在dockerfile文件中有创建,并且在yml文件中有挂载出来
	access_log /log/success.log;
	error_log /log/error.log;

    server {
		# nginx监听的容器外部端口
		listen 9000;
		# 域名按照下面的写法, 没有域名写127.0.0.1
		server_name  127.0.0.1;

		location / {
			# 反向代理端口,这里的端口要与Gunicorn中配置的端口对应!!!而且不能写IP,要写yml文件中项目的名字!!!
			proxy_pass http://fastapi:8003;
			proxy_set_header Host $host;
			proxy_redirect off;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

	# 前端项目,这里不用管,我自己是带着前端项目一起部署的.有想学的可以评论下我有时间会联系.
    server {
    	# 监听 80和443端口
        listen 8080;
        # 域名 没有域名就写127.0.0.1
        server_name 127.0.0.1;

        # 设置静态文件的根目录,这里需要替换成你实际的 Vue.js 应用的路径
        root /dist;

        # 设置默认的索引文件
        index index.html;

        # 设置路由重写规则,用于处理 Vue.js 单页面应用的路由
        location / {
            try_files $uri $uri/ /index.html;
        }

        # 设置静态文件的缓存策略
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
            expires 1y;
            add_header Cache-Control "public";
        }

    }

}


postgres文件夹:这里只需要创建data文件夹


redis文件夹:创建一个Dockerfile文件,之后创建一个conf文件夹里面创建redis.conf,再创建一个data文件夹

  • Redis.conf配置文件
bind 0.0.0.0
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 32
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
# 这个是连接密码
requirepass 123456789
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

list-max-ziplist-size -2
list-compress-depth 0

set-max-intset-entries 512

zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

  • Redis的Dockerfile文件
# Redis镜像
FROM redis
MAINTAINER Alfred

RUN apt-get -y update && \
    apt-get -y install vim

ADD ./config/redis.conf /usr/local/etc/redis/redis.conf

supervisor文件夹:创建supervisord.conf的文件夹

  • Supervisord.conf配置文件
[unix_http_server]
file=/var/run/supervisor.sock   ; the path to the socket file

[supervisord]
logfile=/project/log/supervisor/supervisor.log  ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/var/run/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false               ; start in foreground if true; default false
silent=false                 ; no logs to stdout if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200
user=root

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

[include]
files=conf.d/*.conf

# 配置可视化管理界面,注意一定要先设置端口映射,因为我们在容器中所以port的ip必须为0.0.0.0
[inet_http_server]
port = 0.0.0.0:9010
username = admin
password = 123456789

日志文件夹的创建

在日志文件夹下创建gunicorn和nginx文件夹,并且在两个文件夹下都分别创建success.log、error.log。再创建一个supervisor文件夹,之后在此文件夹中创建superviosr.log文件


根目录下的Dockerfile文件

# 建立 python3.9 环境
FROM python:3.9

# 镜像作者
LABEL maintainer="Alfred"

RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

# 更新依赖并安装vim、supervisor、设置时区
RUN apt-get update && \
    apt-get install -y \
    vim \
    gcc \
    cmake \
    tzdata \
    supervisor && \
    ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo Asia/Shanghai > /etc/timezone && \
    rm -rf /var/lib/apt/lists/*


# 设置python环境变量
ENV PYTHONUNBUFFERED 1

# 设置容器内工作目录
WORKDIR /project

# 将当前目录文件加入到容器工作目录中
ADD . /project

# 换源更新PIP
RUN /usr/local/bin/python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 换源安装requirements的依赖包
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 换源安装gunicorn,也可以将gunicorn放入requirements,并注释掉这里
RUN pip install gunicorn -i https://pypi.tuna.tsinghua.edu.cn/simple/
# 复制supervisor的配置文件
RUN cp /project/construction/supervisor/supervisord.conf /etc/supervisor/supervisord.conf
# 复制supervisor的gunicorn配置文件
RUN cp /project/construction/gunicorn/gunicorn.conf /etc/supervisor/conf.d/gunicorn.conf

# 如果下面的命令在编排的时候报错就注释掉,用ENTRYPOINT,我在不同服务器测试的时候指不定哪个可以用
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
# ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

根目录下的docker-compose.yml文件

version: "3"
services:
  redis:
    build: docker-utils/redis
    command: redis-server /usr/local/etc/redis/redis.conf   # 指定配置文件路径
    volumes:
      - ./construction/redis/data:/data	# 这里的数据卷与上面创建的文件夹的对应
    ports:
      - "6381:6379"	# 端口映射
    restart: always # always表容器运行发生错误时一直重启

  db:
    image: postgres:16 # 用16的原因是老版本会有报错
    environment:
      - POSTGRES_DB=check# 数据库名称
      - POSTGRES_USER=baby# 数据库账户
      - POSTGRES_PASSWORD=baby # 数据库密码
    volumes:
      - ./construction/postgres/data:/var/lib/postgres/data # 挂载数据库数据
    ports:
      - "5435:5432"
    restart: always

  fastapi:
    build: .
    expose:
      - "8003"
    ports:
      - "9010:9010"	# 这里是端口映射到宿主机对Supervisor进行可视化管理    
    volumes:
      - .:/project
	# 这里的坑我放到下面讲
    command: >
        sh -c "[ -e /var/run/supervisor.sock ] && unlink /var/run/supervisor.sock; exec supervisord -n"
    links:
      - db
      - redis
    depends_on:
      - db
      - redis
    restart: always

  nginx:
    build: construction/nginx
    ports:
      - "9000:9000"
    expose:
      - "9000"
    volumes:
      - ./log/nginx:/log # 挂载日志文件,可以对应一下和上面的创建文件和nginx中的Dockerfile相对应
    links:
      - fastapi
    depends_on:
      - fastapi
    restart: always

关于docker-compose.yml文件中的command

command: >
        sh -c "[ -e /var/run/supervisor.sock ] && unlink /var/run/supervisor.sock; exec supervisord -n"

如果没有这个command,编排成功后会出现fastapi-1 | Unlinking stale socket /var/run/supervisor.sock的错误,这个错误是解除套接字链接的报错.我没有尝试提升权限,经过ChatGPT的询问得到上面的解决办法.命令的解释如下: [ -e /var/run/supervisor.sock ] 来检查文件是否存在。如果存在,&& 之后的 unlink /var/run/supervisor.sock 将执行,否则不执行。

ChatGPT给出的原因:
在这里插入图片描述
在这里插入图片描述
ChatGPT给出的解决方案一:

在这里插入图片描述
ChatGPT给出的解决方案二:
在这里插入图片描述


进行编排

在这里插入图片描述

# 注意有的是docker-compose up
docker compose up

编排成功后会出现很多日志,如果没有错误就说明成功.如果有错误就要对应日志来分析错误并解决.


  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速部署分布式应用。通过 Docker Compose,我们可以定义和运行多个 Docker 容器,并通过一个 YAML 文件来配置需要的服务。 下面是使用 Docker Compose 部署 Spring Boot 项目的简单步骤: 1. 编写 Dockerfile 在 Spring Boot 项目的根目录下创建一个名为 Dockerfile 的文件,并添加以下内容: ``` FROM openjdk:8-jdk-alpine VOLUME /tmp ARG JAR_FILE ADD ${JAR_FILE} app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] ``` 2. 编写 docker-compose.yml 文件 在 Spring Boot 项目的根目录下创建一个名为 docker-compose.yml 的文件,并添加以下内容: ``` version: '3' services: app: image: your-image-name build: context: . dockerfile: Dockerfile ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=prod restart: always ``` 其中,your-image-name 是自定义的镜像名称,需要在构建镜像时使用。 3. 构建镜像 在 Spring Boot 项目的根目录下执行以下命令,构建镜像: ``` docker build -t your-image-name . ``` 4. 启动容器 在 Spring Boot 项目的根目录下执行以下命令,启动容器: ``` docker-compose up -d ``` 5. 查看容器状态 执行以下命令查看容器状态: ``` docker-compose ps ``` 至此,你已经成功使用 Docker Compose 部署了 Spring Boot 项目。如果需要停止容器,可以执行以下命令: ``` docker-compose stop ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值