使用Docker Compose时,PHP应用程序无法连接到MariaDB

3

我的应用程序是使用Docker Compose设置的。我的docker-compose.yml内容如下:

version: "3.1"
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
  db:
    image: mariadb:10.4
    restart: always
    ports:
      - "3307:3306"
    volumes:
      - ./mysql:/var/lib/mysql
    container_name: mariadb
    environment:
      - MYSQL_DATABASE=dbname
      - MYSQL_PASSWORD=dbpass
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_USER=dbuser
  phpapp:
    depends_on:
      - nginx-proxy
      - db
    image: myhub/myrepo
    restart: always
    container_name: phpapp
    expose:
      - 80
      - 443
    environment:
      - APP_ENV=prod
      - APP_SECRET="secret"
      - CORS_ALLOW_ORIGIN="^.*?$$"
      - DATABASE_URL="mysql://dbuser:dbpass@db/dbname"
      - VIRTUAL_HOST=phpapp.com
networks:
  default:
    external:
      name: nginx-proxy

然而,在应用程序中尝试连接数据库时,我收到了错误消息:SQLSTATE [HY000] [2002] No such file or directory
然而,我可以使用正确的用户名和密码在本地主机上的3307端口连接。此外,当我使用docker exec -ti phpapp /bin/bash访问容器并运行env时,我会列出所有环境变量,并且它们是正确的。
当我执行docker network inspect nginx-proxy时,我会得到;
[
  {
    "Name": "nginx-proxy",
    "Id": "2529933d7e38cfba34e0e876e43a96fc4c8d7321c1e89048319ba804b00e1026",
    "Created": "2018-12-12T05:04:01.9044879Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
      {
        "Subnet": "172.18.0.0/16",
        "Gateway": "172.18.0.1"
      }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {},
    "Labels": {}
  }
]

虽然在docker-compose.yml文件中设置了默认(外部)网络,但容器数组为空。


你的 PHP 应用程序使用哪个端口连接到数据库?3306 吗?确保你的容器真的在同一个 Docker 网络中:"docker network inspect nginx-proxy"。 - Hannes
我已经更新了我的问题,并附上了该命令的结果,谢谢。 - user10779576
2个回答

2

欢迎来到stackoverflow :)

我认为可能是因为db容器没有从phpapp容器链接过来,所以它不起作用。您可以尝试像这样操作:

version: "3.1"
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
  db:
    image: mariadb:10.4
    restart: always
    ports:
      - "3307:3306"
    volumes:
      - ./mysql:/var/lib/mysql
    container_name: mariadb
    environment:
      - MYSQL_DATABASE=dbname
      - MYSQL_PASSWORD=dbpass
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_USER=dbuser
  phpapp:
    depends_on:
      - nginx-proxy
    links:
      - db
    image: myhub/myrepo
    restart: always
    container_name: phpapp
    expose:
      - 80
      - 443
    environment:
      - APP_ENV=prod
      - APP_SECRET="secret"
      - CORS_ALLOW_ORIGIN="^.*?$$"
      - DATABASE_URL="mysql://dbuser:dbpass@db/dbname"
      - VIRTUAL_HOST=phpapp.com
networks:
  default:
    external:
      name: nginx-proxy

我将数据库从depends_on迁移到了links。现在,在数据库连接中,您必须使用db作为主机名。

希望能对您有所帮助。


1
请注意,在版本3中,links不起作用,因此在OP的情况下它将无法工作,并最终被弃用,请参见:https://docs.docker.com/network/links/。 - Sven Hakvoort
1
此外,我猜在组合服务中,它们可以通过使用自己的名称相互联系,无需提供链接选项。 - vivekyad4v
1
谢谢您和感谢您提供的解决方案。然而,正如Sven和vivekyad4v所指出的那样,版本3支持使用容器名称来链接服务。 - user10779576

0

好的,我已经找到了解决这个问题的方法。然而,它并不是我预期的那个。数据库的URL被定义为:

DATABASE_URL="mysql://dbuser:dbpass@db/dbname"

应该没有引号,像这样:

DATABASE_URL=mysql://dbuser:dbpass@db/dbname

现在一切似乎都正常工作了,有人知道何时以及为什么可以或不能使用引号吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接