Oracle 19c Docker 容器化部署详解

Oracle 19c Docker 容器化部署详解

适用版本:Oracle Database 19c (19.3) for Linux x86-64 适用场景:开发测试环境、CI/CD 流水线、本地学习 文档版本:v1.0 / 2026-07


目录


1. 概述:为什么用 Docker 部署 Oracle

传统 Oracle 安装方式(OUI/RPM)需要繁琐的系统配置、依赖包安装和参数调优,部署时间通常 30-60 分钟。Docker 容器化部署把”操作系统 + Oracle 软件 + 数据库实例”打包成镜像,几秒钟就能拉起一个可用实例[1][2]。

核心优势

  1. 快速部署docker run 一条命令拉起完整数据库
  2. 环境一致:开发、测试、生产用同一镜像,避免”在我机器上能跑”
  3. 隔离性好:每个容器独立,不污染主机环境
  4. 易于销毁重建:开发数据可随时重置
  5. CI/CD 友好:流水线中可快速拉起测试数据库

主要限制

  1. 生产适用性存疑:Oracle 官方文档明确说明容器镜像仅适用于开发测试[1]
  2. 性能开销:Docker 比裸机有 5-10% 性能损失
  3. 数据持久化复杂:需要严格管理数据卷
  4. 补丁管理麻烦:容器原则是不可变,打补丁需重建镜像
  5. 不支持的特性:RAC、GI、ASM 在容器中不适用
  6. License 限制:商业使用需遵守 Oracle 协议

适用场景

  • 开发本地调试
  • 单元测试、集成测试
  • CI/CD 流水线
  • Oracle 学习和实验
  • 数据库迁移的过渡环境

不适用场景

  • 生产核心 OLTP 系统
  • RAC 集群
  • 大规模数据仓库
  • 对性能要求极高的场景

2. Docker 部署的前置准备

2.1 硬件要求

资源最低推荐
CPU2 核4 核+
内存4 GB8 GB+
磁盘20 GB50 GB+
Docker 版本18.0320.10+

2.2 安装 Docker

CentOS / RHEL / Oracle Linux

# 卸载旧版
yum remove -y docker docker-client docker-client-latest docker-common \
    docker-latest docker-latest-logrotate docker-logrotate docker-engine

# 安装 yum-utils
yum install -y yum-utils

# 添加 Docker 官方仓库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker CE
yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动 Docker
systemctl start docker
systemctl enable docker

# 验证
docker --version
docker run hello-world

Ubuntu / Debian

apt-get update
apt-get install -y ca-certificates curl gnupg lsb-release

mkdir -p ******
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

2.3 配置 Docker 镜像加速(国内)

mkdir -p ******
cat > /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ],
  "data-root": "/data/docker",
  "default-runtime": "runc",
  "live-restore": true
}
EOF

systemctl daemon-reload
systemctl restart docker

坑 1:默认 Docker 数据目录 /var/lib/docker 可能空间不足,建议改到独立数据盘。

2.4 配置 Docker 用户组

# 让普通用户可使用 docker 命令
usermod -aG docker $USER

# 重新登录生效

3. 获取 Oracle 官方镜像

3.1 方式一:拉取官方预构建镜像(推荐)

坑 2:必须使用 Oracle 官方新地址 container-registry.oracle.com,旧地址 store/oracle/database:19.0.0.0 已下线[1]。

步骤 1:在 Oracle Container Registry 注册

  1. 访问 https://container-registry.oracle.com
  2. 用 Oracle 账号登录(无账号先注册)
  3. 在左侧选择 Databaseenterprise
  4. 接受许可协议

步骤 2:在命令行登录

docker login container-registry.oracle.com
# 输入 Oracle 账号和密码

步骤 3:拉取镜像

# 19c 企业版
docker pull container-registry.oracle.com/database/enterprise:19.3.0.0

# 19c 标准版 2
docker pull container-registry.oracle.com/database/se2:19.3.0.0

# 查看镜像
docker images | grep oracle

镜像大小:约 5-7 GB。

3.2 方式二:基于官方 Dockerfile 构建

适用场景:需要定制镜像、无法访问 Oracle Container Registry[3]。

步骤 1:克隆官方 docker-images 仓库

git clone https://github.com/oracle/docker-images.git
cd docker-images/OracleDatabase/SingleInstance

步骤 2:下载安装包

从 Oracle 官网下载 LINUX.X64_193000_db_home.zip(约 2.8 GB),放到对应版本目录:

cd dockerfiles/19.3.0
cp /tmp/LINUX.X64_193000_db_home.zip .

步骤 3:构建镜像

cd ..  # 回到 dockerfiles 目录

