当前位置: 首页 > news >正文

Docker-compose部署Fastapi项目

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


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

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

Docker-compose基础文件搭建

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

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

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

  • **gunicorn:**在该文件夹下创建两个配置文件gunicorn.py、gunicorn.conf
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"        # 错误日志文件
[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镜像
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
  • **postgres文件夹:**这里只需要创建data文件夹
  • **redis文件夹:**创建一个conf文件夹里面创建redis.conf,再创建一个data文件夹
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 everysecno-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 64list-max-ziplist-size -2
list-compress-depth 0set-max-intset-entries 512zset-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 yesclient-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
  • **supervisor文件夹:**创建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# 更新依赖
RUN apt-get -y update && \apt-get -y install vim
#    apt-get -y install gcc && \
#    apt-get -y install cmake \# RUN apt-get install -y tzdata
# RUN apt-get install -y --fix-missing tzdata# 设置时区
# RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezone# 设置python环境变量
ENV PYTHONUNBUFFERED 1# 在容器内创建mes文件夹
RUN mkdir -p /peoject# 设置容器内工作目录
WORKDIR /peoject# 将当前目录文件加入到容器工作目录中
ADD . /peoject# 更新pip版本
RUN /usr/local/bin/python -m pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple/ && \# pip安装依赖pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ && \# 安装gunicornpip install gunicorn -i https://pypi.tuna.tsinghua.edu.cn/simple/ && \# 安装supervisorapt-get install -y supervisor && \# 复制supervisor配置文件cp /appagora/construction/supervisor/supervisord.conf /etc/supervisor/supervisord.conf && \# 复制supervisor的gunicorn配置文件cp /appagora/construction/gunicorn/gunicorn.conf /etc/supervisor/conf.d/gunicorn.conf# 设置环境变量
ENV SPIDER=/cyxMES# 移除\r in windows
#RUN sed -i 's/\r//' ./start.sh
#CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

yml文件

version: "3"
services:redis:image: rediscommand: redis-servervolumes:- ./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: alwaysfastapi: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- redisdepends_on:- db- redisrestart: alwaysnginx:build: construction/nginxports:- "9000:9000"expose:- "9000"volumes:- ./log/nginx:/log # 挂载日志文件,可以对应一下和上面的创建文件和nginx中的Dockerfile相对应links:- fastapidepends_on:- fastapirestart: always

所有的文件目录结构如下

project/

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

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

│ ├── postgres
│ │ ├──data

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

│ │── superviosr
│ │ └── gunicorn.conf

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

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

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

│ └── docker-compose.yml

│ └──Dockefile

相关文章:

Docker-compose部署Fastapi项目

Docker-compose部署Fastapi、postgres、Redis、Nginx) 之前有写过使用容器部署的方式,这次尝试使用Docker-compose试一次大胆的尝试 使用容器的方式部署只是掌握这项技能的基础,在使用Docker-compose的过程中会有些稍许的不同。毕竟踩过的坑才算是跨过去…...

Eigen求解线性方程组

1、线性方程组的应用 线性方程组可以用来解决各种涉及线性关系的问题。以下是一些通常可以用线性方程组来解决的问题: 在实际工程和科学计算中,求解多项式方程的根有着广泛的应用。 在控制系统的设计中,我们经常需要求解特征方程的根来分析…...

7、Java基本数据类型的使用细节探讨(超详细版本)

Java基本数据类型的使用细节探讨 一、整数类型二、浮点数三、字符型四、布尔型 我觉得基本数据类型大家学计算机的应该都懂,但是韩顺平老师讲的基本类型的使用细节我觉得有必要记录一下,重新学的时候才发现有了新的感悟! 一、整数类型 使用细…...

MFC实现点击列表头进行排序

MFC实现点击列表头排序 1、添加消息处理函数 在列表窗口右键,类向导。选择 IDC_LIST1(我的列表控件的ID),消息选择LVN_COLUMNCLICK。 2、消息映射如下 然后会在 cpp 文件中生成以下函数 void CFLashSearchDlg::OnLvnColumnclic…...

用龙梦迷你电脑福珑2.0做web服务器

用龙梦迷你电脑福珑2.0上做web服务器是可行的。已将一个网站源码放到该电脑,在局域网里可以访问网站网页。另外通过在同一局域网内的一台windows10电脑上安装花生壳软件,也可以在外网访问该内网服务器网站网页。该电脑的操作系统属于LAMP。在该电脑上安装…...

秋招后端开发面试题 - JVM类加载机制

目录 JVM类加载机制前言面试题能说一下类的生命周期吗?类加载的过程知道吗?类加载器有哪些?什么是双亲委派机制?为什么要用双亲委派机制?如何破坏双亲委派机制?如何判断一个类是无用的类? JVM类…...

OceanBase 分布式数据库【信创/国产化】- OceanBase 配置项和系统变量概述

本心、输入输出、结果 文章目录 OceanBase 分布式数据库【信创/国产化】- OceanBase 配置项和系统变量概述前言OceanBase 数据更新架构OceanBase 配置项和系统变量概述配置项配置项分类配置项查询系统变量系统变量分类系统变量查询配置项与系统变量的区分OceanBase 分布式数据库…...

