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

Docker Compose部署DRF项目:JSON环境变量读取失败求助

问题分析与解决方法

核心问题

  1. Docker Compose的env_file不支持JSON格式:env_file仅识别键值对格式的文本文件(如.env),你的secrets.json是JSON结构,无法被直接加载。
  2. 原entrypoint.sh无法解析JSON:脚本用=分割行的方式读取文件,完全适配不了JSON的语法结构,导致环境变量未正确导出。
  3. backend服务未使用entrypoint.sh:docker-compose.yml里backend的entrypoint直接写了启动命令,等于没用到你准备的entrypoint脚本。

具体修改方案

1. 修复entrypoint.sh,使其正确解析JSON

替换原entrypoint.sh内容为以下代码(依赖jq工具解析JSON,需确保镜像中已安装):

#!/bin/bash

# 解析顶级JSON键值对,导出为环境变量
for key in $(jq -r 'keys[]' /app/secrets.json); do
    value=$(jq -r --arg key "$key" '.[$key]' /app/secrets.json)
    # 跳过嵌套的DATABASES,单独处理
    if [ "$key" != "DATABASES" ]; then
        export "$key"="$value"
    fi
done

# 解析DATABASES下的嵌套字段,统一添加POSTGRES_前缀
db_default=$(jq -r '.DATABASES.default' /app/secrets.json)
for db_key in $(echo "$db_default" | jq -r 'keys[]'); do
    db_value=$(echo "$db_default" | jq -r --arg key "$db_key" '.[$key]')
    export "POSTGRES_$(echo "$db_key" | tr '[:lower:]' '[:upper:]')"="$db_value"
done

# 执行Django启动流程
python manage.py collectstatic --no-input
python manage.py migrate
gunicorn Realby_project.wsgi --workers=5 -b 0.0.0.0:8000

补充:需在Django镜像的Dockerfile中安装jq,基于Debian/Ubuntu的镜像添加:RUN apt-get update && apt-get install -y jq;基于Alpine的镜像添加:RUN apk add --no-cache jq。

2. 修正docker-compose.yml配置

  • 移除postgres服务无效的env_file配置,改用环境变量传递数据库信息;
  • 修改backend服务的entrypoint,指向entrypoint.sh;
  • 删除backend中冗余的environment变量(将由entrypoint.sh从JSON自动导出)。

修改后的docker-compose.yml:

version: '3.8'
volumes:
  postgres: {}
  django_media: {}
  django_static: {}
services:
  postgres:
    container_name: postgres
    image: postgres:15.3
    volumes:
      - postgres:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_NAME=${POSTGRES_NAME}
  backend:
    container_name: backend
    build: ./backend/
    entrypoint: /app/entrypoint.sh
    volumes:
      - ./backend/django/:/app/
      - /etc/localtime:/etc/localtime:ro
      - django_media:/app/media/
      - django_static:/app/static/
      - ./backend/django/secrets.json:/app/secrets.json
    environment:
      - DEBUG=1
    depends_on:
      - postgres
    restart: always
  nginx:
    container_name : nginx
    image: nginx:1.23.2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - django_media:/media/
      - django_static:/static/
    depends_on:
      - backend
    restart: always

3. 配置Django读取环境变量

在settings.py中通过os.environ.get()获取环境变量,示例:

import os

SECRET_KEY = os.environ.get('SECRET_KEY')
DEBUG = os.environ.get('DEBUG', False) == '1'

DATABASES = {
    'default': {
        'ENGINE': os.environ.get('POSTGRES_ENGINE'),
        'NAME': os.environ.get('POSTGRES_NAME'),
        'USER': os.environ.get('POSTGRES_USER'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
        'HOST': os.environ.get('POSTGRES_HOST'),
        'PORT': os.environ.get('POSTGRES_PORT'),
    }
}

# 第三方服务配置同理
SOCIAL_AUTH_GOOGLE_CLIENT_ID = os.environ.get('SOCIAL_AUTH_GOOGLE_CLIENT_ID')
SOCIAL_AUTH_GOOGLE_SECRET = os.environ.get('SOCIAL_AUTH_GOOGLE_SECRET')

额外注意事项

  • 若不想依赖jq,可改用Python脚本解析JSON并导出环境变量;
  • 确保secrets.json中字段值无多余引号,jq会自动处理合法的JSON格式;
  • 生产环境建议使用Docker Secrets或专业密钥管理工具,避免直接挂载密钥文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:54:53