【问题标题】:Docker: Got Connection Timeout when connecting to Oracle Database Container from an Apache ContainerDocker:从 Apache 容器连接到 Oracle 数据库容器时出现连接超时
【发布时间】:2020-03-23 22:14:23
【问题描述】:

目前,我有一个奇怪的问题,当我尝试从 Apache 容器连接到 Oracle 数据库容器时,我会从 oci_error 方法中得到“TNS: Connect Timeout Occurred”。我的PHP代码如下:

<?php

        $objConnect = oci_connect('SYSTEM', 'xxxxxxxxxx', 'x.x.x.x/xxxxx');
        if($objConnect)
        {
                echo "from Docker Oracle Server Connected" . PHP_EOL;
        }
        else
        {
                echo "Cannot connect to Oracle Server" . PHP_EOL;
                var_dump( oci_error() );
        }

?>

我运行 Oracle 数据库的 docker 代码是:

docker run --name orcl_12c_r_1 -p 1521:1521 -p 5500:5500 -e ORACLE_SID=xxxxx oracle/database:12.1.0.2-se2

我用这个 docker-compose.yml 启动了我的 Apache:

version: '3'
services:

  oraclelinuxphp:
    build:
      context: ./oraclelinuxphp
      dockerfile: Dockerfile # install httpd and PHP here.
    ports:
      - "8080:80"
    volumes:
      - ./web:/var/www/html

但是,当我将 network_mode 主机添加到 docker-compose.yml 时,此问题已解决

version: '3'
services:

  oraclelinuxphp:
    build:
      context: ./oraclelinuxphp
      dockerfile: Dockerfile # install httpd and PHP here.
    ports:
      - "8080:80"
    volumes:
      - ./web:/var/www/html
    network_mode: "host"

说到 Docker,我还是个菜鸟,从这里开始,我相信我在 Docker 中缺少一些东西。我可以毫无问题地从桌面上的 Oracle SQL Developer 应用程序连接到服务器上容器中的 Oracle 数据库。另外,我也尝试了非Docker路由,非Docker PHP也可以连接到这个Oracle数据库。

所以我相信这是 Docker 问题。我在这里想念什么?在这种情况下,如何让 Apache 容器连接到 Oracle 数据库容器?

注意:我正在使用:

【问题讨论】:

    标签: oracle apache docker docker-compose oracle12c


    【解决方案1】:

    在使用 docker-compose 与 docker run 时,会发生一些方便的魔法。网络将隐式建立。

    一个例子:

    cat > docker-compose.yml <<EOF
    version: '3'
    services:
      c1:
        image: alpine
        container_name: c1
        command: "sleep 1000"
      c2:
        image: alpine
        container_name: c2
        command: "sleep 1000"
    EOF
    
    # fire up the containers and detach
    docker-compose up -d
    

    由于已经建立了默认网络,这些容器将能够相互通信。 (文件夹名称默认)

    docker network ls -fname=demo1
    NETWORK ID          NAME                DRIVER              SCOPE
    e3777f15f5aa        demo1_default       bridge              local
    
    # c1 can talk to c2
    docker-compose exec c1 sh -c 'ping -c1 c2'
    PING c2 (172.30.0.2): 56 data bytes
    64 bytes from 172.30.0.2: seq=0 ttl=64 time=3.741 ms
    
    # c2 can talk to c1
    docker-compose exec c2 sh -c 'ping -c1 c1'
    PING c1 (172.30.0.3): 56 data bytes
    64 bytes from 172.30.0.3: seq=0 ttl=64 time=0.798 ms
    

    现在,您的情况是您的数据库容器未连接到 docker-compose 创建的网络。像这样:

    docker run --rm -it --name c3 alpine sh -c 'ping -c1 c1'
    ping: bad address 'c1'
    

    您可以为您的运行命令定义网络(这将起作用):

    docker run --rm --net demo1_default -it --name c3 alpine sh -c 'ping -c1 c1'
    PING c1 (172.30.0.3): 56 data bytes
    64 bytes from 172.30.0.3: seq=0 ttl=64 time=0.571 ms
    
    # make sure c3 keeps running while we try to contact it.
    docker run --rm --net demo1_default -d -it --name c3 alpine sh -c 'sleep 1000'
    
    # yes it works! 
    docker-compose exec c1 sh -c 'ping -c1 c3'
    PING c3 (172.30.0.4): 56 data bytes
    64 bytes from 172.30.0.4: seq=0 ttl=64 time=0.314 ms
    

    为了将我所有不同的组件捆绑在一起,我总是在 docker-compose 中定义它们,我在其中明确命名网络,如下所示:

    cat > docker-compose.yml <<EOF
    version: '3'
    services:
      c1:
        image: alpine
        container_name: c1
        command: "sleep 1000"
        networks:
          - mynet
      c2:
        image: alpine
        container_name: c2
        command: "sleep 1000"
        networks:
          - mynet
    networks:
      mynet:
    EOF
    

    docker run 仅用于临时命令的东西。我会将数据库服务包含在 docker-compose.yml 文件或像 docker-compose -f mydb.yml up -d 这样定义网络名称的单独文件中。从那里您的容器将能够与数据库进行通信。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      • 2020-09-24
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多