Dockerfile配置MySQL镜像时JDBC连接URL访问报错如何解决
问题根因
你当前的配置存在3个核心错误,直接导致数据库连接失败:
- 你写的Dockerfile是多阶段构建结构,只有最后一个
FROM openjdk:8-jdk-alpine开始的内容会被打包进最终镜像,前面配置的MySQL相关内容全部不会生效,最终运行的容器里根本没有MySQL进程 - 即便你把MySQL和Java应用打包进同一个镜像,当前
ENTRYPOINT只配置了启动Java应用的命令,MySQL服务不会自动启动,localhost:3307上根本没有监听服务 - MySQL 5.7官方镜像默认监听端口是
3306,你只写EXPOSE 3307不会修改MySQL的实际监听端口,只是个无实际作用的端口标记
修复步骤
按照Docker容器单进程的最佳实践,把Java应用和MySQL拆成两个独立容器,通过自定义网络互联即可,操作如下:
修改JDBC连接配置
不要写localhost作为数据库地址,容器互联通过服务名寻址,同时把端口改回MySQL默认的3306:url: jdbc:mysql://mysql:3306/test-db username: root password: yum-hai-hum这里的
mysql是后续给MySQL容器设置的名称,Docker内置DNS会自动把这个域名解析到MySQL容器的内部IP精简Java应用的Dockerfile
删掉所有MySQL相关的配置,Java镜像只负责打包应用即可:FROM openjdk:8-jdk-alpine ARG JAR_FILE=build/libs/*.war COPY ${JAR_FILE} app.war ENTRYPOINT ["java","-jar","/app.war"]重新构建Java应用镜像
docker build -t="navin/java-app" .创建自定义桥接网络,供两个容器通信
docker network create app-net启动MySQL容器
把初始化SQL、数据库密码、初始库名参数都传给MySQL容器,加入刚创建的网络,设置容器名为mysql和JDBC配置里的地址对应:docker run -d \ --name mysql \ --network app-net \ -e MYSQL_ROOT_PASSWORD=yum-hai-hum \ -e MYSQL_DATABASE=test-db \ -p 3307:3306 \ -v $(pwd)/test-db.sql:/docker-entrypoint-initdb.d/test-db.sql \ mysql:5.7启动后等待10-15秒让MySQL完成初始化,再启动Java应用,避免应用启动时数据库还没就绪。这里的
-p 3307:3306是把宿主机3307端口映射到MySQL容器的3306端口,仅用于你本地客户端连接数据库用,Java应用走容器内部网络通信不需要依赖这个映射。启动Java应用容器,加入同一个网络
docker run -d \ --network app-net \ -e "SPRING_PROFILES_ACTIVE=dev" \ -p 8080:8084 \ navin/java-app
启动完成后就能正常连接数据库了。
内容的提问来源于stack exchange,提问作者Navin Gelot
相关产品推荐
相关产品推荐