单单单单单の刁队列

在数据结构的学习中,队列是一种常用的线性数据结构,它遵循先进先出(FIFO)的原则。而单调队列是队列的一种变体,它在特定条件下保证了队列中的元素具有某种单调性质,例如单调递增或单调递减。单调队列在处理…...

电脑windows系统压缩解压软件-Bandizip

一、软件功能 Bandizip是一款功能强大的压缩和解压缩软件,具有快速拖放、高速压缩、多核心支持以及广泛的文件格式支持等特点。 Bandizip软件的功能主要包括: 1. 支持多种文件格式 Bandizip可以处理多种压缩文件格式,包括ZIP, 7Z, RAR, A…...

图片公式识别@文档公式识别@表格识别@在线和离线OCR工具

文章目录 abstract普通文字识别本地软件识别公式扩展插件下载小结 在线识别网站/API👺Quicker整合(推荐)可视化编辑和识别公式其他多模态大模型识别图片中的公式排版 开源模型 abstract 本文介绍免费图片文本识别(OCR)工具,包括普通文字识别,公式识别,甚至是手写公…...

Java高阶私房菜:JVM分代收集算法介绍和各垃圾收集器原理分解

目录 什么是分代收集算法 GC的分类和专业术语 什么是垃圾收集器 垃圾收集器的分类及组合 ​编辑 应关注的核心指标 Serial和ParNew收集器原理 Serial收集器 ParNew收集器 Parallel和CMS收集器原理 Parallel 收集器 CMS收集器 新一代垃圾收集器G1和ZGC G1垃圾收集器…...

为什么IB损失要在100epochs后再用?

