使用docker部署springboot微服务项目

文章目录

1. 环境准备

检查docker是否已安装

bash 复制代码
[root@localhost /]# docker -v
Docker version 1.13.1, build 7d71120/1.13.1

[root@localhost /]# systemctl status docker #查看docker Engine 的状态
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 六 2023-07-29 22:49:00 CST; 7h ago
     Docs: http://docs.docker.com
 Main PID: 967 (dockerd-current)
    Tasks: 155
   Memory: 285.3M
   CGroup: /system.slice/docker.service
............

1. 准备好所用jar包项目

在/opt/目录下创建docker目录:

将在Idea中通过Maven打包好的可执行项目的jar包上传到服务器的/opt/docker目录下

项目中的yml配置文件中的服务端口为8096:

2.编写相应的Dockerfile文件

用于描述构建项目镜像的这个文件名必须是Dockerfile,无后缀,文件名不能随意起。否则构建时提示找不到Dockerfile文件。

powershell 复制代码
# 基础镜像,也叫父镜像,因为jar的运行依赖于JDK或Jre,这里使用只拥有运行环境的Jre,减少最终生成的镜像的大小。
FROM openjdk:8u212-jre
# 维护者
MAINTAINER ssccxx
# 在宿主机的 /var/lib/docker目录下的volumes目录里会创建一个临时文件随机名称的目录将这个目录下的_data 链接到容器内的 /tmp
VOLUME /tmp  #会自动在容器内的根目录下生成此tmp目录
# 将项目的jar添加到镜像中,并修改名称为myapp.jar,这里默认添加到容器的根目录下(即默认的工作目录)。
ADD platform-customer-post.jar myapp.jar
# 在构建镜像时会执行RUN 命令 ,这里的 touch /myapp.jar 不起作用,因为上方的ADD里已经使根目录下有同名的文件。这里的touch就不会再生效了。
RUN bash -c 'touch /myapp.jar'
# ENTRYPOINT 是 在容器运行时自动执行的命令,也就是启动容器内的项目服务
ENTRYPOINT ["java","-jar","/myapp.jar"]
# 声明, 此容器内的服务监听端口应该为8096,这里的EXPOSE只是声明,方便之后的维护者一目了然可以知道容器内的服务的监听端口。
EXPOSE 8096

说明:上面Dockerfile文件里的指令中的 FROM, ADD ,RUN 都是在镜像构建时执行的。而ENTRYPOINT ,VOLUME ,EXPOSE 是在容器

运行时执行的。

3.构建镜像

powershell 复制代码
[root@localhost docker]# ll
总用量 79156
-rw-r--r-- 1 root root      178 7月  30 01:36 Dockerfile
-rw-r--r-- 1 root root 81049868 7月  29 23:02 platform-customer-post.jar
[root@localhost docker]# docker build --no-cache -t micro-server:v1.0 .

说明: build是构建命令 -t 需要 指定 repository:tag (也就是仓库名:tag标签,因为这两个才能确定一个镜像)。
repository name must be lowercase:如果自定义的仓库名有大写字母时,会提示这个。全部改为小写就行了。
--no-cache:表示构建时不使用上次构建中存在的镜像缓存。一般都加上这个否则有可能使用docker引擎缓存中已构建的镜像,造

成,镜像ID重复,产生冲突。

如果当前/opt/docker目录下没有名为Dockerfile。会提示 Dockerfile文件缺失。
重点最后的 . 表示是上下文路径:这里就是我们docker build命令执行的当前所在位置(opt/docker目录)。

由于 docker 的运行模式是 C/S。我们本机是 C(客户端),docker 引擎是 S(服务端)。docker客户端有可能在一台机器上,而docker 引

擎 也就

是对应的服务端 可能在另一台机器上。我们通过docker 客户端的 CLI 命令将构建信息发送到docker引擎端,实际的构建过程是在

docker 引擎下完成的,所以这个时候无法用到我们本机的文件(比如这里的在构建时需要用到platform-customer-post.jar文件)。

这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。虽然我们现在用的虚拟机演示环境是C/S都在同一台机器

上。但是也要走这个流程的。会将 /opt/docker/目录下 内容都打包发给引擎使用,这样docker引擎在执行ADD 指令时 需要复制

platform-customer-post.jar 到镜像中,就从打包的内容里去找,待全部构建完毕,生成最终的镜像后,docker 引擎自动清理这些打包

发过来的内容。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

如果:构建时使用: docker build . --no-cache=true 命令 ,没有指定 生成的镜像的 repository:tag ,会产生悬虚镜像。		

