如何从我的笔记本电脑 运行 sqlplus 连接到使用 docker-compose 启动的 dockerized oracle?

how to run sqlplus from my laptop and connect to dockerized oracle launched with docker-compose?

我正在尝试针对 Oracle 数据库设置自动集成测试并且我 计划使用 https://www.testcontainers.org/ 来 在我的 docker-compose.yml.

中启动容器

我已经在我的笔记本电脑上成功地 Dockerized Oracle 运行ning 使用这些说明: https://github.com/oracle/docker-images/tree/master/OracleWebLogic/samples/12212-oradb-wlsstore

步骤是:

# see https://docs.oracle.com/cd/E37670_01/E75728/html/oracle-registry-server.html
docker login container-registry.oracle.com  # supply your oracle credentials as described above

docker network create -d bridge SampleNET

cat > env.txt <<EOF
DB_SID=InfraDB
DB_PDB=InfraPDB1
DB_DOMAIN=us.oracle.com
DB_BUNDLE=basic
EOF

docker run -d --name InfraDB --network=SampleNET -p 1521:1521 -p 5500:5500 --env-file env.txt -it --shm-size="8g"  store/oracle/database-enterprise:12.2.0.1

一分钟后,我发出命令 "sudo docker ps -a",我看到数据库正常运行。

CONTAINER ID        IMAGE                                       COMMAND                  
6a276a311b2e        store/oracle/database-enterprise:12.2.0.1   "/bin/sh -c '/bin/ba…"   

CREATED             STATUS                        PORTS                             
2 minutes ago       Up 2 minutes (healthy)        0.0.0.0:1521->1521/tcp, 0.0.0.0:5500->5500/tcp   

NAMES
InfraDB

我现在可以 运行 sqlplus(来自笔记本电脑上的 shell 提示,而不是 Docker 容器):

sqlplus sys/Oradoc_db1@localhost:1521/InfraDB.us.oracle.com AS SYSDBA

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> 

我现在的目标是创建一个 Docker 撰写文件,让我可以 与命令行调用 Dockerized 完成的事情相同 神谕。这是我试过的 docker-compose.yml 文件:

version: '2'
services:
  database:
    image: store/oracle/database-enterprise:12.2.0.1
    ports:
      - 1521:1521
      - 8080:8080
      - 5500:5500
    environment:
      - DB_SID:InfraDB
      - DB_PDB:InfraPDB1
      - DB_DOMAIN:us.oracle.com
      - DB_BUNDLE:basic
networks:
  default:
    external:
      name: SampleNET

所以,有了这个 docker 撰写文件,我可以在 容器 运行ning 我的 Oracle 数据库和 运行 sqlplus:

container=`sudo docker ps -a | grep oracle | sed -e's/\s.*//'`

sudo docker exec -t -i $container bash

# SESSION INSIDE DOCKER CONTAINER:
[oracle@8f26f224db03 /]$ sqlplus sys/Oradoc_db1  AS SYSDBA

                        SQL*Plus: Release 12.2.0.1.0 Production on Tue Mar 3 02:44:03 2020
                        Copyright (c) 1982, 2016, Oracle.  All rights reserved.

现在,百万美元的问题:

我要指定的 sqlplus 命令的语法是什么 从我的笔记本电脑连接(即不启动 shell 容器 运行正在连接数据库服务器)?

以下是我尝试过的许多变体中的一些(注意:我尝试使用本地主机、127.0.0.1 和 我笔记本电脑的实际 IP):

sqlplus sys/Oradoc_db1@'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=InfraDB)))'

sqlplus sys/Oradoc_db1@'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=InfraDB.us.oracle.com)))'

诊断说明:

我 运行宁 Docker Mac。 在我启动 Docker-ized Oracle 后,我确实在 docker 组合配置转发的端口上看到了侦听器,如下所示:

sudo lsof -i -P | grep -i "listen" | egrep "1521|8080|5500"

com.docke 6295 christopher.bedford   33u  IPv6 0xfffffffffffffff      0t0    TCP *:1521 (LISTEN)
com.docke 6295 christopher.bedford   34u  IPv6 0xfffffffffffffff      0t0    TCP *:5500 (LISTEN)
com.docke 6295 christopher.bedford   38u  IPv6 0xfffffffffffffff      0t0    TCP *:8080 (LISTEN)

问题已解决

感谢我的朋友 Matt(下面的 Changos Muertos)的建议,这里总结了我为解决问题所做的工作。

1).不需要创建桥接网络 'SampleNET'。

2).似乎像这样内联指定环境变量(如下)不起作用

  environment:
  - DB_SID:InfraDB
  - DB_PDB:InfraPDB1
  - DB_DOMAIN:us.oracle.com
  - DB_BUNDLE:basic

3).相反,最好在 'env_file' 配置选项引用的文件中定义这些环境设置,如下所示。此文件位于 /tmp/docker-compose.yml

version: '2'
services:
  database:
    image: store/oracle/database-enterprise:12.2.0.1
    ports:
      - 1521:1521
      - 8080:8080
      - 5500:5500
    env_file:
      - e2.txt

env 文件内容位于同一目录 ( /tmp/e2.txt ),内容如下:

DB_SID=InfraDB
DB_PDB=InfraPDB1
DB_DOMAIN=us.oracle.com
DB_BUNDLE=basic

给运行 我愿意

   docker-compose -f /tmp/docker-compose.yml up

然后我可以通过以下方式连接(从我的笔记本电脑作为最初的目标):

    sqlplus sys/Oradoc_db1@0.0.0.0:1521/InfraDB.us.oracle.com as SYSDBA

这取决于一些因素,例如网络类型,以及端口转发是否正确。然后在主机上验证这一点(在 linux 'netstat -tlpn' 中),这将显示它是否正在侦听端口,如果是的话是什么接口和协议。该工具可能因主机而异 OS.

一旦您看到它通过 tcp(不仅是 tcp6)侦听,并且防火墙在主机上打开,您可以结合该信息来制作您的连接字符串。