一、拉取MySQL镜像,并启动镜像对应的容器
由于上一篇文章实现了拉取jdk8的环境,同时将jar包打成了一个镜像。但是要想真正的把项目运行起来(此处仅以单体项目为例)还需要MySQL的容器提供数据支持(当然这里面方法有多种,可以将两个环境分别放在两个容器中,也可以直接放到一个容器中实现,但秉承着一个容器只放一个环境的原则,Docker 官方也是推荐将多个环境放置到多个容器中的)。所以本例则是使用两个容器分开配置,进行项目的部署。
这里我已经pull好了,方法跟pull jdk 8一样。
启动容器,这里面写法看到有的文章采用这个写法
docker run -it --network my-net -p 3306:3306 --name mysqld -d mysql
但是此处我是使用的是另外一个写法(其实都一样)
docker run -it --network my-net --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
启动成功
二、实现两个容器互相访问(容器间的通信)
但是当放到多个容器中,又会出现一个问题,我的 API 服务该怎么访问 MySQL、Redis 呢?有三种办法可以解决。
- 通过容器内 ip + 映射出的端口进行访问(不推荐)
- 通过
--link
链接另一个容器访问(不推荐,即将废弃,原理就不描述了)--link
只能在docker run
一个容器时链接另一个已运行的容器,所以说该方法只能单向访问。 - 通过
network
将两个容器链接到同一个network
中可以进行双向访问
此处我使用的是第三种方法:
即Docker Network 有多种驱动模式,默认为 bridge,桥接模式。bridge network 原理是在新建 network 时建立一个 bridge(即容器外的一个 Linux 网络接口,通过 ip a
命令可以查看),所有加入此 network 的容器会通过容器内部的网络接口与外部的 bridge 接口的 veth interface 相连,这样,network 内容器间需要彼此通信时就可以通过 bridge 进行转发。每一个 bridge network(包含其下的容器)都有一个独立的 IP 网段,不同网段间的容器无法通信,这也就是指定 bridge network 进行容器间网络隔离的原理。
具体来说,这里有几个地方需要修改:
①、yml文件
密码要改成MySQL容器对应的的密码(也是连接navicat对应数据库的密码),尽量不要写172.18.0.3这样的ip地址,有可能会变,后面存在问题,就直接写名字。
docker exec -it appds sh
②、docker network ls
自定义创建的网络可以通过容器名进行通信
docker network create NAME
docker network inspect my-net
docker network create my-net
三、将项目运行起来(踩坑总结)
错误①:The container name "/mysql-test" is already in use by container
在这里使用到了
lsof -i:3306
kill -15
kill -9
netstat -an|grep 3306
错误②:(mysql)容器删除后,没有重新导入数据进去
容器一旦删除,之前配置数据库,和里面的数据也都没了,记得要重新导入
错误③:No chain/target/match by that name.
遇到这个问题可以尝试重启docker
systemctl restart docker
最后,把两个容器都run起来的时候,可以通过日志看到项目运行的状态。
docker logs appd
在虚拟机内部访问:(直接localhost没有问题,当然你用IP地址直接访问也可以)
在外部浏览器访问:(这里就不能用localhost了!!!,只能用虚拟机的IP地址)