第一次通过docker部署java服务的全过程

 更新时间:2026年03月13日 11:00:34   作者:爱读书的普通程序员  
这篇文章主要介绍了第一次通过docker部署java服务的相关资料,在这个过程中,我们将从基础开始,逐步深入到Docker镜像的构建和Java项目的部署,文中通过代码及图文介绍的非常详细,需要的朋友可以参考下

为什么要学习docker

今天在网上学习项目时,讲到可以在本机装docker部署服务,也可以在服务器上使用docker部署。我对docker一无所知,哪怕是看项目的视频讲解也是一知半解,搞了一上午,连依葫芦画瓢都不会。于是,为了避免复杂项目对docker学习的影响,下午用了一个最简单的用户crud项目来进行学习,最终将服务部署在docker上,成功调用了接口。

docker的优势

网上有很多的说明,这里大概讲一下自己的理解。

第一,docker类似于一个可以随时开关和添加删除的虚拟机,我们可以在虚拟机里装各种环境,比如jdk、mysql、redis等等。如果哪天不需要了,直接删除虚拟机即可,避免对主机进行各种下载配置,容易出问题,且清理不干净

第二,这套部署好的环境是可移植的,也就是如果换了一个电脑,可以直接把这套docker部上去就能用,避免反复在电脑上各种配置环境,同样,它也可以方便的移植到云服务器上。这个有点像U盘的功能。

前期准备

需要本地先下载docker再进行,其他老生常谈。

项目结构

src/
├── main/
│   ├── java/com/example/demo/
│   │   ├── controller/UserController.java
│   │   ├── mapper/UserMapper.java
│   │   ├── model/User.java
│   │   └── DockerDemoApplication.java
│   └── resources/
│       ├── application.yml
|       ├── application-dev.yml
|       ├── application-docker.yml
│       └── mybatis/mapper/UserMapper.xml
Dockerfile
docker-compose.yml
init.sql

业务代码

业务就是写了个用户类,通过controller和mapper对用户进行crud,主要是为了测试mysql在docker上的部署。init.sql是建表语句。

配置类application.yml

使用docker部署服务和mysql,第一个注意点在于三个application配置文件。application.yml配置各个环境共有的配置,而application-dev.ymlapplication-docker.yml仅声明不同值的配置项。详细见如下:

# application.yml
server:
  port: 8080

spring:
  profiles:
    active: dev
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: 111
    username: 111
    password: 111

mybatis:
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    
    
# application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
    username: root
    password: 123456
    

# application-docker.yml
spring:
  datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}

首先看application.yml,里面有全量的配置项,可以通过修改spring.profiles.active的值来对不同环境的值进行生效。如当配置为dev时,url、username、password的值会被替换为application-dev.yml对应的配置项值。

application-docker.yml的值均为占位符,这个占位符来自于docker相关的配置项。当使用docker部署java服务时,这些值会被替换掉。详细见下面的分析。

Dockerfile

Dockerfile用于构造单个容器,比如这里就是构造java容器。

