容器化 Spring Boot 应用程序 折腾记录

140 阅读4分钟

容器化 Spring Boot 应用程序 折腾记录

编辑历史

2023-07-28 14:39,乘着掘金举办聊聊工程化Docker活动的机会,我也来整理一下我的折腾记录,如何将SpringBoot应用打包部署在我的本地主机和云服务器上

导语: 聊技术专题,争技术先锋,发布工程化docker相关原创技术文章,既有机会获得现金奖励!

2023-07-28 22时22分 继续实现

宜一键三连 志向如同okr,具体可行再坚持一下

2023-07-29 8时20分

宜摸鱼 有些人总是妄想通过宅来脱单,像是期待13月有奇迹发生

参考资料

linux.cn/article-148…

1、安装Docker

Docker 是一个快捷、轻便的系统级虚拟化技术,开发者和系统管理员可以使用它构建具备所有必要依赖项的应用程序,并将其作为一个包发布。

如何在 本机 Ubuntu 22.04 LTS 中安装 DockerDocker Compose 可以参考如下文章:linux.cn/article-148…

如何在 云服务器 Ubuntu 22.04.2 LTS 安装 Docker

1、 获取Linux发行版信息

root@hecs-139528:~# sudo lsb_release -a  
No LSB modules are available.  
Distributor ID: Ubuntu  
Description: Ubuntu 22.04.2 LTS  
Release: 22.04  
Codename: jammy  

2、使用 docker 命令,提示云服务器中没有安装Docker

root@hecs-139528:~# docker  
Command 'docker' not found, but can be installed with:  
snap install docker # version 20.10.24, or  
apt install docker.io # version 20.10.21-0ubuntu1~22.04.3  
apt install podman-docker # version 3.4.4+ds1-1ubuntu1  
See 'snap info docker' for additional versions.  
root@hecs-139528:~#  

3、安装 docker 后 使用 docker info命令查看是否安装成功

root@hecs-139528:~# docker info  
Client: Docker Engine - Community  
  
root@hecs-139528:~#  

1-2、非root用户时操作docker提示无权限解决方法

在开发项目过程中发下了提示如下错误:

ERROR: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/dockerck/_pingonnect: permission denied  

顺手记录一下我是怎么解决的

将当前用户加入 docker 组 : sudo gpasswd -a $USER docker

查看 docker.socket 配置 cat /usr/lib/systemd/system/docker.socket

可以看到以下内容

[Unit]  
Description=Docker Socket for the API  
  
[Socket]  
# If /var/run is not implemented as a symlink to /run, you may need to  
# specify ListenStream=/var/run/docker.sock instead.  
ListenStream=/run/docker.sock  
SocketMode=0660  
SocketUser=root  
SocketGroup=docker  
  
[Install]  
WantedBy=sockets.target  

使用如下命令对该文件进行编辑 sudo vim /usr/lib/systemd/system/docker.socket

我们只需修改 SocketMode0666 即可。

重新加载守护并重启socket即可

sudo systemctl daemon-reload  
  
sudo systemctl restart docker.socket  

2、搭建一个 Spring Boot Application

这部分可以看我之前的文章,就不再重复了,或者甚至可以搭建一个最简单的 Spring Boot Web 应用程序,building a REST Service (spring.io/guides/gs/r…)

但是这篇文章中我们使用之前搭建起来的项目。juejin.cn/post/726035…

3、项目回顾

看一下目前的build.gradle文件, 文件中定义了应用程序的版本是 0.0.1-SNAPSHOT

plugins {  
id 'java'  
id 'org.springframework.boot' version '2.7.14'  
id 'io.spring.dependency-management' version '1.0.15.RELEASE'  
}  
  
group = 'com.example'  
version = '0.0.1-SNAPSHOT'  
  
java {  
sourceCompatibility = '1.8'  
}  
  
repositories {  
mavenCentral()  
}  
  
dependencies {  
// https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter  
implementation group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.5.3.1'  
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui  
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.7.0'  
implementation 'org.springframework.boot:spring-boot-starter-web'  
runtimeOnly 'com.mysql:mysql-connector-j'  
compileOnly 'org.projectlombok:lombok'  
annotationProcessor 'org.projectlombok:lombok'  
testImplementation 'org.springframework.boot:spring-boot-starter-test'  
}  
  
tasks.named('test') {  
useJUnitPlatform()  
}  

看一下 application.yml 文件(部分配置)项目名称是 lkcoffee , 端口 8888

spring:  
application:  
name: lkcoffee  
  
server:  
port: 8888  

接下来使用 Gradle 构建一下项目 :正在执行 'build'

/lkcoffee/build/libs/lkcoffee-0.0.1-SNAPSHOT.jar 在项目的 build 文件夹 libs 子文件中生成了一个 jar 包: lkcoffee-0.0.1-SNAPSHOT.jar

使用命令运行项目 :java -jar build/libs/lkcoffee-0.0.1-SNAPSHOT.jar

Ctrl + C 结束项目运行

4、容器化应用程序-第一种姿势

创建 Dockerfile 文件

首先,在项目的根目录中创建一个名为 Dockerfile 的文件,Dockerfile 是用于定义 Docker 镜像的构建规则的文本文件。

Dockerfile 中添加以下内容:

