Docker:从 Apache 容器连接到 Oracle 数据库容器时出现连接超时
Docker: Got Connection Timeout when connecting to Oracle Database Container from an Apache Container
目前,我有一个奇怪的问题,当我尝试从 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() );
}
?>
我的 docker 到 运行 Oracle 数据库的代码是:
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路由,非DockerPHP也可以连接到这个Oracle数据库。
所以我认为这是 Docker 问题。我在这里错过了什么?在这种情况下,我怎样才能让 Apache 容器连接到 Oracle 数据库容器?
注意:我正在使用:
- centos-release-7-7.1908.0.el7.centos.x86_64
- Docker 版本 19.03.8,构建 afacb8b
- 来自 https://github.com/oracle/docker-images
的 Oracle 数据库 12.1.0.2
使用 docker-compose 与 docker 运行 时会发生一些方便的魔法。网络将隐式建立。
一个例子:
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
由于已建立默认网络,这些容器将能够相互通信。 (folder_name_default)
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
这样定义了网络名称的单独文件中。从那里你的容器将能够与数据库通信。
祝你好运!
目前,我有一个奇怪的问题,当我尝试从 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() );
}
?>
我的 docker 到 运行 Oracle 数据库的代码是:
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:
启动了我的 Apacheversion: '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路由,非DockerPHP也可以连接到这个Oracle数据库。
所以我认为这是 Docker 问题。我在这里错过了什么?在这种情况下,我怎样才能让 Apache 容器连接到 Oracle 数据库容器?
注意:我正在使用:
- centos-release-7-7.1908.0.el7.centos.x86_64
- Docker 版本 19.03.8,构建 afacb8b
- 来自 https://github.com/oracle/docker-images 的 Oracle 数据库 12.1.0.2
使用 docker-compose 与 docker 运行 时会发生一些方便的魔法。网络将隐式建立。
一个例子:
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
由于已建立默认网络,这些容器将能够相互通信。 (folder_name_default)
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
这样定义了网络名称的单独文件中。从那里你的容器将能够与数据库通信。
祝你好运!