FROM openjdk:8-jdk # 使用jdk8的镜像
WORKDIR /app # 设置容器的工作目录为app,可以随意命名
COPY target/*.jar app.jar # 将jar包拷贝到app目录之下
EXPOSE 8080 # 容器的服务端口为8080
CMD ["java", "-jar", "app.jar"] # 容器启动时执行的命令:运行Java应用

docker-compose.yml

docker-compose用于多个容器的构造和编排,比如当服务涉及前端、后端、mysql等多个容器时,可以定义其构造关系。本样例仅涉及java和mysql两个容器,java的启动依赖于mysql,也就是只有mysql容器起来后才能构造java。

具体配置如下:

version: '3.8'

services:
  mysql:
    image: mysql:8.0 # docker的mysql版本
    container_name: mysql-container # 容器名称
    environment: # root账号信息,涉及的数据库
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: testdb
    ports: # 端口,前面为暴露到公网的端口(与主机公用),后面为docker内部占用的端口
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot" ]
      interval: 5s
      timeout: 10s
      retries: 20

  app:
    build: .
    container_name: app-container
    depends_on: # 添加依赖关系
      mysql:
        condition: service_healthy
    ports:
      - "8080:8080"
    environment: # 环境变量,这里与application-docker.yml进行呼应,且需要与上面的mysql信息一致(登陆账号信息)
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/testdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: 123456
    links:
      - mysql

volumes:
  mysql-data:

全docker启动

上述配置好,即可将服务和mysql用docker启动。点击docker-compose.ymlservices左边的按钮即可。

在docker客户端上也可以看到相关执行情况。

通过postman请求本地的接口,可以看到请求成功。

架构图大致长这样

怎么debug?

将服务部署在docker后,可以测试,也可以通过docker查看日志等信息,但问题在于,我想debug怎么办呢?

在不使用docker的情况下,是在idea上点击SpringBootApplication来启动服务的,并且可以选择debug模式。如果用idea启动了java服务,那mysql服务怎么办,以及java服务怎么访问mysql?

答案是这样的:docker-compose.yml包括了两个容器的启动,可以选择仅启动mysql,只需要点击mysql 左边的按钮即可。而java服务按照原来的方式去启动,只不过这里要注意,spring.profiles.active需要改为dev,并按照上述配置文件,配置好mysql连接串、账号信息即可。

架构图是这样

踩坑点

mysql端口与主机冲突

之前提到,mysql容器配置的端口为3306:3306,前面的端口会和主机共享。所以如果主机本就安装了mysql并且启动了,需要把mysql停掉,否则mysql容器部署会失败,因为默认就是这个端口。(或者换一个端口部署)

添加数据时服务报错:表不存在

mysql部署成功后,需要登陆docker进入mysql,手动创建需要的表,否则在插入表时会报错,因为表不会自动创建。应该还有别的方式,比如在mysql启动时,可以关联init.sql文件进行sql执行,不过这需要考虑之前的表数据是否会清空或者发生冲突的问题,这块还没有仔细研究。

【重要】默认的镜像源无法下载镜像(403 forbidden)

部署mysql容器时,镜像拉不下来,搜索后发现要修改镜像源,参考:status.1panel.top/status/dock…

也可以在docker客户端手动修改:

尾声

有三点想说的:

  • 本次的docker学习完全靠deepseek来进行,全程几乎没有查阅其他资料;
  • 本次学习仅停留在简单的demo实现层面,关于docker还有很多花式操作以及原理,还需要日后涉及到再学习;
  • 学习方法总结:要控制变量法的学习,比如学习docker,就不能和很复杂的项目相结合,项目只是一个学习docker的依托,一定要越简单越好。

到此这篇关于通过docker部署java服务的文章就介绍到这了,更多相关docker部署java服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • maven异常Invalid bound statement(not found)的问题解决

    maven异常Invalid bound statement(not found)的问题解决

    本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • Java 抽象类特点总结

    Java 抽象类特点总结

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
    2021-10-10
  • mybatis.type-aliases-package的作用及用法说明

    mybatis.type-aliases-package的作用及用法说明

    这篇文章主要介绍了mybatis.type-aliases-package的作用及用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • JAVA实现微信APPV3支付保姆级教程

    JAVA实现微信APPV3支付保姆级教程

    微信实现支付功能与支付宝实现支付功能是相似的,这篇文章主要介绍了JAVA实现微信APPV3支付的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 使用Java实现加密之AES加解密

    使用Java实现加密之AES加解密

    这篇文章主要介绍了使用Java实现加密之AES加解密,AES为最常见的对称加密算法,对称加密算法也就是加密和解密用相同的密钥,需要的朋友可以参考下
    2023-05-05
  • SpringBoot中动态数据源配置与使用详解

    SpringBoot中动态数据源配置与使用详解

    在现代应用中,处理多数据源是常见的需求,在 Spring Boot 中,这样的需求可以通过动态数据源来轻松实现,本篇博客将详细介绍如何在 Spring Boot 中配置和使用动态数据源,并演示如何切换到指定的数据源,需要的朋友可以参考下
    2024-10-10
  • java实时监控文件行尾内容的实现

    java实时监控文件行尾内容的实现

    这篇文章主要介绍了java实时监控文件行尾内容的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • springboot 自定义权限标签(tld),在freemarker引用操作

    springboot 自定义权限标签(tld),在freemarker引用操作

    这篇文章主要介绍了springboot 自定义权限标签(tld),在freemarker引用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 基于java实现websocket代码示例

    基于java实现websocket代码示例

    这篇文章主要介绍了基于java实现websocket代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • Java死锁和活锁的联系及说明

    Java死锁和活锁的联系及说明

    这篇文章主要介绍了Java死锁和活锁的联系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05

最新评论