Docker容器中Telethon+Cron调度时API ID/Hash为空的ValueError问题
问题排查:Cron调度Docker容器内Telethon脚本时API ID/Hash为空错误
问题概述
在Docker容器中运行基于Telethon的Python脚本,通过Cron调度执行时触发ValueError: Your API ID or Hash cannot be empty or None错误。但将API ID和Hash硬编码到脚本中,或直接通过docker-compose的command执行脚本时运行正常,问题定位为Cron环境导致。
相关配置信息
docker-compose文件片段
... name_xyz: env_file: .env environment: PYTHONUNBUFFERED: 1 TELEGRAM_POSTING_API_HASH: ${TELEGRAM_POSTING_API_HASH} TELEGRAM_POSTING_API_ID: ${TELEGRAM_POSTING_API_ID} build: context: ./xyz/ dockerfile: Dockerfile volumes: - ./xyz:/app working_dir: /app/xyz/ restart: always command: ./entrypoint.sh ...
Python脚本核心代码
import os import asyncio import requests from telethon import TelegramClient TELEGRAM_POSTING_API_HASH = os.getenv('TELEGRAM_POSTING_API_HASH') TELEGRAM_POSTING_API_ID = os.getenv('TELEGRAM_POSTING_API_ID') client = TelegramClient('session_name', TELEGRAM_POSTING_API_ID, TELEGRAM_POSTING_API_HASH) ...
.env文件内容
TELEGRAM_POSTING_API_ID=11111111111 TELEGRAM_POSTING_API_HASH=11111111111
entrypoint.sh内容
#!/bin/bash # Start the run once job. echo "Docker container has been started" # shellcheck disable=SC2046 # Setup a cron schedule echo "SHELL=/bin/bash */2 * * * * cd /app/xyz/telegram/ && python3 my_python_script.py >> /var/log/cron.log 2>&1 # This extra line makes it a valid cron" > scheduler.txt crontab scheduler.txt cron -f
原因分析
Cron默认不会继承宿主进程(此处为entrypoint.sh所在的shell)的环境变量,当Cron执行Python脚本时,脚本无法通过os.getenv()获取到容器中设置的TELEGRAM_POSTING_API_ID和TELEGRAM_POSTING_API_HASH,导致这两个值为空,触发Telethon的参数校验错误。
修复方案
方案一:在Cron任务中直接传递环境变量
修改entrypoint.sh中生成Cron配置的代码,将需要的环境变量直接写入Cron配置文件:
echo "SHELL=/bin/bash TELEGRAM_POSTING_API_ID=${TELEGRAM_POSTING_API_ID} TELEGRAM_POSTING_API_HASH=${TELEGRAM_POSTING_API_HASH} */2 * * * * cd /app/xyz/telegram/ && python3 my_python_script.py >> /var/log/cron.log 2>&1 # This extra line makes it a valid cron" > scheduler.txt
这样Cron执行任务时会加载这些环境变量,脚本就能正常获取到API信息。
方案二:让Cron加载容器的完整环境变量
- 在entrypoint.sh中添加导出环境变量到系统文件的命令:
# 导出当前shell的环境变量到/etc/environment printenv > /etc/environment
- 修改Cron任务行,先加载环境变量文件再执行脚本:
echo "SHELL=/bin/bash */2 * * * * source /etc/environment && cd /app/xyz/telegram/ && python3 my_python_script.py >> /var/log/cron.log 2>&1 # This extra line makes it a valid cron" > scheduler.txt
这种方法会让Cron任务继承容器的所有环境变量,适合需要多个环境变量的场景。
验证修复
重启Docker容器后,等待Cron执行任务(根据配置为每2分钟一次),查看/var/log/cron.log日志确认无报错,或手动执行Cron任务测试脚本是否正常运行。
内容的提问来源于stack exchange,提问作者rrcabrera9625
相关产品推荐
相关产品推荐

