为什么赢了';t TeamCity在使用docker compose时连接到MySQL?

为什么赢了';t TeamCity在使用docker compose时连接到MySQL?,mysql,docker-compose,teamcity,Mysql,Docker Compose,Teamcity,我正在尝试使用docker compose运行TeamCity服务器。这是我的撰写文件: version: '3' services: db: image: mysql container_name: teamcity-db restart: unless-stopped env_file: .env environment: - MYSQL_DATABASE=teamcity volumes: - mysql:/v

我正在尝试使用
docker compose
运行TeamCity服务器。这是我的撰写文件:

version: '3'

services:
  db:
    image: mysql
    container_name: teamcity-db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=teamcity
    volumes: 
      - mysql:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'

  teamcity:
    depends_on: 
      - db
    image: jetbrains/teamcity-server
    container_name: teamcity
    restart: unless-stopped
    volumes: 
      - datadir:/data/teamcity_server/datadir
      - logs:/opt/teamcity/logs
    ports:
      - "8111:8111"

volumes:
  mysql:
  datadir:
  logs:
我已经使用一种非常类似的技术成功地建立了wordpress,我可以运行phpMyAdmin并将其链接到MySQL容器,然后查看数据库,所以它就在那里

当我浏览到teamcity网址时,它会按预期显示初始设置屏幕。我告诉它使用MySQL,并输入'root'作为用户名和MySQL根密码。Teamcity随后显示:


我相信这很简单,但我就是看不出有什么不对。有什么想法吗?

解决了!以下是我的解决方案和一些其他经验教训

问题是我告诉TeamCity使用“localhost”作为数据库服务器URL。这看起来很直观,因为所有服务都在同一台机器上,但这是不正确的。这就好像每个容器都是自己的主机,因此“localhost”是每个容器特有的容器中的localhost是指容器本身,而不是主机或任何其他容器。所以teamcity服务上的“localhost”指的是teamcity服务器,而不是数据库服务器,这就是它无法连接的原因

基于我的
docker compose.yml
文件,数据库服务器的正确地址是
db
(数据库容器的服务名称)。服务名称将成为该容器的主机名,docker将这些名称正确解析为组合组中的DNS名称

另请注意:
default
虚拟网络由
docker compose
隐式创建,并允许组合组中的所有容器相互通信。这个网络的名称来自
docker compose.yml
文件所在的文件夹(在我的例子中是
~/projects/teamcity
),因此我得到了一个名为
teamcity\u default
的网络。此专用虚拟网络上的所有服务器彼此可见,无需进一步配置


teamcity
服务器容器在主机的网络接口上显式公开端口
8111
,因此它是外部世界唯一可见的容器。如果只需要服务器相互通信,则不需要(也可能不应该)公开端口。例如,数据库服务器不需要有
ports
条目,因为它是在专用容器间网络上自动公开的。这对安全性非常重要,因为所有后端服务都隐藏在物理LAN和Internet之外。

解决了!以下是我的解决方案和一些其他经验教训

问题是我告诉TeamCity使用“localhost”作为数据库服务器URL。这看起来很直观,因为所有服务都在同一台机器上,但这是不正确的。这就好像每个容器都是自己的主机,因此“localhost”是每个容器特有的容器中的localhost是指容器本身,而不是主机或任何其他容器。所以teamcity服务上的“localhost”指的是teamcity服务器,而不是数据库服务器,这就是它无法连接的原因

基于我的
docker compose.yml
文件,数据库服务器的正确地址是
db
(数据库容器的服务名称)。服务名称将成为该容器的主机名,docker将这些名称正确解析为组合组中的DNS名称

另请注意:
default
虚拟网络由
docker compose
隐式创建,并允许组合组中的所有容器相互通信。这个网络的名称来自
docker compose.yml
文件所在的文件夹(在我的例子中是
~/projects/teamcity
),因此我得到了一个名为
teamcity\u default
的网络。此专用虚拟网络上的所有服务器彼此可见,无需进一步配置

teamcity
服务器容器在主机的网络接口上显式公开端口
8111
,因此它是外部世界唯一可见的容器。如果只需要服务器相互通信,则不需要(也可能不应该)公开端口。例如,数据库服务器不需要有
ports
条目,因为它是在专用容器间网络上自动公开的。这对安全性非常重要,因为所有后端服务都隐藏在物理LAN和Internet之外