Docker:从Apache容器连接到Oracle数据库容器时出现连接超时



目前,我有一个奇怪的问题,当我试图从Apache容器连接到Oracle数据库容器时,我会从oci_error方法中得到"TNS:连接超时"。我的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数据库容器?

注意:我使用的是:

  • centos-release-7-7.1908.0.el7.centos.x86_64
  • Docker版本19.03.8,构建afacb8b
  • Oracle数据库12.1.0.2来自https://github.com/oracle/docker-images

在使用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

现在,您的场景是您的数据库容器没有连接到dockercompose创建的网络。像这样:

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这样的单独文件中,其中定义了网络名称。从那时起,您的容器将能够与数据库进行通信。

祝你好运!

最新更新