# 构建企业版
./buildContainerImage.sh -v 19.3.0 -e

# 构建标准版 2
./buildContainerImage.sh -v 19.3.0 -s

参数说明

参数含义
-vOracle 版本(如 19.3.0)
-eEnterprise Edition
-sStandard Edition 2
-t自定义镜像名
-i忽略 SHA256 校验
-o构建后立即运行容器

构建时间:约 30-60 分钟,视硬件和网络。

坑 3:构建过程需要从 yum 源安装依赖包,国内网络可能慢,建议先配置好 yum 源或镜像加速。

步骤 4:验证镜像

docker images oracle/database
# REPOSITORY          TAG         IMAGE ID       CREATED         SIZE
# oracle/database     19.3.0-ee   8c5af2c3c4d5   2 minutes ago   6.5GB

3.3 方式三:使用第三方镜像(不推荐生产)

gvenzl/oracle-xe(21c XE 免费版,适合开发):

docker pull gvenzl/oracle-xe:21-full

docker run -d --name oracle-xe \
  -p ****** -p ****** \
  -e ORACLE_PASSWORD=****** \
  -v /data/oracle-xe:/opt/oracle/oradata \
  gvenzl/oracle-xe:21-full

坑 4不要使用 Docker Hub 上标着 “oracle19c” 的不明镜像[1],多数未更新且无签名验证,存在安全风险。


4. 启动 Oracle 容器

4.1 基础启动

docker run -d \
  --name oracle19c \
  -p ****** -p ****** \
  -e ORACLE_PWD=****** \
  container-registry.oracle.com/database/enterprise:19.3.0.0

关键参数[1]:

参数作用推荐值
--name容器名oracle19c
-p 1521:1521数据库监听端口映射1521
-p 5500:5500EM Express 端口映射5500
-e ORACLE_PWDSYS/SYSTEM/PDBADMIN 密码强密码
-e ORACLE_SID实例名(默认 ORCLCDB)orcl
-e ORACLE_PDBPDB 名(默认 ORCLPDB1)pdb1
-e ORACLE_CHARACTERSET字符集(默认 AL32UTF8)AL32UTF8

4.2 数据持久化

坑 5:容器销毁后数据会丢失,必须挂载数据卷[1]。

# 在宿主机创建目录(必须用绝对路径,权限 777)
sudo mkdir -p ******
sudo chmod 777 /data/oracle/oradata

# 启动时挂载
docker run -d \
  --name oracle19c \
  -p ****** -p ****** \
  -e ORACLE_PWD=****** \
  -v /data/oracle/oradata:/opt/oracle/oradata \
  container-registry.oracle.com/database/enterprise:19.3.0.0

坑 6:挂载目录必须用绝对路径,权限 777。容器内 oracle 用户没有 sudo 权限,无法递归创建父目录[1]。

坑 7:相对路径(如 ./oradata~/oradata)不行,会导致静默失败。

4.3 完整启动命令

docker run -d \
  --name oracle19c \
  --hostname oracle19c.example.com \
  -p ****** -p ****** \
  -e ORACLE_SID=orcl \
  -e ORACLE_PDB=pdb1 \
  -e ORACLE_PWD=****** \
  -e ORACLE_CHARACTERSET=AL32UTF8 \
  -v /data/oracle/oradata:/opt/oracle/oradata \
  -v /data/oracle/scripts:/opt/oracle/scripts/setup \
  --memory=8g --memory-swap=8g \
  --shm-size=2g \
  --restart unless-stopped \
  container-registry.oracle.com/database/enterprise:19.3.0.0

关键参数解析

参数作用
--hostname容器主机名(影响 listener.ora 中 HOST)
--memory容器可用内存上限
--shm-size/dev/shm 大小,影响 MEMORY_TARGET
--restart unless-stopped容器异常退出自动重启
-v /opt/oracle/scripts/setup启动时执行的初始化脚本目录

5. 验证数据库就绪

坑 8:容器启动后不能立即连接,Oracle 初始化需要 5-10 分钟[1]。

实时监控日志

docker logs -f oracle19c

等待关键标志

DATABASE IS READY TO USE!

看到这行后才能连接。

后台查看(非阻塞)

docker logs --tail 50 oracle19c

典型启动日志

Starting Oracle Net Listener.
Oracle Net Listener started.
Starting Oracle Database instance ORCLCDB.
Oracle Database instance ORCLCDB mounted.
Oracle Database instance ORCLCDB opened.
DATABASE IS READY TO USE!

自动等待就绪脚本