悬虚镜像:就是 repository 和 tag 都是<none> 的镜像.

这样的镜像 没有实际意思。可以删除掉,释放磁盘空间

powershell 复制代码
[root@localhost docker]# docker images -f dangling=true #查询出全部的本地悬虚镜像
[root@localhost docker]# docker image prune  #删除所有悬虚镜像
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y #键入y表示删除所有悬虚镜

使用docker images 查看构建好的镜像是否存在:

4. 运行镜像

通过镜像生成容器实例

  1. docker create --name 容器实例名称 -p 宿主机端口:容器内服务的端口 镜像id
    说明: docke create 命令 是 指定镜像id对应的镜像创建容器,但是并不直接运行容器实例,通过docker ps -a 查看所有容器(包括正在运行
    的停止的容器),然后配合docker start 容器id或容器名 来使用。
  2. docker run -d --name 容器实例名称 -p 宿主机端口:容器内服务的端口 镜像id
    说明:docker run 命令 会根据指定镜像id对应的镜像 创建容器,并直接运行此生成的容器实例。-d 指的是后台运行此容器,否则会在控制
    台打印内容。
    说明:不指定--name 容器名称,系统会自动生成一个容器名:以 形容词 加下划线 加 人名的方式 命名。注意--name属性的位置。
    说明:docker start 命令 。只能用于已存在的容器,不能用于创建并启动容器。
    推荐 使用 docker run 这个命令。因为使用docker create时并不检查宿主机端口是否已经被占用的问题,只有在启动容器时才检查,如果宿主
    机端口冲突 则容器启动失败。
powershell 复制代码
[root@localhost _data]# docker run -d --name xiaohai -p 8090:8096 79bcb7a73dd2
fdb21e089157e0080ecf26585f5ac174f3e56c056f4d341d838387d048debc5e #执行成功后,会返回容器实例id的完整部分。
[root@localhost _data]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                    NAMES
fdb21e089157        79bcb7a73dd2        "java -jar /myapp.jar"   2 seconds ago        Up 2 seconds        0.0.0.0:8090->8096/tcp   xiaohai

说明:

CONTAINER ID:容器实例id

IMAGE:镜像id

COMMAND: 容器启动时,在容器内部自动执行的命令

CREATED:容器被创建至当前时间的过去的时间

PORTS:表示宿主机端到容器内应用端口的映射及协议

NAMES:容器实例名称

根据同一个镜像我们可以同一台宿主机上创建多个容器实例。容器与容器直接是隔离的,相同的服务端口不会产生冲突。保证宿主机的端口不一致就行。在外部 通过请求宿主机ip:宿主机端口/应用服务接口 会根据 端口映射关系,转发到对应的容器内的服务。

5. 测试服务是否OK

[root@localhost _data]# curl http://localhost:8090/v3/api/client/v1/captchaImage

查看容器日志:

docker logs -f 容器id

可以看到请求进来了,说明容器内的服务是正常的。
说明:容器启动失败,或服务是否正常 都可以通过docker logs -f 容器id查看到对应的日志。

6.端口说明

1.宿主机端口,EXPOSE 端口 ,应用服务配置文件里服务端口。这三者之间的关系。

先说 EXPOSE 端口 这个是在Dockerfile配置文件里声明的。其实这个就是给后期维护这个配置文件的人员看的。执行 EXPOSE 端口时,

并不会真正的出现监听这个端口。只是说明 我们应用服务对外监听的端口是这个。具体容器应用服务端口 以容器内服务启动时的端口为(也就是应用服务配置文件里的服务端口)。不在写Dockerfile里 写 EXPOSE 端口 一点影响也没有。只是不方便 后期其他人员维护。

一般情况下 EXPOSE 端口 要和 应用服务配置文件里服务端口一致,方便其他人员通过读Dockerfile文件就知道将来的容器内应用服务的端

口号是多少。

  1. 端口映射的说明。-p 宿主机端口:容器应用服务端口(应用服务配置文件里服务端口)。

如果不配置这个端口映射会有什么影响。影响就是:访问容器内的服务,只有两种方式。 1. 在宿主机上 通过 容器ip:容器内应用服务的

端口 来访问。2.进入容器内,通过 容器ip或者localhost :容器内应用服务的端口 来访问。

如果配置这个端口映射会有什么好处。好处就是:可以在宿主机上通过 localhost或者宿主机ip:宿主机端口来访问。也可以在

