Docker化Django应用连接Oracle报DPY-4027错误求助
Docker化Django应用连接Oracle数据库失败排查与解决
我在Windows10上使用Docker Desktop部署Django应用,尝试连接Oracle数据库时失败,已添加TNS_ADMIN环境变量但问题依旧。日常使用SQL Developer工具连接数据库正常。
1. tnsnames.ora 配置
# tnsnames.ora Network Configuration File: C:\app\HP\product\21c\homes\OraDB21Home1\NETWORK\ADMIN\tnsnames.ora # Generated by Oracle configuration tools. XE = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = xxx)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE) ) ) LISTENER_XE = (ADDRESS = (PROTOCOL = TCP)(HOST = xxx)(PORT = 1521)) ORACLR_CONNECTION_DATA = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) (CONNECT_DATA = (SID = CLRExtProc) (PRESENTATION = RO) ) )
2. Django数据库配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': os.environ.get("DB_NAME"), 'USER': os.environ.get("DB_USER"), 'HOST': os.environ.get("DB_HOST"), 'POSRT': os.environ.get("DB_PORT"), 'PASSWORD': os.environ.get("DB_PASS") } }
3. docker-compose.yml 配置
version: '3' services: backend: container_name: bdr-backend build: context: . command: > sh -c "python manage.py makemigrations --noinput && python manage.py migrate --noinput && python manage.py runserver 0.0.0.0:8000" ports: - 8000:8000 volumes: - ./backend:/backend env_file: - .env environment: - DEBUG=1 - DB_HOST=${DB_HOST} - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} depends_on: - redis redis: image: redis:7.0.5-alpine container_name: redis2 expose: - 6379
排查与解决步骤
1. 修正Django配置拼写错误
你的DATABASE配置里PORT写成了POSRT,这会导致端口参数读取失败,先修正:
'PORT': os.environ.get("DB_PORT"),
2. 在Docker镜像中安装Oracle Instant Client
Django的Oracle后端依赖Oracle客户端库,默认Python镜像没有包含,需要在Dockerfile中添加安装步骤:
FROM python:3.10-slim # 安装系统依赖 RUN apt-get update && apt-get install -y libaio1 wget unzip # 下载并解压Oracle Instant Client(对应你的Oracle版本,示例为21c) WORKDIR /opt/oracle RUN wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linux.x64-21.13.0.0.0.zip RUN unzip instantclient-basiclite-linux.x64-21.13.0.0.0.zip RUN rm instantclient-basiclite-linux.x64-21.13.0.0.0.zip # 设置Oracle相关环境变量 ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_21_13:$LD_LIBRARY_PATH ENV TNS_ADMIN=/opt/oracle/instantclient_21_13/network/admin # 创建TNS配置目录并复制本地的tnsnames.ora RUN mkdir -p /opt/oracle/instantclient_21_13/network/admin COPY ./tnsnames.ora /opt/oracle/instantclient_21_13/network/admin/ # 安装Python依赖 WORKDIR /backend COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制项目代码 COPY . .
3. 完善Docker Compose的环境变量与挂载
在docker-compose.yml的backend服务中,添加Oracle相关环境变量:
environment: - DEBUG=1 - DB_HOST=${DB_HOST} - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASS=${DB_PASS} - TNS_ADMIN=/opt/oracle/instantclient_21_13/network/admin - LD_LIBRARY_PATH=/opt/oracle/instantclient_21_13
如果不想在Dockerfile中复制tnsnames.ora,也可以通过volume挂载本地文件:
volumes: - ./backend:/backend - ./path/to/local/tnsnames.ora:/opt/oracle/instantclient_21_13/network/admin/tnsnames.ora
4. 解决本地数据库的网络访问问题
如果Oracle数据库在Windows本地主机上:
- 不能用
localhost或127.0.0.1作为DB_HOST,改用Windows主机的局域网IP(如192.168.x.x),或者Docker Desktop的特殊DNS名称host.docker.internal - 检查Windows防火墙是否允许1521端口的入站连接,确保容器能访问数据库端口
5. 验证数据库连接参数
确认.env文件中的参数正确:
DB_HOST=host.docker.internal DB_PORT=1521 DB_NAME=XE DB_USER=你的数据库用户名 DB_PASS=你的数据库密码
6. 测试容器内的连接
进入容器用sqlplus直接测试,排查是Django配置问题还是网络/客户端问题:
docker exec -it bdr-backend bash # 测试直连 sqlplus ${DB_USER}/${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME} # 测试TNS名称连接 sqlplus ${DB_USER}/${DB_PASS}@XE
内容的提问来源于stack exchange,提问作者leauradmin
相关产品推荐
相关产品推荐