#!/bin/bash
# wait-for-oracle.sh
echo "Waiting for Oracle to be ready..."
while ! docker logs oracle19c 2>&1 | grep -q "DATABASE IS READY TO USE!"; do
  sleep 10
  echo "Still waiting..."
done
echo "Oracle is ready!"

6. 连接数据库

6.1 容器内连接

# 进入容器
docker exec -it oracle19c bash

# 容器内用 sqlplus 连接
sqlplus / as sysdba

SQL> SELECT status FROM v$instance;
STATUS
------------
OPEN

SQL> SELECT name, open_mode FROM v$pdbs;
NAME            OPEN_MODE
--------------- ----------
ORCLPDB1        READ WRITE

6.2 宿主机连接

前提:宿主机已安装 Oracle Instant Client。

# 安装 Instant Client(Oracle Linux)
yum install -y oracle-instantclient-basic oracle-instantclient-sqlplus

# 或下载 RPM 安装
rpm -ivh oracle-instantclient-basic-*.rpm oracle-instantclient-sqlplus-*.rpm

# 连接
sqlplus system/Oracle_123@//localhost:1521/ORCLPDB1

6.3 远程客户端连接

使用 SQL Developer / DBeaver / Navicat

参数
Host服务器 IP
Port1521
Service NameORCLCDB(CDB)或 ORCLPDB1(PDB)
Usernamesystem 或 sys as sysdba
PasswordOracle_123

使用 tnsnames.ora

ORCLCDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = server_ip)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCLCDB)
    )
  )

ORCLPDB1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = server_ip)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCLPDB1)
    )
  )

连接测试

sqlplus system/Oracle_123@ORCLPDB1

6.4 EM Express Web 管理

访问 http://server_ip:5500/em,用户名 sys,密码 Oracle_123,连接身份 SYSDBA

坑 9:EM Express 默认只允许容器内访问,需配置允许远程:

sqlplus / as sysdba <<EOF
EXEC DBMS_XDB_CONFIG.SETLISTENERLOCALACCESS(FALSE);
COMMIT;
EOF

7. 容器管理与运维

7.1 启停容器

# 停止(会优雅关闭数据库)
docker stop oracle19c

# 启动
docker start oracle19c

# 重启
docker restart oracle19c

# 查看状态
docker ps -a | grep oracle19c

坑 10:直接 docker kill 会导致数据库异常关闭,可能丢数据。必须用 docker stop(默认 10 秒超时,建议加大):

docker stop -t 60 oracle19c

7.2 进入容器

# 以 oracle 用户进入
docker exec -it oracle19c bash

# 以 root 用户进入
docker exec -it -u root oracle19c bash

# 直接执行 SQL
docker exec -it oracle19c sqlplus / as sysdba

7.3 查看日志

# 容器启动日志
docker logs oracle19c

# 实时跟踪
docker logs -f oracle19c

# 最近 100 行
docker logs --tail 100 oracle19c

# 指定时间后
docker logs --since 2h oracle19c

Oracle alert log

docker exec -it oracle19c bash -c "tail -100 \$ORACLE_BASE/diag/rdbms/orclcdb/ORCLCDB/trace/alert_ORCLCDB.log"

7.4 资源限制

查看容器资源使用

docker stats oracle19c

运行时限制资源(启动时):

docker run -d \
  --name oracle19c \
  --memory=8g \
  --memory-swap=8g \
  --cpus=4 \
  --shm-size=2g \
  ...

运行时调整

docker update --memory=16g --cpus=8 oracle19c

8. 数据持久化与备份

8.1 数据卷规划

推荐目录结构[2]:

/data/oracle/
├── oradata/           # 数据文件(必须)
├── scripts/
│   ├── setup/         # 启动时执行的脚本
│   └── startup/       # 每次启动执行的脚本
├── backup/            # 备份目录
└── config/            # 自定义配置

完整挂载启动

docker run -d \
  --name oracle19c \
  -p ****** -p ****** \
  -e ORACLE_PWD=****** \
  -v /data/oracle/oradata:/opt/oracle/oradata \
  -v /data/oracle/scripts/setup:/opt/oracle/scripts/setup \
  -v /data/oracle/scripts/startup:/opt/oracle/scripts/startup \
  -v /data/oracle/backup:/opt/oracle/backup \
  container-registry.oracle.com/database/enterprise:19.3.0.0

8.2 备份与恢复

方式一:容器内 RMAN 备份

# 进入容器
docker exec -it oracle19c bash

# 执行 RMAN 备份
rman target / <<EOF
RUN {
  ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
  BACKUP DATABASE PLUS ARCHIVELOG 
    FORMAT '/opt/oracle/backup/db_%d_%T_%U.bkp';
  RELEASE CHANNEL ch1;
}
EOF

