如何在Postgres Docker容器启动时自动激活cron守护进程?
问题描述
目标:扩展官方Postgres Docker镜像,启用cron任务自动运行数据库备份,要求容器启动时自动激活cron守护进程。
已尝试的方法均失败:
- 将脚本放入
./docker-entrypoint-initdb.d:存在权限问题,且该目录下脚本仅在数据库首次创建时运行,无法满足每次容器启动都执行的需求。 - 修改官方镜像的
CMD/ENTRYPOINT:尝试先启动cron再启动Postgres,遇到以下错误:- 直接设置
ENTRYPOINT ["cron && docker-entrypoint.sh"]等形式时,报错找不到可执行文件:Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/usr/bin/cron && docker-entrypoint.sh": stat /usr/bin/cron && docker-entrypoint.sh: no such file or directory: unknown - 复制自定义启动脚本到镜像,脚本内容如下:
执行时报错:#!/bin/bash cron /usr/local/bin/docker-entrypoint.sh
(注:错误源于路径拼写错误,docker_compose_templates-latticeflow-db-1 | /root/startup_script.sh: line 3: /usr/local/bin/docker_entrypoint.sh: No such file or directorydocker-entrypoint.sh被写成了docker_entrypoint.sh)
- 直接设置
正确实现步骤
1. 编写正确的启动脚本
修正路径拼写错误,同时确保Postgres入口点能接收原CMD参数,且cron以后台方式运行:
#!/bin/bash # 后台启动cron守护进程 cron -f & # 执行官方Postgres入口点脚本,并传递所有命令行参数 exec /usr/local/bin/docker-entrypoint.sh "$@"
2. 编写Dockerfile
扩展官方Postgres镜像,安装cron、复制启动脚本及cron任务配置:
# 替换为你需要的Postgres版本 FROM postgres:15 # 安装cron(Debian/Ubuntu系镜像需执行,Alpine系替换为apk add cron) RUN apt-get update && apt-get install -y --no-install-recommends cron && rm -rf /var/lib/apt/lists/* # 创建备份脚本存放目录(按需调整) RUN mkdir -p /opt/postgres-backups # 复制启动脚本到容器内 COPY startup.sh /usr/local/bin/startup.sh # 设置脚本可执行权限 RUN chmod +x /usr/local/bin/startup.sh # 复制cron任务配置到指定目录 COPY backup-cron /etc/cron.d/backup-cron # 设置cron配置文件权限(必须为0644,否则cron不会加载) RUN chmod 0644 /etc/cron.d/backup-cron # 应用cron任务 RUN crontab /etc/cron.d/backup-cron # 替换ENTRYPOINT为自定义启动脚本 ENTRYPOINT ["/usr/local/bin/startup.sh"] # 保留官方镜像的默认CMD CMD ["postgres"]
3. 编写cron任务配置(backup-cron)
示例配置:每天凌晨2点执行备份脚本,输出日志到指定文件
0 2 * * * root /opt/postgres-backups/backup.sh >> /var/log/postgres-backup.log 2>&1
4. 编写备份脚本(backup.sh)
示例备份脚本,使用pg_dump完成备份并自动清理旧文件:
#!/bin/bash BACKUP_DIR="/opt/postgres-backups" DATE=$(date +%Y%m%d_%H%M%S) DB_NAME=$POSTGRES_DB BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql" # 执行备份 pg_dump -U $POSTGRES_USER $DB_NAME > $BACKUP_FILE # 压缩备份文件(可选) gzip $BACKUP_FILE # 删除7天前的备份文件(可选) find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +7 -delete
关键注意事项
- 路径正确性:确保所有脚本路径拼写无误,避免出现类似之前的路径错误。
- 权限配置:cron配置文件权限必须设置为
0644,备份脚本和启动脚本需添加可执行权限(chmod +x)。 - 信号处理:使用
exec执行Postgres入口点,确保容器能正确响应SIGTERM等信号,实现优雅停止。 - cron启动方式:用
cron -f &让cron在后台运行,避免阻塞Postgres启动流程。
内容的提问来源于stack exchange,提问作者Ivaylo Toskov
相关产品推荐
相关产品推荐

