AWS上Django应用Redis连接失败:环境变量读取异常求助
Django应用Redis连接失败:环境变量已存在但仍获取为None
问题描述
在AWS部署用于检查RDS与Redis连接的小型Django应用时,遭遇Redis无法读取HOST、PORT等配置的问题:
- 先后尝试在ci.yml中配置环境变量、使用docker-compose搭配.env文件,均未解决问题
- 代码经资深开发者确认无逻辑错误
- 报错信息:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType',报错位置在/usr/local/lib/python3.9/site-packages/redis/connection.py第1415行的get_connection方法,触发请求为GET http://13.53.189.243:8001/test_connection/ - 执行
docker exec -it backend_redis_container env | grep REDIS可正常看到所有Redis相关环境变量,但应用连接Redis时仍触发上述错误
settings.py中Redis相关配置片段:
# Redis settings REDIS_HOST = os.environ.get('REDIS_HOST') REDIS_PORT = os.environ.get('REDIS_PORT') REDIS_DB = os.environ.get('REDIS_DB') REDIS_PASSWORD = os.environ.get('REDIS_PASSWORD')
解决方案
1. 确认容器启动时环境变量已正确传递
尽管docker exec能看到环境变量,但需确保变量是在容器启动阶段注入,而非启动后手动添加:
- 检查docker-compose.yml配置,确保env_file或environment字段正确:
services: backend: # 方式1:通过.env文件加载 env_file: - .env # 注意路径需相对于docker-compose.yml所在目录 # 方式2:直接映射环境变量 environment: - REDIS_HOST=${REDIS_HOST} - REDIS_PORT=${REDIS_PORT} - REDIS_DB=${REDIS_DB} - REDIS_PASSWORD=${REDIS_PASSWORD} - 重启容器使配置生效:
docker-compose down && docker-compose up -d
2. 修正环境变量读取逻辑
Django在启动时加载settings.py,若变量未就绪会导致os.environ.get返回None:
- 给变量添加默认值,同时增加调试日志确认值:
import os import logging logger = logging.getLogger(__name__) # Redis settings REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost') REDIS_PORT = os.environ.get('REDIS_PORT', '6379') REDIS_DB = os.environ.get('REDIS_DB', '0') REDIS_PASSWORD = os.environ.get('REDIS_PASSWORD', '') # 调试打印,部署后可移除 logger.info(f"Loaded REDIS_HOST: {REDIS_HOST}") logger.info(f"Loaded REDIS_PORT: {REDIS_PORT}") - 直接在读取时转换REDIS_PORT为整数,避免后续类型错误:
REDIS_PORT = int(os.environ.get('REDIS_PORT', 6379))
3. 检查.env文件格式
.env文件需严格遵循无引号、无空格的格式:
# 正确写法 REDIS_HOST=redis-service REDIS_PORT=6379 REDIS_DB=0 REDIS_PASSWORD=your-redis-password # 错误写法(会导致变量值异常) REDIS_HOST = "redis-service" REDIS_PORT='6379'
4. 确认文件权限
若应用容器运行用户无法读取.env文件,会导致变量加载失败:
- 修改.env文件权限:
chmod 644 .env - 确保docker-compose.yml中挂载的.env文件对容器内运行用户可读
5. 适配django-environ插件(若使用)
如果项目依赖django-environ管理环境变量,需确保正确读取.env文件:
import environ import os env = environ.Env() # 指定.env文件路径 environ.Env.read_env(os.path.join(BASE_DIR, '.env')) REDIS_HOST = env('REDIS_HOST') REDIS_PORT = env.int('REDIS_PORT') REDIS_DB = env.int('REDIS_DB') REDIS_PASSWORD = env('REDIS_PASSWORD', default='')
内容的提问来源于stack exchange,提问作者Vladyslav Kolodiazhnyi
相关产品推荐
相关产品推荐

