V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hansonwang99
V2EX  ›  推广

SpringBoot 应用 Docker 化

  •  
  •   hansonwang99 · 2018-04-12 09:04:44 +08:00 · 4319 次点击
    这是一个创建于 2447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Surface Studio


    概述

    当下 web 服务端开发中最火的名词中绝对有微服务的一席之地,其也成为当下互联网后端服务架构演进历程中最闪亮的技术之一。微服务的基本思想在于考虑围绕着业务领域组件来创建应用,这些应用可独立地进行开发、管理和加速。在分散的组件中使用微服务云架构和平台,使部署、管理和服务功能交付变得更加简单。既然服务被分割和微小化了,我们很容易想到如果将其和 docker 结合,让 docker 承载着一个个的微服务运行,如此一来将会让服务间耦合度降低,部署简洁,同时系统的架构也更加清晰,便于长期演进,基于此想法有了这篇文章的入门实践!


    创建基于 maven 的 spring bt 项目

    • pom.xml 中加依赖:
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
    
    <dependencies>
    
         <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
    </dependencies>
    
    • 我们只需要在启动类中添加一个简单的 restful 接口就行了,为了后续浏览器能验证一下,访问 /hello 接口,能向浏览器返回一个 Hello Docker !的问好!
    @RestController
    public class DockerDemoSpringApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DockerDemoSpringApplication.class, args);
        }
    
        @RequestMapping("/hello")
        public String hello(){
            return "Hello! Docker!”;
        }
    }
    

    编写 Dockerfile

    我们在 Spring Bt 项目的根目录下建立 Dockerfile,用起来完成 Docker 镜像构建的编排:

    FROM maven:3.3.3
    
    ADD pom.xml /tmp/build/
    
    RUN cd /tmp/build && mvn -q dependency:resolve
    
    ADD src /tmp/build/src
            #构建应用
    RUN cd /tmp/build && mvn -q -DskipTests=true package \
            #拷贝编译结果到指定目录
            && mv target/*.jar /app.jar \
            #清理编译痕迹
            && cd / && rm -rf /tmp/build
    
    
    VOLUME /tmp
    EXPOSE 8080
    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar ”]
    

    进入 Docker 的世界

      1. 在 Spring 项目根目录下根据 Dockerfile 来生成 docker 镜像

    docker build -t springindocker .

      1. 从刚创建的镜像来启动容器

    docker run -d -p 8080:8080 springindocker

      1. 打开浏览器,或者使用 curl 访问http://127.0.0.1:8080就可以看到 web 服务器里返回的Hello Docker!!!问好的字符了

    至此就说明你成功将一个基于 Spring Boot 的应用 Docker 化了。

    本文虽然只是以一个 Demo,但一个大型的 web 项目无非也就是由诸多这种 Rest 服务,外加各种基础设施、数据库、通信、中间件以及调度来构成,每个子元素的开发也依然遵循这里的基本流程。


    后记

    作者更多的 SpringBt 实践文章在此:


    CodeSheep

    21 条回复    2018-04-12 21:57:30 +08:00
    lingoJay
        1
    lingoJay  
       2018-04-12 09:11:55 +08:00 via iPhone
    学习
    mritd
        2
    mritd  
       2018-04-12 09:13:26 +08:00 via iPhone   ❤️ 1
    这个 dockerfile 写的很不好
    WispZhan
        3
    WispZhan  
       2018-04-12 09:15:19 +08:00
    换 Gradle 吧,Maven 的插件太蛋疼。
    salmon5
        4
    salmon5  
       2018-04-12 09:17:07 +08:00 via Android
    距离世纪情况还很远啊
    配置和日志呢
    letitbesqzr
        5
    letitbesqzr  
       2018-04-12 09:21:30 +08:00
    说实话,实例少的情况,用 docker 只会自找麻烦。
    monsterxx03
        6
    monsterxx03  
       2018-04-12 09:21:41 +08:00 via iPhone
    这也太水了,好歹弄个 multi stage 吧
    mritd
        7
    mritd  
       2018-04-12 09:26:12 +08:00 via iPhone
    @letitbesqzr 单实例 日常 docker,ci 调整好就行了 https://mritd.me/2017/11/28/ci-cd-gitlab-ci/
    mritd
        8
    mritd  
       2018-04-12 09:28:05 +08:00 via iPhone
    @salmon5 实际生产没有他这种手撸 dockerfile 的,日志肯定走集群收集,配置一般配置中心,也可以挂载
    woscaizi
        9
    woscaizi  
       2018-04-12 09:29:38 +08:00
    这其实是简化了 springboot serverport 的设置吧。
    毕竟 springboot 可以直接打成 jar 包 java -jar 运行。
    woscaizi
        10
    woscaizi  
       2018-04-12 09:30:14 +08:00
    springboot 项目 docker 化有意义吗?(询问的语气,不是反问)
    yuanfnadi
        11
    yuanfnadi  
       2018-04-12 09:33:16 +08:00
    FROM gradle as build

    ADD ./ /tmp/

    RUN cd /tmp && \
    gradle build

    FROM java:8-jre-alpine

    ENV TZ=Asia/Shanghai
    RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

    COPY --from=build /tmp/build/libs/*.jar /srv/
    CMD ["java", "-jar", "/srv/tmp-0.0.1-SNAPSHOT.jar"]



    需要多步构建 时区也要注意。
    rockyou12
        12
    rockyou12  
       2018-04-12 09:46:32 +08:00 via Android
    @woscaizi 有 docker 不用管 jre 多版本问题,而且你要是想用 k8s 之类的做服务治理还是必须 docker 化的
    th00000
        13
    th00000  
       2018-04-12 10:07:21 +08:00
    按照楼主的这个写法, docker 应该会创建两层镜像吧
    而且第一层重用的可能性感觉很低
    不知道是不是这样
    ittianyu
        14
    ittianyu  
       2018-04-12 10:22:09 +08:00
    不用 gradle 竟然还在用笨重的 maven,差评+1
    Mogugugugu
        15
    Mogugugugu  
       2018-04-12 10:35:48 +08:00
    为什么编译要用 docker 去做?
    qinxi
        16
    qinxi  
       2018-04-12 11:41:15 +08:00
    @yuanfnadi 哈哈哈哈哈 我也想吐槽居然不改时区..还是年轻啊...以为跑起来就行了
    aa6563679
        17
    aa6563679  
       2018-04-12 11:50:54 +08:00 via iPhone
    @woscaizi serverport 可以设个 0 自动生成
    STRRL
        18
    STRRL  
       2018-04-12 11:51:32 +08:00 via Android
    Maven 插件了解一下
    znood
        19
    znood  
       2018-04-12 13:35:19 +08:00 via iPhone
    这 docker 用法给两分
    beginor
        20
    beginor  
       2018-04-12 18:56:06 +08:00 via Android
    @znood 我觉得只能给 1 分,算是熟悉 dockerfile 怎么写,build 环境没必要在 docker 里面
    henneko
        21
    henneko  
       2018-04-12 21:57:30 +08:00 via Android
    docker 是为 app 服务的,“ docker 化”这个词让人觉得是本末倒置
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2853 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:36 · PVG 22:36 · LAX 06:36 · JFK 09:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.