外部的机器上 通过访问 宿主机ip:宿主机端口来间接访问到容器内的应用服务,即方便外边网络访问容器内的服务。
说明:这里说的宿主机是指的运行容器的这个node机器。这个node机器是通过VMware安装的虚拟机或者其他物理机。

我这里演示环境是 物理机是Windows系统机器,上面安装有VMware Station,通过VMware Station安装的虚拟机。容器就运行在这个虚

拟机上。上面所说的容器宿主机就是这台虚拟机。并不是我的物理机。

7.进入容器内

powershell 复制代码
[root@localhost _data]# docker exec -it fdb21e089157 /bin/bash  #-it后 是容器实例id  /bin/bash指的是进入容器后,打开一个bash终端  #构建镜像时没有指定工作目录,则默认进入容器后的目录为容器内的根目录
root@fdb21e089157:/# ls
bin  boot  dev	etc  home  lib	lib64  media  mnt  myapp.jar  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
#可以看到myapp.jar包就在容器的根目录下,包括挂载点 tmp目录
#查看容器的java环境,可以看到java版本已经 java的安装目录
root@fdb21e089157:/# java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-b04)
OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)

root@fdb21e089157:/# which java
/usr/local/openjdk-8/bin/java
#也就是我们这个容器内已经有个可执行文件jar包的运行环境了。
root@fdb21e089157:/usr/local/openjdk-8/bin# pwd
/usr/local/openjdk-8/bin
root@fdb21e089157:/usr/local/openjdk-8/bin# ls
clhsdb	hsdb  java  jjs  keytool  orbd	pack200  policytool  rmid  rmiregistry	servertool  tnameserv  unpack200
#可以看到bin目录下只有java命令,没有 javac,jps等命令。因为我们用的基础镜像为openjdk:8u212-jre。所以么有java的编译等命令。只有运行的命令。而且java 命令也已经是容器内的环境变量了。在容器内的任意目录下都可以执行。所以在容器启动后,在容器内的根目录下 自动执行java -jar xxxx.jar 指令是没有问题的。所以宿主机不需要安装java环境。容器内已经拥有了自己的java环境了。
#容器就像一个精简版的centos或ubuntu,里面只有极少的命令如ls,df,du , 没有ll,vim,netstat,yum等命令。
root@fdb21e089157:/# du -h myapp.jar #可以用这个du -h 文件名 查看文件的大小
78M	myapp.jar

8. 操作容器的常用命令

1. docker start 容器id  							#启动已停止的容器
2. docker stop 容器id  							#停止正在运行的容器
3. docker exec -it 容器id -- bin/bash        #进入容器内,注意只有当容器是运行时此命令才有效
4. docker ps 										    #查看正在运行的容器
5. docker ps  -a									    #查看本机所有的容器,包含已停止运行的容器
6. docker logs -f 容器id							#查看容器运行及内部服务查看的日志,若容器已被删除,这里的日志也就查不到了,会被跟着容器自动被删除。
7. docker  inspect 容器id							#查看容器内部组织结构信息,包括容器内的挂载点信息,容器的ip地址信息
8. docker rm 容器id                                  #删除已停止的指定的容器
9. docker rm -f 容器id								#删除容器(包括正在运行的容器)
10. docker rm -f $(docker ps -a -q)          # 删除所有容器,包括正在运行的容器,所有删除操作 因此,在执行该命令之前,请确保您的所有数据已经保存
相关推荐
QuietNightThought24 分钟前
使用Github Action将Docker镜像转存到阿里云私有仓库,供国内服务器使用,免费易用
阿里云·docker
喵叔哟1 小时前
17. 【.NET 8 实战--孢子记账--从单体到微服务】--记账模块--主币种设置
微服务·.net·ruby
it噩梦1 小时前
Springboot 实现Server-Sent Events
java·spring boot·后端
鸽鸽程序猿1 小时前
【JavaEE】Spring Boot 项目创建
java·spring boot·java-ee
一休哥助手1 小时前
使用 Docker 容器创建一个 Web 服务器:从入门到实践
服务器·docker
运维&陈同学1 小时前
【kafka04】消息队列与微服务之Kafka 图形工具
后端·微服务·zookeeper·云原生·架构·kafka·消息队列·云计算
淘淘 小窝4 小时前
springboot配置多数据源mysql+TDengine保姆级教程
spring boot·mysql·tdengine
柴米油盐那点事儿5 小时前
springboot引入kafka
spring boot·kafka
有来技术6 小时前
Docker 部署 MongoDB
mongodb·docker
独泪了无痕9 小时前
探索 IntelliJ IDEA 中 Spring Boot 运行配置
spring boot·intellij idea