news 2026/11/5 2:00:53

5.用DockerCompose启动FastAPIPostgreSQL和Redis

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5.用DockerCompose启动FastAPIPostgreSQL和Redis

用 Docker Compose 启动 FastAPI、PostgreSQL 和 Redis

码海寻道 · AI 算法工程化与系统落地实战第 5 篇

一个算法服务真正接入业务后,通常至少需要保存三类信息:请求和任务状态、算法结果、短期缓存或限流数据。FastAPI 负责接口,PostgreSQL 负责业务事实,Redis 负责速度和短期状态。本文用 Docker Compose 把三者启动起来,形成一个可以本地联调的基础环境。

一、三个组件怎么分工?

FastAPI:接收请求、鉴权、参数校验、调用算法 PostgreSQL:任务、结果、模型版本、审计记录 Redis:缓存、限流、短期锁、进度加速读取

Redis 不是 PostgreSQL 的替代品。任务最终状态、推理结果和需要长期保存的数据应该进入 PostgreSQL;Redis 中的数据即使丢失,也应能够从数据库或任务系统恢复。

二、项目准备

algorithm-stack/ ├── app/ │ ├── main.py │ ├── config.py │ └── routes.py ├── requirements.txt ├── Dockerfile ├── compose.yaml └── .env.example

依赖:

fastapi uvicorn[standard] psycopg[binary] redis pydantic-settings

三、编写 Compose 文件

services:api:build:.ports:-"8000:8000"environment:APP_ENV:developmentDATABASE_URL:postgresql://algo:algo@postgres:5432/algorithmREDIS_URL:redis://redis:6379/0depends_on:postgres:condition:service_healthyredis:condition:service_healthypostgres:image:postgres:16environment:POSTGRES_DB:algorithmPOSTGRES_USER:algoPOSTGRES_PASSWORD:algovolumes:-postgres_data:/var/lib/postgresql/dataports:-"5432:5432"healthcheck:test:["CMD-SHELL","pg_isready -U algo -d algorithm"]interval:5stimeout:3sretries:10redis:image:redis:7-alpinevolumes:-redis_data:/dataports:-"6379:6379"healthcheck:test:["CMD","redis-cli","ping"]interval:5stimeout:3sretries:10volumes:postgres_data:redis_data:

容器内部访问 PostgreSQL 使用postgres:5432,访问 Redis 使用redis:6379。ports只是把端口暴露到宿主机,服务之间并不依赖宿主机端口。

四、建立数据库连接

# app/config.pyfrompydantic_settingsimportBaseSettingsclassSettings(BaseSettings):database_url:strredis_url:strsettings=Settings()
# app/main.pyfromcontextlibimportasynccontextmanagerfromfastapiimportFastAPIfromredis.asyncioimportRedisimportpsycopgfromapp.configimportsettings@asynccontextmanagerasyncdeflifespan(app:FastAPI):app.state.redis=Redis.from_url(settings.redis_url,decode_responses=True)app.state.db=awaitpsycopg.AsyncConnection.connect(settings.database_url)yieldawaitapp.state.redis.aclose()awaitapp.state.db.close()app=FastAPI(lifespan=lifespan)

真实项目中不要为每个请求创建一个数据库连接,而应使用连接池。应用启动时如果数据库不可用,要有明确的重试和未就绪策略。

五、实现一个结果接口

fromfastapiimportRequest@app.get("/api/v1/results/{request_id}")asyncdefget_result(request_id:str,request:Request):cache_key=f"algorithm:result:{request_id}"cached=awaitrequest.app.state.redis.get(cache_key)ifcached:return{"source":"redis","data":cached}asyncwithrequest.app.state.db.cursor()ascur:awaitcur.execute("SELECT request_id, status, result_json FROM inference_results ""WHERE request_id = %s",(request_id,),)row=awaitcur.fetchone()ifrowisNone:return{"status":"not_found"}data={"request_id":row[0],"status":row[1],"result":row[2]}awaitrequest.app.state.redis.set(cache_key,str(data),ex=60)return{"source":"postgres","data":data}