# 使用基于Java 1.8的OpenJDK作为基础镜像  
FROM openjdk:8-jdk-alpine  
  
# 定义了一个构建参数 JAR_FILE,用于传递构建过程中的jar文件路径。  
# 默认情况下,它指向 target 目录下任意名称的 .jar 文件。  
ARG JAR_FILE=target/*.jar  
  
# 将构建环境中的 JAR_FILE 参数对应的 jar 文件复制到镜像中,并重命名为 lkcoffee.jar。这里是将构建的 Java 应用程序的可执行 jar 文件复制到容器中。  
COPY ${JAR_FILE} lkcoffee.jar  
  
# 暴露 Spring Boot 应用程序使用的端口号(根据你的应用程序配置进行更改)  
EXPOSE 8888  
  
# 定义启动容器时运行的命令  
ENTRYPOINT ["java","-jar","/lkcoffee.jar"]  

构建

我的项目是一个 Gradle 构建工具构建的 Spring Boot 应用

sudo docker build --build-arg JAR_FILE=build/libs/\*.jar -t coffee/lkcoffee .  

-build-arg 参数用于设置构建参数。在这里,它设置了一个名为 JAR_FILE 的构建参数,并指定了参数的值为 build/libs/*.jar。这表示构建过程中的jar文件路径为 build/libs 目录下任意名称的 .jar 文件。

-t 参数用于为构建的镜像设置标签(tag)。在这里,它将镜像命名为 coffee/lkcoffee,其中 coffee 是镜像的仓库名称,lkcoffee 是镜像的名称。

该命令会执行 Docker 构建流程,根据 Dockerfile 中的指令进行构建。通过 --build-arg 参数,将构建参数 JAR_FILE的值传递给 Dockerfile 中的 ARG 指令。然后,Docker 将根据 Dockerfile 中的指令和构建参数执行构建操作,并生成一个名为 coffee/lkcoffee 的镜像。

执行 docker images -a 命令,可以看到本地的镜像仓库中已经有了我们的 coffee/lkcoffee 镜像

REPOSITORY TAG IMAGE ID CREATED SIZE  
coffee/lkcoffee latest c7948817964e 45 seconds ago 135MB  
hello-world latest 9c7a54a9a43c 2 months ago 13.3kB  

运行 Docker 镜像

执行命令运行 Docker 镜像, 可以看到在控制台中在输出 LOG

docker run -p 8888:8888 coffee/lkcoffee

. ____ _ __ _ _  
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \  
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \  
\\/ ___)| |_)| | | | | || (_| | ) ) ) )  
' |____| .__|_| |_|_| |_\__, | / / / /  
=========|_|==============|___/=/_/_/_/  
:: Spring Boot :: (v2.7.14)  
  
2023-07-29 00:21:23.346 INFO 1 --- [ main] c.example.lkcoffee.LkcoffeeApplication : Starting LkcoffeeApplication using Java 1.8.0_212 on e283e3432898 with PID 1 (/lkcoffee.jar started by root in /)  
2023-07-29 00:21:23.349 INFO 1 --- [ main] c.example.lkcoffee.LkcoffeeApplication : No active profile set, falling back to 1 default profile: "default"  
2023-07-29 00:21:23.916 WARN 1 --- [ main] o.m.s.mapper.ClassPathMapperScanner : Skipping MapperFactoryBean with name 'userinfoMapper' and 'com.example.lkcoffee.persistence.mapper.UserinfoMapper' mapperInterface. Bean already defined with the same name!  
2023-07-29 00:21:23.916 WARN 1 --- [ main] o.m.s.mapper.ClassPathMapperScanner : No MyBatis mapper was found in '[com.example.lkcoffee.persistence.mapper]' package. Please check your configuration.  
2023-07-29 00:21:24.294 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8888 (http)  
2023-07-29 00:21:24.305 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]  
2023-07-29 00:21:24.305 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.78]  
2023-07-29 00:21:24.386 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext  
2023-07-29 00:21:24.386 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 991 ms  
_ _ |_ _ _|_. ___ _ | _  
| | |\/|_)(_| | |_\ |_)||_|_\  
/ |  
3.5.3.1  
2023-07-29 00:21:25.271 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8888 (http) with context path ''  
2023-07-29 00:21:25.280 INFO 1 --- [ main] c.example.lkcoffee.LkcoffeeApplication : Started LkcoffeeApplication in 2.303 seconds (JVM running for 2.663)  
2023-07-29 00:21:25.283 INFO 1 --- [ main] c.example.lkcoffee.LkcoffeeApplication :  
---------------------------------------------lkcoffee-----------------------------------------------------------------------  
应用 'lkcoffee' 运行成功!  
Swagger-UI-Interface 访问连接: http://172.17.0.2:8888/swagger-ui/index.html  
API-Docs 访问连接: http://172.17.0.2:8888/v3/api-docs  

5、容器话应用程序-第二种姿势

2023-07-29 08:20 ,待补充

6、可能会踩到的坑

2023-07-28 23时41分 遇见了如下错误,这个原因是因为没有将 Dockerfile 放置在根目录下,即 与 build.gradle 文件在同一级。

ERROR: failed to solve: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount1070978720/Dockerfile: no such file or directory