在给定的代码中,参数start_ib_epoch用于控制从第几轮开始使用IB(Instance-Balanced)损失函数进行训练。具体来说,如果start_ib_epoch的值大于等于100,那么在训练的前100轮中将使用普通的交叉熵损失函数(CE&…...

《Video Mamba Suite》论文笔记(4)Mamba在时空建模中的作用

原文翻译 4.4 Mamba for Spatial-Temporal Modeling Tasks and datasets.最后,我们评估了 Mamba 的时空建模能力。与之前的小节类似,我们在 Epic-Kitchens-100 数据集 [13] 上评估模型在zero-shot多实例检索中的性能。 Baseline and competitor.ViViT…...

【备战软考(嵌入式系统设计师)】10 - 软件工程基础

这一部分的内容是概念比较多,不要理解,去感受。 涉及的知识点是嵌入式系统开发和维护的部分,也就是和管理相关的,而不是具体如何进行嵌入式系统开发的细节。 系统开发生命周期 按照顺序有下面几个阶段,我们主要要记…...

随手笔记-GNN(朴素图神经网络)

自己看代码随手写的一点备忘录,自己看的,不喜勿喷 GNN (《------ 代码) 刚开始我还在怀疑为什么没有加weigth bias,已经为什么权重才两个,原来是对node_feats进行的network的传播,而且自己内部直接进行了。 下面是一…...

C 语言指针怎么理解?

在今天的学习中,我注意到有位学员似乎对 C 语言指针的理解有些困惑。为了帮助大家更好地理解,我来举个例子。 C 语言指针就好比 Windows 桌面上常见的快捷方式。快捷方式可以指向某个游戏,这就是普通指针;它也可以指向另一个快捷…...

HTTP协议:通信机制、特点及实践应用

目录 前言 1. 运行机制 2. 通信方式 3. 主要特点 4. 统一资源标识符(URL) 5. HTTP报文 6. HTTP请求 7. HTTP响应 8. 实体 9. 持续连接 结语 前言 HTTP(Hypertext Transfer Protocol)是互联网上应用最广泛的一种协议&a…...

Leetcode—289. 生命游戏【中等】

2024每日刷题&#xff08;126&#xff09; Leetcode—289. 生命游戏 算法思想 实现代码 class Solution { public:void gameOfLife(vector<vector<int>>& board) {int rows board.size();int cols board[0].size();int neighbors[3] {0, 1, -1};vector<…...

系统运维(虚拟化)

1.VLAN VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直接通信&#xff0c;而VLAN间则不能直接互通。这样&#xff0c;广播报…...

Linux域名解析

1.hosts:windows c盘下面 Linux: /etc/hosts 作用:实现名字解析&#xff0c;主要为本地主机名、集群节点提供快速解析。平面式结构&#xff0c;集中式数据库。 缺点:不便于查询更新 2.DNS:域名系统 作用:实现名字解析(分层性&#xff0c;层次性) FQDN:完全合格域名/全称域…...

树形结构和列表的区别

树形结构和列表在数据组织、表示方式以及应用场景等方面存在明显的区别。 首先&#xff0c;树形结构是一种非线性的数据结构&#xff0c;表现为层次的嵌套结构。每个节点可以有多个子节点&#xff0c;这些子节点又可以有自己的子节点&#xff0c;形成一个层次分明的结构。这种一…...

Go中json的解析和反解析

在解析过程中&#xff0c;反向解析不包含其中的部分参数也不会报错&#xff0c;这是需要注意的一点 31 func main() { // E: main redeclared in this block 32 type A…...

SpringBoot+vue实现退出功能

目录 1. 创建点击事件 2. 编写退出逻辑 在Spring Boot 和 Vue.js 应用中实现退出功能&#xff0c;通常涉及到前端的用户界面操作和注销逻辑。 以下是实现退出功能的步骤&#xff1a; 1. 创建点击事件 在header.vue中创建一个点击事件 <span style"text-decoratio…...

Linux操作系统中管理磁盘的另外一种操作方式。即LVM——逻辑卷管理操作

在Linux操作系统中管理磁盘的一种方法名称——LVM&#xff0c;这种管理磁盘的优势。 1.使用LVM去管理磁盘可以在不影响原来数据的前提下去扩容磁盘空间或者是缩减磁盘空间。 在LVM中除了上层逻辑券可以扩容&#xff0c;下层的券组也可以扩容。 2.使用LVM管理的磁盘支持快照功…...

Lua 零基础入门

Lua 1.Lua是什么&#xff1f; 1.1 Lua的历史 Lua是由Roberto Ierusalimschy、Luiz Henrique de Figueiredo和Waldemar Celes于1993年创建的&#xff0c;当时他们是巴西里约热内卢天主教大学计算机图形技术组&#xff08;Tecgraf&#xff09;的成员。在开发Lua之前&#xff0…...

记录DemoApplication.java不变蓝问题

问题 解决方案 一、点击右下角加载 二、右键项目 勾选maven...

22_Scala集合Seq

文章目录 Seq序列1.构建集合2.List集合元素拼接&&集合拼接3.可变Seq&&List3.1 ListBuffer创建3.2 增删改查3.3 相互转化 Appendix1.Scala起别名2.Seq底层3.关于运算符操作: :4.空集合的表示 Seq序列 –Seq表示有序&#xff0c;数据可重复的集合 1.构建集合 …...

机器学习初学者 6 个核心算法!建议收藏,反复观看!

今天再来介绍机器学习算法的基本概念和适用场景&#xff01; 首先&#xff0c;引用一句英国统计学家George E. P. Box的名言&#xff1a;All models are wrong, but some are useful. 没有哪一种算法能够适用所有情况&#xff0c;只有针对某一种问题更有用的算法。 也就是说&…...

SpringBoot 打包所有依赖

SpringBoot 项目打包的时候可以通过插件 spring-boot-maven-plugin 来 repackage 项目&#xff0c;使得打的包中包含所有依赖&#xff0c;可以直接运行。例如&#xff1a; <plugins><plugin><groupId>org.springframework.boot</groupId><artifact…...

QpushButton绘制圆角矩形并绘制背景颜色

要在QPushButton的paintEvent中绘制按钮的颜色&#xff0c;可以创建一个自定义的QPushButton类&#xff0c;并重写它的paintEvent函数。在paintEvent函数中&#xff0c;可以使用QPainter来绘制按钮的背景颜色。 以下是一个简单的示例代码&#xff0c;演示如何在自定义的QPushB…...

余姚网站建设的公司/培训学校加盟费用

大家好&#xff0c;我是老赵一. 介绍FACE-UI 基于前后端分离Web端项目&#xff0c;主要实现了网页版的人脸登录&#xff0c;通过调取前端摄像头拍照&#xff0c;传入后台进行跟数据库人脸库的相似度比对。技术点&#xff1a;Springboot&#xff0c;Mysql&#xff0c;JWT&#x…...

动物摄影网站/有免费做网站的吗

1. 更新不透明贴图的压缩格式为ETC 4bit&#xff0c;因为android市场的手机中的GPU有多种&#xff0c;每家的GPU支持不同的压缩格式&#xff0c;但他们都兼容ETC格式&#xff0c;  2. 对于透明贴图&#xff0c;我们只能选择RGBA 16bit 或者RGBA 32bit。  3. 减少FPS&#x…...

做数据ppt模板下载网站/深圳网站优化公司

1. MediaPlayer状态机 MediaPlayer状态机如下图所示&#xff1a;...

好知网做网站/100个成功营销策划案例

读取文件和目录名 这一节開始我们将陆续看到Windows App是如何操作文件的。 在Windows上读取文件名称、目录名 首先我们在XAML中定义一个Button和TextBlock&#xff0c;将读取文件/目录名的过程写在前者的click事件中。后者则用来显示文件信息。 <Grid Background"{The…...

和老妇做爰视频网站/英语培训

上英语课 阅读《艺术学概论》 转载于:https://www.cnblogs.com/bgd140206110/p/6568092.html...

简述建设政府门户网站的原因/网络营销企业有哪些公司

1.1.1 摘要 Ajax技术的核心是XMLHttpRequest对象&#xff08;简称XHR&#xff09;&#xff0c;可以通过使用XHR对象获取到服务器的数据&#xff0c;然后再通过DOM将数据插入到页面中呈现。虽然名字中包含XML&#xff0c;但Ajax通讯与数据格式无关&#xff0c;所以我们的数据格式…...