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

Docker容器内Scrapy的Cron任务无法连接PostgreSQL容器

问题说明

手动在app容器终端执行scrape.sh时,Scrapy可正常连接PostgreSQL;但通过Cron定时触发该脚本时,出现数据库连接失败错误,提示connection is bad: No such file or directory,程序默认尝试连接本地Unix socket而非db服务容器。

问题根源
  1. Cron环境变量缺失:Cron运行时不会自动继承容器的系统环境变量,导致脚本无法获取POSTGRES_HOST等关键参数,进而错误尝试连接本地服务。
  2. 脚本拼写错误:scrape.sh中export POSTGRES_PASSWORD=$POSTGRES_PASSW存在笔误,POSTGRES_PASSW应为POSTGRES_PASSWORD,会导致密码参数为空。
  3. Cron的PATH路径不全:默认Cron的PATH范围有限,可能无法正确定位依赖命令。
解决方案

方案1:修复脚本并导入容器环境变量

  • 修正scrape.sh的拼写错误,并添加环境变量导入逻辑:
    #!bin/bash
    # 从容器主进程导入完整环境变量(Docker容器主进程环境变量存储在/proc/1/environ)
    for env in $(cat /proc/1/environ | tr '\0' '\n'); do
        export "$env"
    done
    # 补充PATH确保命令可被找到
    export PATH=$PATH:/usr/local/bin
    cd "/scrape"
    scrapy crawl spider
    

方案2:在Cron配置中显式传递环境变量

修改Cron任务,直接指定所需环境变量,避免依赖脚本导入:

30 5 * * 0 POSTGRES_USER=${POSTGRES_USER} POSTGRES_PASSWORD=${POSTGRES_PASSWORD} POSTGRES_DB=${POSTGRES_DB} POSTGRES_HOST=${POSTGRES_HOST} POSTGRES_PORT=${POSTGRES_PORT} PATH=$PATH:/usr/local/bin sh /shell_scripts/scrape.sh

方案3:调整Dockerfile让Cron自动加载环境变量

修改app容器的Dockerfile,将容器环境变量写入Cron默认读取的配置文件:

FROM python:3.10-bookworm
RUN apt-get update -q 
RUN apt-get install -y cron
COPY . .
RUN pip3 install -r requirements.txt
# 将容器环境变量写入Cron默认读取的/etc/environment
RUN printenv | grep -E 'POSTGRES_|PATH' > /etc/environment
COPY shell_scripts/scrape_cron /etc/cron.d/scrape_cron
RUN chmod 0744 /etc/cron.d/scrape_cron
RUN crontab /etc/cron.d/scrape_cron 
RUN touch /var/log/cron.log
CMD cron && tail -f /var/log/cron.log

方案4:替换Cron为Python定时任务(更稳定)

放弃系统Cron,使用Python定时任务库直接集成到Scrapy项目:

  • 安装依赖:pip install apscheduler
  • 创建定时脚本run_spider.py:
    from apscheduler.schedulers.blocking import BlockingScheduler
    from scrapy.crawler import CrawlerProcess
    from scrapy.utils.project import get_project_settings
    
    def run_spider():
        process = CrawlerProcess(get_project_settings())
        process.crawl('spider')
        process.start()
    
    if __name__ == '__main__':
        scheduler = BlockingScheduler()
        # 每周日5:30执行爬取
        scheduler.add_job(run_spider, 'cron', day_of_week='sun', hour=5, minute=30)
        scheduler.start()
    
  • 修改app容器Dockerfile的启动命令:
    CMD ["python", "run_spider.py"]
    
验证方法

修改配置后,重新构建并启动容器:

docker-compose down
docker-compose build
docker-compose up -d

通过以下命令查看执行日志:

# 查看Cron日志
docker exec app tail -f /var/log/cron.log
# 查看Scrapy爬取日志(需根据项目日志配置调整路径)
docker exec app cat /scrape/scrapy.log

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:04:57