如何在 docker 容器之间连接到 oracle 数据库?

Posted

技术标签:

【中文标题】如何在 docker 容器之间连接到 oracle 数据库?【英文标题】:How can i connect to the oracle database between docker containers? 【发布时间】:2022-01-21 02:46:02 【问题描述】:

我有两个从 docker-compose 创建的容器,一个具有 apispringboot,另一个具有 oracle 数据库,但是它没有将 api 连接到数据库并且我已经用完了选项,我尝试在 aplication.propertiesdocker-compose.yml 中配置连接

这是docker-compose.yml

version: "3.7"
services:
  app:
    image: "bm_spring_boot:latest"
    build:
      context: ./BmApiRestV2/
      dockerfile: Dockerfile
    container_name: api_spring
    depends_on:
      - db
    ports:
      - 8888:8080
    environment:
      - SPRING_DATASOURCE_URL=jdbc:oracle:thin:@//db:49161/xe
      - SPRING_DATASOURCE_USERNAME=system
      - SPRING_DATASOURCE_PASSWORD=oracle
    networks:
      spring-net:
        aliases:
          - spring-host

  db:
    image: oracleinanutshell/oracle-xe-11g:latest
    container_name: oracle_db
    ports:
      - 49161:1521
      - 5500:5500
    environment:
      - ORACLE_ALLOW_REMOTE=true
    networks:
      spring-net:
        aliases:
          - db-host
networks:
  spring-net:
    driver: bridge
    ipam:
      driver: default

Dockerfile

ARG VERSION=8-jdk-slim
FROM openjdk:$VERSION
ARG JAR_FILE=BmApiRestV2
COPY "./target/$JAR_FILE.jar" "app.jar"
EXPOSE 8080
ENTRYPOINT [ "java","-jar","app.jar"]

aplication.properties

#spring.datasource.username=system
#spring.datasource.password=oracle
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
#DOCKER
#spring.datasource.url=jdbc:oracle:thin:@ (DESCRIPTION =    (ADDRESS_LIST =      (ADDRESS = (PROTOCOL = TCP)(HOST = db)(PORT = 49161))    )    (CONNECT_DATA =      (SID = xe)    )  )

(连接已被注释,因为在 docker-compose 中已配置)

感谢您的帮助(我为我的英语道歉)

------------- 更新 --------------

连接测试

 ping db
PING db (172.20.0.2) 56(84) bytes of data.
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=1 ttl=64 time=0.221 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=3 ttl=64 time=0.072 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=4 ttl=64 time=0.072 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=5 ttl=64 time=0.144 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=6 ttl=64 time=0.071 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=7 ttl=64 time=0.161 ms
64 bytes from oracle_db.imagenspring_spring-net (172.20.0.2): icmp_seq=8 ttl=64 time=0.063 ms
^C
--- db ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7090ms
rtt min/avg/max/mdev = 0.063/0.109/0.221/0.054 ms
root@2254b03a8ef4:/#

【问题讨论】:

查看应用容器的日志。 docker logs -f app_1 看看这个@RenéLink GenericDAO.findByCriteria. Causa: Failed to obtain JDBC Connection; nested exception is java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection (CONNECTION_ID=ovjLg/qBR/CvVN1B4sRQEw==). 如果将容器放在同一个网络中,则需要连接到原来的1521端口和你在别名中设置的主机名:db-host 如果要连接桥接接口需要使用主机接口的ip地址到端口49161 好的,我明白了。但我尝试使用 IP 地址并不起作用 【参考方案1】:

TLDR

将连接字符串中的端口更改为 1521。

加长版

您的服务和网络配置正确。两个容器都在同一个 docker 网络中,这允许它们相互通信。

另外,与某些 cmets 不同,所有 3 种调用容器的方式都是正确的:

分贝 数据库主机 oracle_db。

这可以使用简化的docker-compose.yml 轻松验证,只是为了测试连通性:

version: "3.7"
services:
  app:
    image: busybox
    command: "sh -c 'sleep 3600;'"
    networks:
      spring-net:
        aliases:
          - app-host
  db:
    image: busybox
    command: "sh -c 'sleep 3600;'"
    container_name: oracle_db
    networks:
      spring-net:
        aliases:
          - db-host
networks:
  spring-net:
    driver: bridge
    ipam:
      driver: default

如果您尝试解析名称 - 它们都指向同一个容器:

/ # ping db
PING db (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.593 ms
^C
--- db ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.593/0.593/0.593 ms
/ # ping oracle_db
PING oracle_db (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.213 ms
^C
--- oracle_db ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.213/0.213/0.213 ms
/ # ping db-host
PING db-host (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.334 ms
^C
--- db-host ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.334/0.334/0.334 ms

其实问题似乎出在你的连接字符串上:

- SPRING_DATASOURCE_URL=jdbc:oracle:thin:@//db:49161/xe

port 49161 是主机端口,而您连接到容器(db)。在这种情况下,您应该使用容器内的服务器绑定到的1521 端口。

【讨论】:

好的...但是那个端口正在本地使用,反正我测试了连接,没关系 没事是什么意思?切换到 1521 端口就可以了? 我更新了问题,你可以看到。我无法切换到 1521 端口,因为正在使用。 您的 1521 端口可能正在您的 docker 主机上使用。它仍然在您的容器中可用。在你的 conn 字符串中,你指的是你的容器 (db),它打开了 1521 端口。如果您要引用 docker 主机,则可以使用其他端口。 这看起来更像是您可能需要检查数据库服务器日志文件的错误,而不是连接问题

以上是关于如何在 docker 容器之间连接到 oracle 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

将 Spring Boot 应用程序连接到 Docker 容器中的 Oracle 数据库 12.2.0.1

如何将 Grafana 的 Docker 容器连接到 MySql 的 Docker 容器?

如何从 Docker 容器连接到本地 Redis 服务器?

如何通过 JMX 连接到远程 Docker 容器

如何将运行在 Docker 容器中的 Flyway 连接到运行在 Docker 容器中的数据库?

如何从 Windows 10 上的容器连接到 docker 主机(Docker for Windows)