方式二:导出数据泵(expdp)

docker exec -it oracle19c bash -c "
mkdir -p ******
sqlplus / as sysdba <<EOF
CREATE OR REPLACE DIRECTORY dpump_dir AS '/opt/oracle/backup/dpump';
GRANT READ, WRITE ON DIRECTORY dpump_dir TO system;
EOF

expdp system/Oracle_123@ORCLPDB1 \
  schemas=HR \
  directory=dpump_dir \
  dumpfile=hr.dmp \
  logfile=hr.log
"

方式三:宿主机直接备份挂载目录

# 停止容器
docker stop oracle19c

# 备份整个数据目录
tar -czf /backup/oracle_$(date +%Y%m%d).tar.gz /data/oracle/oradata/

# 启动容器
docker start oracle19c

坑 11:必须在容器停止后才能完整备份 oradata,运行中备份可能不一致。

8.3 镜像与数据迁移

导出镜像

docker save -o oracle19c.tar container-registry.oracle.com/database/enterprise:19.3.0.0

导入镜像

docker load -i oracle19c.tar

数据迁移到新机器

# 1. 停止旧容器
docker stop oracle19c

# 2. 复制数据目录
rsync -avz /data/oracle/oradata/ newserver:/data/oracle/oradata/

# 3. 在新机器启动新容器(用相同镜像和数据卷)
docker run -d --name oracle19c \
  -v /data/oracle/oradata:/opt/oracle/oradata \
  ...其他参数...

9. 自定义初始化脚本

Oracle 官方镜像支持在启动时自动执行自定义脚本[1]。

9.1 setup 脚本(仅首次启动执行)

放置在 /opt/oracle/scripts/setup,首次创建数据库后执行。

示例:创建业务表空间和用户

# 宿主机
mkdir -p ******

cat > /data/oracle/scripts/setup/01_create_tablespace.sh <<'EOF'
#!/bin/bash
sqlplus / as sysdba <<SQL
CREATE TABLESPACE business_data
  DATAFILE '/opt/oracle/oradata/ORCLCDB/business01.dbf' SIZE 1G
  AUTOEXTEND ON NEXT 100M MAXSIZE 10G;

CREATE USER biz_user IDENTIFIED BY ******
  DEFAULT TABLESPACE business_data
  QUOTA UNLIMITED ON business_data;

GRANT CONNECT, RESOURCE TO biz_user;
SQL
EOF

chmod +x /data/oracle/scripts/setup/01_create_tablespace.sh

9.2 startup 脚本(每次启动执行)

放置在 /opt/oracle/scripts/startup

示例:启动后打开所有 PDB

mkdir -p ******

cat > /data/oracle/scripts/startup/01_open_pdbs.sh <<'EOF'
#!/bin/bash
sqlplus / as sysdba <<SQL
ALTER PLUGGABLE DATABASE ALL OPEN;
SQL
EOF

chmod +x /data/oracle/scripts/startup/01_open_pdbs.sh

9.3 脚本执行顺序

  • setup 目录中脚本按文件名排序执行
  • startup 目录中脚本按文件名排序执行
  • 建议用数字前缀(01_02_)保证顺序

10. Docker Compose 部署

10.1 docker-compose.yml

version: '3.8'

services:
  oracle19c:
    image: container-registry.oracle.com/database/enterprise:19.3.0.0
    container_name: oracle19c
    hostname: oracle19c.example.com
    ports:
      - "1521:1521"
      - "5500:5500"
    environment:
      - ORACLE_SID=orcl
      - ORACLE_PDB=pdb1
      - ORACLE_PWD=******
      - ORACLE_CHARACTERSET=AL32UTF8
    volumes:
      - oracle_data:/opt/oracle/oradata
      - ./scripts/setup:/opt/oracle/scripts/setup
      - ./scripts/startup:/opt/oracle/scripts/startup
      - ./backup:/opt/oracle/backup
    shm_size: '2gb'
    mem_limit: 8g
    cpus: 4
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "echo 'SELECT 1 FROM DUAL;' | sqlplus -s / as sysdba || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 5m

volumes:
  oracle_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /data/oracle/oradata

10.2 启动与管理

# 启动
docker-compose up -d

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs -f oracle19c

# 停止
docker-compose down

# 停止并删除数据卷(危险!会丢失数据)
docker-compose down -v

11. 常见坑与排错

坑 1:ORACLE_PWD 被解析错误

