You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot容器无法通过Docker容器名连接MariaDB的问题

问题描述

我有一个连接MariaDB数据库的Spring Boot应用,尝试用docker-compose部署时出现以下错误:

java.sql.SQLNonTransientConnectionException: Socket fail to connect to host:address=(host=maria_db)(port=10000)
(type=primary). maria_db
...
Caused by: java.net.UnknownHostException: maria_db

相关配置文件如下:

docker-compose.yml

version: "3.7"
services:
  api_service:
    build: .
    restart: always
    ports:
      - "8080:8080"
    depends_on:
      - maria_db
  maria_db:
    image: "mariadb:10.5.8"
    restart: always
    ports:
      - "10000:3306"
    environment:
      MYSQL_DATABASE: app_db
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_ROOT_PASSWORD: examplepass

Spring应用Dockerfile

FROM openjdk:17-oracle
COPY target/app-0.0.1.jar app-0.0.1.jar
RUN ["java","-jar","/app-0.0.1.jar"]

application.properties

spring.datasource.url=jdbc:mariadb://maria_db:10000/app_db
spring.datasource.username=exampleuser
spring.datasource.password=examplepass
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
springdoc.api-docs.path = /javainuse-openapi

使用版本信息:

  • Spring Boot 3.0.2
  • Java 17
  • Docker Engine v20.10.22(Docker Windows)

作为Docker新手,按资料配置仍报错,请问哪里操作有误?


错误分析与修复方案

你的问题集中在三个关键配置错误上:

1. Dockerfile启动指令错误

Dockerfile中使用RUN指令启动jar包,这会在镜像构建阶段执行启动命令——此时容器网络尚未创建,根本无法解析maria_db这个主机名,必然报错。

修复:将RUN替换为CMD(容器启动时执行的命令):

FROM openjdk:17-oracle
COPY target/app-0.0.1.jar app-0.0.1.jar
CMD ["java","-jar","/app-0.0.1.jar"]

2. 数据库连接端口错误

Docker Compose同一网络内的服务通信,直接使用容器内部端口即可,无需用宿主机映射的端口。MariaDB容器内部默认端口是3306,你映射了宿主机10000端口到容器3306,但Spring应用连接时应该用容器内部的3306,而非10000。

修复:修改application.properties中的数据库URL:

spring.datasource.url=jdbc:mariadb://maria_db:3306/app_db

3. depends_on的局限性

depends_on仅保证容器的启动顺序,不保证数据库服务完全初始化就绪。Spring应用启动时,可能数据库还没完成初始化,导致连接失败。

修复方案(二选一):

  • 给Spring应用添加连接重试机制,在application.properties中追加:
    spring.datasource.hikari.connection-timeout=60000
    spring.datasource.hikari.maximum-pool-size=5
    spring.datasource.hikari.validation-timeout=3000
    spring.jpa.properties.hibernate.connection.provider_disables_autocommit=true
    
  • 在docker-compose中添加健康检查,让API服务等待数据库就绪后再启动:
    api_service:
      build: .
      restart: always
      ports:
        - "8080:8080"
      depends_on:
        maria_db:
          condition: service_healthy
    maria_db:
      image: "mariadb:10.5.8"
      restart: always
      ports:
        - "10000:3306"
      environment:
        MYSQL_DATABASE: app_db
        MYSQL_USER: exampleuser
        MYSQL_PASSWORD: examplepass
        MYSQL_ROOT_PASSWORD: examplepass
      healthcheck:
        test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pexamplepass"]
        interval: 5s
        timeout: 5s
        retries: 10
    

内容的提问来源于stack exchange,提问作者MilanJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:09:29