Oracle 23c 容器启动报“port is already allocated”基本是宿主机1521端口被占,需用sudo lsof -iTCP:1521 -sTCP:LISTEN查PID和进程名,确认是否为本地Oracle实例、残留docker-proxy或后台服务,并避免硬写1521:1521映射,推荐改用1522:1521等动态端口。

Oracle 23c 容器启动时卡在 port is already allocated,基本就是宿主机 1521 端口被占了——不是 Oracle 容器之间撞车,就是本地 Oracle 实例、旧容器残留、或某些后台服务(比如 Oracle XE、Instant Client 监听器)悄悄占着。
查清谁真正在监听 1521
别只信 docker ps,很多冲突来自宿主机原生进程或已退出但未清理的 docker-proxy 进程:
-
sudo lsof -iTCP:1521 -sTCP:LISTEN—— macOS/Linux 最准,能直接看到 PID 和命令名;如果输出里有oracle或tnslsnr,说明本地 Oracle 实例在运行 -
sudo ss -tuln | grep :1521—— Linux 快速验证,注意看State列是否为LISTEN -
docker ps --format "table {{.Names}}\t{{.Ports}}"—— 检查是否有其他 Oracle 容器(比如oracle-21c或oraclexe)也在映射1521 - Windows 用户用:
Get-NetTCPConnection -LocalPort 1521 | Format-List *,重点看OwningProcess对应的 PID,再用Get-Process -Id <PID>查进程名
Oracle 23c 容器端口映射不能硬写 1521:1521
Oracle 官方镜像(如 container-registry.oracle.com/database/free:23c)默认监听容器内 1521,但宿主机端口必须灵活。硬编码 "1521:1521" 在开发机多项目共存时必然撞车:
- 改用动态端口:比如
"1522:1521"或"1531:1521",只要宿主机空闲就行 - 在
docker-compose.yml里用环境变量:- "${ORACLE_PORT:-1522}:1521",启动时传ORACLE_PORT=1523即可切换 - 避免在多个
docker-compose.yml中重复声明同一宿主机端口,尤其团队协作时——建议约定:Oracle 服务统一用 1522~1529 范围
清理残留的 docker-proxy 或僵尸监听
即使 docker ps -a 看不到容器,1521 仍可能被 docker-proxy 持有(常见于 docker-compose down 后未加 --remove-orphans):
- 运行
sudo lsof -i :1521,若看到COMMAND是docker-proxy,说明有“幽灵容器”残留 - 执行
sudo pkill docker-proxy(Linux/macOS),或重启 Docker daemon:sudo systemctl restart docker - Windows WSL2 用户注意:WSL2 内核有时会缓存端口绑定,
netsh interface ipv4 show excludedportrange protocol=tcp可查系统保留端口,必要时wsl --shutdown再重启
Oracle 23c 特殊情况:监听地址绑定问题
Oracle 23c 容器启动后,有时日志显示 Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=0.0.0.0)(PORT=1521))),但宿主机仍连不上——这不是端口冲突,而是容器内监听绑定了 0.0.0.0,但 Docker 的 -p 映射没生效:
- 确认启动命令含
-p 1522:1521(或对应端口),且没加--network host(host 模式下不走端口映射) - 检查容器内是否真在监听:进容器执行
netstat -tlnp | grep :1521,若无输出,说明 Oracle 实例根本没起来,得看tail -f /opt/oracle/diag/rdbms/*/*/trace/alert_*.log - Oracle 23c 默认启用 TLS,客户端连接需用
tcps://协议和 wallet;若只想走明文,启动时加环境变量ORACLE_SSL=true改为false(具体以镜像文档为准)
真正麻烦的不是找不到谁占了 1521,而是找到之后不敢杀——比如生产环境本地装了 Oracle Client 并启了监听器。这时候别硬刚,换端口是最稳的解法;长期来看,把 Oracle 23c 放到独立网络(docker network create oracle-net)并配反向代理,比死磕 1521 更可持续。


















