我是docker的新手,我正在尝试将运行到我的 boot-example docker容器中的spring boot app连接到运行到我的 mymysql 的mysql服务器端口6603上的docker容器,两者都在同一台机器上运行。 事实是:如果我将我的spring-boot应用程序连接到我的 mymysql docker容器以便与数据库通信,我没有错误,一切正常。
我将弹簧启动应用程序移动到我的启动示例容器中并尝试通过Hibernate与 mymysql 容器进行通信,然后我收到这个错误:
2018-02-05 09:58:38.912 ERROR 1 --- [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
我的spring boot application.properties是:
server.port=8083
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:mysql://localhost:6603/mydockerdb
spring.datasource.username=root
spring.datasource.password=mypassword
它工作正常,直到我的春季启动应用程序在端口8082上的docker容器中运行(在正确构建docker镜像之后):
docker run -it -p 8082:8083 boot-example
答案 0 :(得分:10)
您不能在容器内使用localhost
,它是容器本身。因此,您将始终收到连接拒绝错误。
你可以做以下事情 -
在Spring Boot应用程序的application.properties
文件中添加主机IP。 (不推荐,因为它破坏了泊坞窗可移植性逻辑)
如果您想使用localhost
,请在启动容器时使用--net=host
。 (由于不存在逻辑网络层,因此不建议用于生产)
使用--links
进行与DNS名称的容器通信。的(弃用/遗留)强>
创建撰写文件&使用服务名称从spring boot app调用您的数据库,因为它们将位于同一网络和高度整合。的(推荐)强>
PS - 每当您需要将多个容器集成在一起时,请始终选择docker-compose version 3+
。使用docker run|build
了解基本面和&进行干/试运行。
答案 1 :(得分:5)
@ vivekyad4v建议 - 实现您的愿望的最简单方法是使用具有更好容器通信集成的docker-compose
。
Docker-compose是一个管理单个或多个docker容器的工具。它使用名为docker-compose.yml
的单个配置文件。
有关docker-compose的更多信息,请查看documentation和compose file reference
根据我的经验,遵循SRP(单一责任原则)是一种好习惯,因此 - 为您的数据库创建一个容器,为您的应用程序创建一个容器。它们都使用您在配置中指定的网络进行通信。
以下docker-compose.yml
示例可能会对您有所帮助:
version: '2'
networks:
# your network name
somename:
driver: bridge
services:
# PHP server
php:
image: dalten/php5.6-apache
ports:
- 80:80
volumes:
- .application_path:/some/application/path
# your container network name defined at the beggining
networks:
- somename
# Mysql server for backend
mysql:
image: dalten/mysql:dev
ports:
- 3306:3306
# The /var/lib/mysql volume MUST be specified to achieve data persistence over container restart
volumes:
- ./mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: backend
# your container network name defined at the beggining
networks:
- somename
注意:可以通过从容器内部调用service name
来实现网络内容器之间的通信。
PHP中MySQL容器的连接参数,在本例中为:
hostname: mysql
port: 3306
database: backend
user: root
password: root
答案 2 :(得分:2)
根据上述建议,Docker-compose是一种方式,但如果您不想使用compose / swarm模式。
docker network create myNet
--network myNet
jdbc:mysql://mymysql:6603/mydockerdb
通过使用docker demon的DNS解析,容器可以相互发现,因此可以进行通信。 [默认网桥不支持DNS。使用网桥的用户定义网络。]