Skip to content

使用Dockerfile为SpringBoot应用构建Docker镜像

使用Jar包部署

编写Dockerfile文件

dockerfile
# 该镜像需要依赖的基础镜像
FROM java:8
# 将当前目录下的jar包复制到docker容器的/目录下
ADD mall-tiny-docker-file-0.0.1-SNAPSHOT.jar /mall-tiny-docker-file.jar
# 运行过程中创建一个mall-tiny-docker-file.jar文件
RUN bash -c 'touch /mall-tiny-docker-file.jar'
# 声明服务运行在8080端口
EXPOSE 8080
# 指定docker容器启动时运行jar包
ENTRYPOINT ["java", "-jar","/mall-tiny-docker-file.jar"]
# 指定维护者的名字
MAINTAINER macrozheng
dockerfile
# 用jdk容器执行这个程序
FROM openjdk:8
# 作者
MAINTAINER XiaoHH <1431984546@qq.com>
# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp
# 将可执行的jar包放到容器当中去
ADD target/xiaohh-cost-1.0.0.jar app.jar
# 暴露服务端口
EXPOSE 8080
# 暴露日志目录,Java程序运行的错误日志就在这个里面
VOLUME '/logs'
# 运行时的环境
ENV SPRING_PROFILES_ACTIVE="prod"
# JVM 调优参数
ENV JAVA_OPTION="-Dfile.encoding=UTF-8 -Xmx512m -Xms512m -Xmn256m -XX:+UseParallelGC -XX:+PrintGCDetails -XX:+PrintGCCause -XX:+PrintHeapAtGC -Xloggc:/logs/xiaohh-cost.gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC"
# 运行程序
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["sh", "-c", "java -Djava.security.egd=file:/dev/./urandom -jar $JAVA_OPTION /app.jar"]

使用war包部署

https://blog.csdn.net/lanren312/article/details/123469227

修改打包方式,默认是jar包,加了才是war包

xml
<packaging>war</packaging>

排除内置的tomcat

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--去掉SpringBoot内置的tomcat, jar包需要去掉-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

添加tomcat依赖,或者添加servlet-api依赖,二者用其一,本人使用是添加tomcat依赖

xml
<!-- 这里指定打war包的时不再需要tomcat相关的包,但是本地运行时必须注释掉,否则会报错-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
     <version>8.0.36</version>
     <scope>provided</scope>
</dependency>

<!-- 添加servlet-api的依赖-->
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-servlet-api</artifactId>
    <version>8.5.56</version>
    <scope>provided</scope>
</dependency>

主类继承SpringBootServletInitializer,重写configure方法..(ps:HeroesApplication是我的项目启动类,需要根据自己的项目修改)

public class HeroesApplication extends SpringBootServletInitializer{
 
    public static void main(String[] args) {
        SpringApplication.run(HeroesApplication.class, args);
    }
 
    /**
     * 需要把web项目打成war包部署到外部tomcat运行时需要改变启动方式
     *
     */
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(HeroesApplication.class);
    }

重新写一个类 SpringBootStartApplication,和HeroesApplication平级,HeroesApplication可以不做更改,这个方法更方便,推荐用这个

public class SpringBootStartApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        // 注意这里要指向原先用main方法执行的Application启动类
        return builder.sources(HeroesApplication.class);
    }
}

问题分析

1、本地开发登录地址 http:localhost:30000/heroes/login,部署Tomcat后yml文件中配置的port会失效,登录地址应该是 http:localhost:8080/heroes/login;

上篇博客提到登录地址一致是 http:localhost:8080/heroes/heroes/login,是因为没有在server.xml 中配置,登录也有问题,因为多了一个/heroes

2、在配置server.xml时如果不将appBase设置为空,访问地址是 http:localhost:8080/heroes/heroes/login,并且tomcat启动了两次 3、如果docBase地址写错,就会报错

Dockerfile

$CATALINA_HOME/webapps表示Tomcat的部署目录。对于官方的Docker镜像,CATALINA_HOME/usr/local/tomcat,因此完整的部署目录将是/usr/local/tomcat/webapps

dockerfile
FROM tomcat:9.0.53-jdk11-openjdk
# 设置环境变量
ENV JAVA_OPTS="-Xms512m -Xmx1024m"
# 复制WAR包到Tomcat的webapps目录
COPY your-app.war /usr/local/tomcat/webapps/
# 暴露Tomcat默认的8080端口
EXPOSE 8080
# 启动Tomcat
CMD ["catalina.sh", "run"]