Oracle 19c Docker 容器化部署详解
Oracle 19c Docker 容器化部署详解
适用版本:Oracle Database 19c (19.3) for Linux x86-64 适用场景:开发测试环境、CI/CD 流水线、本地学习 文档版本:v1.0 / 2026-07
目录
- 1. 概述:为什么用 Docker 部署 Oracle
- 2. Docker 部署的前置准备
- 3. 获取 Oracle 官方镜像
- 4. 启动 Oracle 容器
- 5. 验证数据库就绪
- 6. 连接数据库
- 7. 容器管理与运维
- 8. 数据持久化与备份
- 9. 自定义初始化脚本
- 10. Docker Compose 部署
- 11. 常见坑与排错
- 12. 最佳实践
- 13. 参考资料
1. 概述:为什么用 Docker 部署 Oracle
传统 Oracle 安装方式(OUI/RPM)需要繁琐的系统配置、依赖包安装和参数调优,部署时间通常 30-60 分钟。Docker 容器化部署把”操作系统 + Oracle 软件 + 数据库实例”打包成镜像,几秒钟就能拉起一个可用实例[1][2]。
核心优势:
- 快速部署:
docker run一条命令拉起完整数据库 - 环境一致:开发、测试、生产用同一镜像,避免”在我机器上能跑”
- 隔离性好:每个容器独立,不污染主机环境
- 易于销毁重建:开发数据可随时重置
- CI/CD 友好:流水线中可快速拉起测试数据库
主要限制:
- 生产适用性存疑:Oracle 官方文档明确说明容器镜像仅适用于开发测试[1]
- 性能开销:Docker 比裸机有 5-10% 性能损失
- 数据持久化复杂:需要严格管理数据卷
- 补丁管理麻烦:容器原则是不可变,打补丁需重建镜像
- 不支持的特性:RAC、GI、ASM 在容器中不适用
- License 限制:商业使用需遵守 Oracle 协议
适用场景:
- 开发本地调试
- 单元测试、集成测试
- CI/CD 流水线
- Oracle 学习和实验
- 数据库迁移的过渡环境
不适用场景:
- 生产核心 OLTP 系统
- RAC 集群
- 大规模数据仓库
- 对性能要求极高的场景
2. Docker 部署的前置准备
2.1 硬件要求
| 资源 | 最低 | 推荐 |
|---|---|---|
| CPU | 2 核 | 4 核+ |
| 内存 | 4 GB | 8 GB+ |
| 磁盘 | 20 GB | 50 GB+ |
| Docker 版本 | 18.03 | 20.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 注册
- 访问 https://container-registry.oracle.com
- 用 Oracle 账号登录(无账号先注册)
- 在左侧选择
Database→enterprise - 接受许可协议
步骤 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
参数说明:
| 参数 | 含义 |
|---|---|
-v | Oracle 版本(如 19.3.0) |
-e | Enterprise Edition |
-s | Standard 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:5500 | EM Express 端口映射 | 5500 |
-e ORACLE_PWD | SYS/SYSTEM/PDBADMIN 密码 | 强密码 |
-e ORACLE_SID | 实例名(默认 ORCLCDB) | orcl |
-e ORACLE_PDB | PDB 名(默认 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 |
| Port | 1521 |
| Service Name | ORCLCDB(CDB)或 ORCLPDB1(PDB) |
| Username | system 或 sys as sysdba |
| Password | Oracle_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. 最佳实践
- 用官方镜像:从
container-registry.oracle.com拉取[1] - 必须挂载数据卷:避免容器销毁丢数据
- 挂载目录用绝对路径 + 777 权限[1]
- 密码用纯字母数字:避免 shell 解析问题
- 配置 —shm-size:影响自动内存管理
- 配置 —restart unless-stopped:异常自动恢复
- 配置健康检查:让编排系统知道数据库状态
- 启用 EM Express 远程访问:方便 Web 管理
- 用 Docker Compose:配置版本化管理
- 定期备份:RMAN + 数据卷双备份
- 生产环境慎用:仅推荐开发测试,生产用裸机或 OCI DB
- 资源限制合理:内存至少 4G,CPU 至少 2 核
- 监控资源使用:
docker stats定期查看 - 使用 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
相关文章