我有以下docker-compose.yml
<dependencyManagement>
我的应用程序服务需要连接到数据库,并使用我尝试使用服务名称“ db”连接的文档(从应用程序容器中)
version: '3'
services:
app:
build: .
network_mode: host
volumes:
- .:/usr/usr/src/app
db:
image: mysql/mysql-server:5.7
environment:
MYSQL_DATABASE: config_dev
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
restart: always
ports:
- "1200:3306"
但是,出现错误mysql --hostname=db --port=3306 --user=root
我在做什么错了?
答案 0 :(得分:1)
您的app
容器正在与network_mode: host
一起运行。如果它正在使用主机网络,则它不能使用任何特定于Docker的网络功能;例如,它不能通过主机名访问其他容器,也不能通过主机名访问。对于Docker网络而言,它与主机上运行的进程没有区别。
对于我在SO上建议的大多数情况,主机联网实际上不是必需的,并且如果您删除该行,则应查看您的应用程序是否有效。您可能需要添加ports:
才能从外部对其进行访问。
如果您确实无法禁用主机联网,则需要通过其他容器的已发布端口以与运行在Docker网络空间之外的其他进程相同的方式连接到数据库。主机名localhost
应该可以工作(因为您处于主机上下文中),但是需要映射的端口号--port=1200
。
答案 1 :(得分:1)
由于network_mode: host
,您的应用程序容器实际上位于docker的专用网络上,例如192.168.65.1/24,而您的数据库容器位于docker-compose创建的另一个专用网络上,例如172.20.0.2/16。运行docker-compose down时,您会看到此网络已删除:
Removing network XXXX_default
其中XXXX是您的目录名称。
如果您要从服务应用中删除network_mode: host
,则两个容器将位于同一专用网络上,并可以通过其服务名称访问。
$ docker inspect XXXX_default
"Containers": {
...
"Name": "app",
"IPv4Address": "172.21.0.3/16",
...
},
...
"Name": "db",
"IPv4Address": "172.21.0.2/16",
...
}
},
应用程序容器可以访问端口3306上的数据库。无需将端口公开为1200。根据文档:
连接到同一用户定义网桥网络的容器 自动将所有端口公开给彼此,而没有端口公开给 外面的世界。这允许容器化的应用程序进行通信 彼此之间轻松互通,而不会意外打开对 外部世界。
答案 2 :(得分:0)
在“应用”部分添加链接配置
version: '3'
services:
app:
build: .
network_mode: host
volumes:
- .:/usr/usr/src/app
links:
- db
db:
image: mysql/mysql-server:5.7
environment:
MYSQL_DATABASE: config_dev
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- ./docker/images/config-dev-image/sql-scripts:/docker-entrypoint-initdb.d
restart: always
ports:
- "1200:3306"