Docker化Java应用无法连接MySQL容器问题求助
问题描述
本地运行Java应用时,能正常连接MySQL容器;但将Java应用Docker化后,无法建立数据库连接。
相关配置
MySQL容器Docker Compose配置
version: '2' services: mysql: image: mysql:latest ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORD=$DB_ROOT_PWD - MYSQL_DATABASE=$DB_NAME - MYSQL_USER=$DB_USER - MYSQL_PASSWORD=$DB_PWD volumes: - msql-data:/var/lib/msql volumes: msql-data: driver: local
Java应用数据库配置
@Configuration public class DatabaseConfig { private String user = System.getenv("DB_USER"); private String password = System.getenv("DB_PWD"); private String serverName = System.getenv("DB_SERVER"); // db host name, like localhost without the port private String dbName = System.getenv("DB_NAME"); private MysqlDataSource datasource = new MysqlDataSource(); public DatabaseConfig() { datasource.setPassword(password); datasource.setUser(user); datasource.setServerName(serverName); datasource.setDatabaseName(dbName); //datasource.setPort(3306) default config //datasource.setURL("jdbc:mysql://localhost:3306/dbname"); } }
Java应用Dockerfile配置
FROM openjdk:8-jdk-alpine ENV DB_USER=$user \ DB_NAME=$db_name \ DB_SERVER=$server_location \ DB_PWD=$user_pwd RUN mkdir -p /app/ COPY java_app.jar /app/app.jar EXPOSE 8080 CMD ["java","-jar","/app/app.jar"]
镜像构建与容器启动命令
- 构建镜像:
docker build -t my-app:1.0 --build-arg user=$DB_USER --build-arg db_name=$DB_NAME --build-arg server_location=$DB_SERVER --build-arg user_pwd=$DB_PWD . - 启动容器:
docker run --name=app -tid app:1
问题分析与解决方案
核心问题
Docker容器拥有独立的网络命名空间,当Java应用容器内的DB_SERVER配置为localhost时,实际指向的是容器自身,而非宿主机上的MySQL容器,这就是连接失败的原因。
解决方案
方案1:用Docker Compose统一编排服务(推荐)
将Java应用和MySQL容器放在同一Docker网络中,直接用MySQL服务名作为数据库主机地址。修改后的Docker Compose配置如下:
version: '2' services: mysql: image: mysql:latest ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORD=$DB_ROOT_PWD - MYSQL_DATABASE=$DB_NAME - MYSQL_USER=$DB_USER - MYSQL_PASSWORD=$DB_PWD volumes: - msql-data:/var/lib/mysql # 修复原配置中路径拼写错误(msql -> mysql) app: build: . environment: - DB_USER=$DB_USER - DB_NAME=$DB_NAME - DB_SERVER=mysql # 使用MySQL服务名作为主机地址 - DB_PWD=$DB_PWD ports: - 8080:8080 depends_on: - mysql volumes: msql-data: driver: local
执行命令启动所有服务:docker-compose up -d
方案2:使用宿主机内网IP作为数据库地址
查看宿主机的内网IP(Linux用ip addr,Windows用ipconfig),将DB_SERVER设置为该IP值,再构建Java应用镜像并启动容器。注意不能用localhost或127.0.0.1,因为容器内的回环地址指向自身。
方案3:使用host网络模式(不推荐)
启动Java容器时添加--network host参数,让容器共享宿主机网络:docker run --name=app --network host -tid my-app:1.0
此时DB_SERVER设为localhost即可连接,但这种方式会失去容器的网络隔离性,仅适合测试场景,不建议生产环境使用。
额外提示
原MySQL容器配置中的数据卷路径/var/lib/msql存在拼写错误,应改为/var/lib/mysql,否则无法正确持久化MySQL数据。
内容的提问来源于stack exchange,提问作者PythonOfTheMoon74
相关产品推荐
相关产品推荐

