You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI项目中用Celery定时备份Docker中的PostgreSQL?

解决Celery任务中实现PostgreSQL备份的方案

方案1:在Celery容器中安装PostgreSQL客户端,直接执行pg_dump

这是最安全且常规的实现方式,由于Celery与PostgreSQL处于同一Docker网络,可直接通过服务名访问数据库。

步骤1:修改Dockerfile,添加PostgreSQL客户端

在项目的Dockerfile中加入安装命令(以Python基础镜像为例):

# 基础镜像声明后添加
RUN apt-get update && apt-get install -y postgresql-client && rm -rf /var/lib/apt/lists/*

步骤2:在tasks.py中编写备份逻辑

使用Python的subprocess模块执行pg_dump命令,注意用Docker服务名替代localhost作为数据库地址:

from celery import Celery
import subprocess
import os
from datetime import datetime
from celery.schedules import crontab

# 初始化Celery,根据你的实际配置调整
celery = Celery('tasks', broker='redis://redis:6379/0')

@celery.task
def dump_dbase():
    # 生成带时间戳的备份文件名,防止覆盖
    backup_filename = f"db_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.dump"
    # 指定备份存储路径,建议使用Docker共享卷挂载的目录
    backup_path = os.path.join('/backups', backup_filename)
    
    # 构造pg_dump命令,替换为你的数据库服务名、用户名、库名
    cmd = [
        'pg_dump',
        '-U', 'postgres',
        '-d', 'dbase',
        '-h', 'postgr',  # 对应你的PostgreSQL容器服务名
        '-f', backup_path
    ]
    
    try:
        # 设置环境变量避免密码输入提示,建议从环境变量读取密码而非硬编码
        env = os.environ.copy()
        env['PGPASSWORD'] = os.getenv('POSTGRES_PASSWORD', '默认密码')
        
        # 执行备份命令
        subprocess.run(cmd, check=True, env=env)
        return f"备份成功:{backup_path}"
    except subprocess.CalledProcessError as e:
        return f"备份失败:{str(e)}"

# 配置周期性任务(示例:每天凌晨2点执行备份)
celery.conf.beat_schedule = {
    'daily-db-backup': {
        'task': 'tasks.dump_dbase',
        'schedule': crontab(hour=2, minute=0),
    },
}

步骤3:配置Docker共享卷持久化备份

在docker-compose.yaml中给Celery服务添加卷挂载,确保备份文件不会随容器销毁丢失:

services:
  celery:
    # 其他配置...
    volumes:
      - ./backups:/backups  # 本地目录映射到容器内的备份路径
    environment:
      - POSTGRES_PASSWORD=你的数据库密码  # 与PostgreSQL服务的密码保持一致
  postgr:
    # 其他配置...
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./backups:/backups  # 可选,让PostgreSQL容器也能访问备份目录

volumes:
  postgres_data:

方案2:通过docker exec在PostgreSQL容器中执行pg_dump(不推荐)

此方式需要Celery容器访问Docker Socket,存在安全风险,仅适合特殊场景:

步骤1:修改docker-compose.yaml挂载Docker Socket

celery:
  # 其他配置...
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./backups:/backups
  environment:
    - POSTGRES_PASSWORD=你的数据库密码

步骤2:在tasks.py中编写备份逻辑

@celery.task
def dump_dbase():
    backup_filename = f"db_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.dump"
    backup_path = f"/backups/{backup_filename}"
    
    # 构造docker exec命令,直接在PostgreSQL容器内执行pg_dump
    cmd = f"docker exec postgr pg_dump -U postgres dbase > {backup_path}"
    
    try:
        env = os.environ.copy()
        env['PGPASSWORD'] = os.getenv('POSTGRES_PASSWORD', '默认密码')
        subprocess.run(cmd, check=True, shell=True, env=env)
        return f"备份成功:{backup_path}"
    except subprocess.CalledProcessError as e:
        return f"备份失败:{str(e)}"

关键注意事项

  • 密码安全:绝对不要硬编码数据库密码,通过Docker环境变量传递更安全。
  • 备份清理:可额外编写Celery任务,定期删除指定天数前的旧备份,避免磁盘空间耗尽。
  • 任务监控:可结合Flower监控Celery任务的执行状态,及时发现备份失败情况。

内容的提问来源于stack exchange,提问作者Evgeny Romensky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:33:16