缓存 Key 至少要包含业务类型、资源 ID、版本和权限维度。不能因为命中 Redis 就跳过用户权限检查。缓存中的结果过期后,应安全回源数据库。

六、启动和验证

dockercompose up-d--builddockercomposepsdockercompose logs-fapi

检查数据库:

dockercomposeexecpostgres psql-Ualgo-dalgorithm

检查 Redis:

dockercomposeexecredis redis-cliping

验证顺序:

  1. PostgreSQL 和 Redis 状态变为 healthy;
  2. API 容器成功启动;
  3. API 能连接两个依赖;
  4. 写入一条算法结果;
  5. 第一次读取回源 PostgreSQL;
  6. 第二次读取命中 Redis;
  7. 删除或修改结果后,缓存能够失效。

七、开发环境和生产环境的区别

本示例把数据库端口暴露到宿主机,方便调试。生产环境通常只让 API 和 Worker 通过内部网络访问,数据库密码也不能写成 Compose 文件中的明文。

还需要补充:

  • 数据库迁移工具和启动迁移流程;
  • PostgreSQL 备份与恢复;
  • Redis 持久化或明确的缓存丢失策略;
  • 连接池大小和超时;
  • API、数据库和 Redis 的日志与指标;
  • 升级时的数据兼容和回滚方案。

结语

FastAPI、PostgreSQL 和 Redis 是算法服务中很常见的一组基础组件:API 负责交互,PostgreSQL 负责事实,Redis 负责加速。通过 Compose 把它们放在同一套网络和配置中,团队可以快速获得稳定的本地联调环境。

下一篇将加入 MinIO,把上传文件、推理结果和模型文件从容器文件系统中分离出来。

参考资料

  1. Docker Compose 官方文档
  2. PostgreSQL 官方文档
  3. Redis 官方文档

本文中的数据库密码和端口仅用于本地演示,生产环境必须使用密钥管理、网络隔离和备份策略。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/5 1:59:55

AgentScope Java v2 第9课,Harness 总架构:13 个中间件从哪来

摘要:一个什么都没配置的 HarnessAgent,默认挂了 13 个中间件、23 个工具,还把账本落到了家目录。本文从一个解剖端点出发,拆这份清单:哪些是固定的,哪些随配置变;12 项能力为什么不是 12 个中间…

作者头像 李华
网站建设 2026/11/5 1:58:27

10-02-互操作-Unsafe代码与手动内存管理

Unsafe 代码与手动内存管理篇章:10-核心技术-托管互操作篇 | 阅读时间:约 35 分钟一、引言C# 的 unsafe 代码允许使用指针直接操作内存,完全绕开 GC。这是 Unity 中实现零分配性能热路径的关键技术。代价是失去了 C# 的类型安全和 GC 的内存安…

作者头像 李华
网站建设 2026/11/5 1:58:21

链上MEV原理与实战:从0到1理解最大可提取价值与Flashbots

引言:区块空间的价值,不在于交易本身,而在于交易的位置 以太坊的公开内存池(mempool)中,每一笔待确认交易在被打包之前都是可见的。这个设计原本是为了让节点验证交易有效性、防止双花,但它附带了一个深远的经济后果:交易的执行顺序本身具有价值。一笔大额买单可以在D…

作者头像 李华
网站建设 2026/11/5 1:56:17

移动硬盘和网盘哪个更安全?2026年数据存储可靠性深度对比

文章目录一、「移动硬盘 vs 网盘」:一个被问烂了但很少被正确回答的问题二、从四个维度真实对比2.1 物理损坏:硬盘的致命弱点2.2 误操作恢复:云端的核心优势2.3 灾难场景:谁更扛得住2.4 多设备访问:云端的天然优势三、…

作者头像 李华