原因[1]:密码含特殊字符(!$`")会被 shell 提前解析。

解决

# 推荐:纯字母+数字
-e ORACLE_PWD=******

# 必须含特殊字符时用单引号
-e 'ORACLE_PWD=******

坑 2:容器内 mkdir 失败

现象:日志报 mkdir: cannot create directory '/opt/oracle/oradata': Permission denied[1]。

原因:宿主机挂载目录权限不足。

解决

# 必须用绝对路径并授权 777
sudo mkdir -p ******
sudo chmod 777 /data/oracle/oradata

坑 3:连接报 ORA-12514

原因:容器还未就绪就尝试连接[1]。

解决:等日志输出 DATABASE IS READY TO USE! 再连接。

坑 4:内存不足导致容器被 OOM Kill

现象docker logs 显示 Killed,宿主机 dmesg 有 oom-killer 记录。

解决

# 增大容器内存限制
docker update --memory=16g oracle19c

# 或调整 Oracle SGA/PGA
docker exec -it oracle19c sqlplus / as sysdba
ALTER SYSTEM SET sga_target=4G SCOPE=SPFILE;
ALTER SYSTEM SET pga_aggregate_target=1G SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;

坑 5:容器时区错误

现象:数据库时间与宿主机不一致。

解决

docker run -d \
  -e TZ=Asia/Shanghai \
  -v /etc/localtime:/etc/localtime:ro \
  ...

坑 6:listener.ora HOST 错误

现象:远程连接失败。

解决

# 查看监听配置
docker exec oracle19c cat $ORACLE_HOME/network/admin/listener.ora

# HOST 应为 0.0.0.0 或容器主机名,不能是 localhost

坑 7:数据卷已存在数据导致启动失败

现象:删除容器后用旧数据卷启动,启动失败。

原因:旧数据可能与新容器 SID 配置不一致。

解决

# 方案 1:清空数据卷重新初始化
rm -rf /data/oracle/oradata/*

# 方案 2:保持原 SID
docker run -d --name oracle19c \
  -e ORACLE_SID=ORCLCDB \
  -v /data/oracle/oradata:/opt/oracle/oradata \
  ...

坑 8:容器重启后 PDB 没打开

现象:连接 PDB 报 ORA-01109。

解决

docker exec -it oracle19c sqlplus / as sysdba <<EOF
ALTER PLUGGABLE DATABASE ALL OPEN;
SAVE STATE;
EOF

或在 startup 脚本中加入该命令。

坑 9:磁盘空间不足

现象:容器启动失败,日志报 No space left on device

解决

# 查看 Docker 占用空间
docker system df

# 清理无用镜像和容器
docker system prune -a

# 转移 Docker 数据目录
# 见 2.3 配置 daemon.json

12. 最佳实践

  1. 用官方镜像:从 container-registry.oracle.com 拉取[1]
  2. 必须挂载数据卷:避免容器销毁丢数据
  3. 挂载目录用绝对路径 + 777 权限[1]
  4. 密码用纯字母数字:避免 shell 解析问题
  5. 配置 —shm-size:影响自动内存管理
  6. 配置 —restart unless-stopped:异常自动恢复
  7. 配置健康检查:让编排系统知道数据库状态
  8. 启用 EM Express 远程访问:方便 Web 管理
  9. 用 Docker Compose:配置版本化管理
  10. 定期备份:RMAN + 数据卷双备份
  11. 生产环境慎用:仅推荐开发测试,生产用裸机或 OCI DB
  12. 资源限制合理:内存至少 4G,CPU 至少 2 核
  13. 监控资源使用docker stats 定期查看
  14. 使用 startup 脚本:自动化常见运维操作

13. 参考资料

[1] php.cn,《如何在 Docker 中快速部署 Oracle 19c 容器化环境》: https://m.php.cn/faq/2677952.html

[2] CSDN,《Oracle 数据库 Docker 化实战:从镜像构建到 Navicat 连接全流程》: https://wenku.csdn.net/column/5g9x1f289ga

[3] Oracle 官方 GitHub docker-images 仓库: https://github.com/oracle/docker-images

[4] Oracle Container Registry: https://container-registry.oracle.com

[5] Oracle Database 19c 官方文档: https://docs.oracle.com/en/database/oracle/oracle-database/19/

[6] jishuzhan.net,《自己如何动手创建 Oracle 19c 19.3 标准版 2 DOCKER 镜像》: https://jishuzhan.net/article/1996794338324578306

[7] Oracle 官方文档,Setting Up Oracle Database in Docker: https://docs.oracle.com/cd/F26413_38/books/DeployCont/c-Setting-Up-Oracle-Database.html

[8] gvenzl/oracle-xe 开源镜像: https://hub.docker.com/r/gvenzl/oracle-xe


相关文章