Docker是一个应用打包、分发、部署的工具
可以理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要。
而普通虚拟机则是一个完整庞大的系统。
打包、分发、部署
打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
分发:你可以吧你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不论是在Windows/Mac/Linux
镜像、容器
镜像:可以理解为软件的安装包,可以方便的进行传播和安装
容器:软件安装后的状态,每个软件运行环境是独立的、隔离的、称之为容器
安装需要的软件包,yum-util提供yum-config-manager功能,另外两个是devecemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
设置yum源(阿里源)
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
更新源
yum update
安装docker (docker-ce社区 ee企业版)
yum install docker-ce docker-ce-cli containerd.io
使用命令docker version查看版本判断是否安装成功
运行官方测试例子HelloWorld
用于加速个人仓库
开启步骤:
docker run hello-world时发生了什么?
官方文档:https://docs.docker.com/
#启动docker服务
systemctl start docker
#查看版本
docer version
#查看更详细的信息,包括镜像和容器数量
docker info
#帮助
命令 --help
查看本地所有的镜像
[root@hecs-79730 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像创建时间
SIZE 镜像大小
可选参数:
-a, --all #列出所有镜像
-q, --quiet #只显示镜像的ID
所有镜像(从DockerHub中搜索一样)
[root@hecs-79730 docker]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12708 [OK]
mariadb MariaDB Server is a high performing open sou… 4878 [OK]
#可选项
--filter=stars=3000 #搜索出来的镜像就是stars大于3000的
拉取镜像(下载镜像)
#下载镜像 docker pull 镜像名[:版本tag]
[root@hecs-79730 docker]# docker pull mysql
Using default tag: latest #如果不写tag,默认就是最新版
latest: Pulling from library/mysql
72a69066d2fe: Pull complete #分层下载,docker iamge的核心 联合文件
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #镜像真实地址
#两个命令是一致的,第二条使用真实地址来拉取镜像
#docker pull mysql
#docker pull docker.io/library/mysql:latest
#指定版本下载
[root@hecs-79730 docker]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists #共用相同的文件
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
删除镜像命令,rmi意思就是remove image
#根据镜像id删除
docker rmi -f 3218b38490ce
#删除多个镜像
docker rmi -f id1 id2 id3 id4 ...
#删除全部容器
docker rmi -f $(docker images -aq) #$()先执行里面的命令,里面的命令意思是列出所有镜像id,执行完里面后再执行外层的rmi -f,根据所有的镜像id进行批量删除
有了镜像才可创建容器
下面例子是在docker里面跑一个centos容器来测试学习
拉取centos镜像
[root@hecs-79730 docker]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
docker run [可选参数] image
#参数说明
--name="Name" #容器名字,用来区分容器
-d #后台运行方式
-it #使用交互方式运行,进入容器查看内容
-rm #容器退出后将会自动删除容器,也就是docker ps -a 也没有记录
-p #指定容器端口
-p #ip:主机端口:容器端口 (映射,访问宿主机的端口会映射给容器)
-p #主机端口:容器端口(常用)
-p #容器端口
-P #随机指定端口
docker run -it centos /bin/bash
-it 交互方式打开
centos 镜像名
/bin/bash 以命令行交互方式打开
#直接退出并停止容器
exit
#容器不停止退出(快捷键)
ctrl + P + Q
#查看正在运行的容器
docker ps
#查看所有的容器
docker ps -a
#查看最近创建的容器
docker ps -a -n=1 #最近1个
#以容器ID显示所有容器
docker ps -aq
#根据容器id指定删除,不能删除正在运行的容器,强势删除可以 rm -f
docker rm 容器id
#删除所有容器,正在运行的容器删除不了
docker rm -f $(docker ps -aq)
#删除所有容器2
docker ps -a -q | xargs docker rm
#启动容器
docker start 容器id
#重启容器
docker restart 容器id
#停止当前正在运行的容器
docker stop 容器id
#强制停止当前容器
docker kill 容器id
#docker run -d centos
#问题docker ps,发现centos停止了
#常见的坑:容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
#nginx,启动容器后,发现自己没有提供服务,就会立即停止,就是没有程序了
docker logs -f -t --tail 容器id
# -tf 显示日志
# --tail number 显示日志的条数
示例:
docker logs -tf --tail 10 容器id
docker stats
#根据容器id查看容器中的进程信息
[root@hecs-79730 docker]# docker top be1086a105df
UID PID PPID C STIME TTY TIME CMD
root 12987 12968 0 17:29 pts/0 00:00:00 /bin/bash
#根据容器id查询
docker inspect 容器id
#根据镜像id查询
docker iamge inspect 镜像id
这个其实才是完整的容器id,里面包含了许多信息,其中网络配置比较重要
第一种方式
#当容器后台启动后,或者按ctrl+P+Q退出容器,使用此命令重新进入
docker exec -it 容器id bashShell
#解释
-it 以交互方式进入
bashShell 前台交互方式
#例子
docker exec -it be1086a105df /bin/bash
#解释
/bin/bash 以命令行方式进入
第二种方式
#查看正在运行的容器
[root@hecs-79730 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be1086a105df centos "/bin/bash" 13 minutes ago Up 8 seconds admiring_wilson
#使用docker attach进入到容器
[root@hecs-79730 docker]# docker attach be1086a105df
[root@be1086a105df /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
两种方式的区别
docker exec 进入容器后开启一个新的终端,可以在里面操作
docker attach 进入容器正在执行的终端,不会启动新的进程
无论容器是否在运行都可以进项复制,前提是容器没有被删除
#docker cp 容器id:容器内路径 目的主机的路径
[root@hecs-79730 docker]# docker cp be1086a105df:/home/helloworld.java /data
[root@hecs-79730 docker]# ls /data
a.txt helloworld.java
#1、搜索镜像,可以去dockerhub.com查找对应版本以及文档
docker search nginx
#2、拉取镜像至本地
docker pull nginx
#3、运行测试
#解释
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器端口(因为nginx默认是监听80端口的)
[root@localhost ~]# docker run -d --name nginx01 -p 3344:80 nginx
#4、查看正在运行容器
[root@localhost ~]# docker ps
#5、测试nginx是否启动成(返回nginx网页默认源码)
[root@localhost ~]# curl localhost:3344
其中端口映射的原理如下图所示
外网用户通过请求宿主机暴露的接口,便会映射给对应端口的容器。
主要要开入防火墙和安全组的入栈端口。
进入正在运行nginx的容器
#查看正在运行的容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e3f0b14cc3f nginx "/docker-entrypoint.…" 9 minutes ago Up About a minute 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
#通过exec命令,打开一个新终端进入
#nginx01是刚在启动nginx时命名的名字,可以直接通过名字操作,不需要容器id
[root@localhost ~]# docker exec -it nginx01 /bin/bash
root@7e3f0b14cc3f:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
nginx
#查找nginx目录
root@7e3f0b14cc3f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@7e3f0b14cc3f:/#
#/etc/nginx nginx配置文件
#/usr/share/nginx 静态网页文件
前往DockerHub查询Tomcat版本以及使用文档
https://hub.docker.com/_/tomcat
docker 拉取镜像,这里指定9.0版本
docker pull tomcat:9.0
官方启动方式
#官方启动方式
docker run -it --rm tomcat:9.0
#这种方式是用于临时测试的,
#-rm 是用完即删,就是tomcat退出时会自动删除容器,也就是docker ps -a也没记录
#而且这种方式是以前台方式启动,启动后直接打印tomcat日志
常用启动方式
docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
# -d 后台启动
# -p 端口映射,宿主机3355,容器8080,因为tomcat默认端口为8080
# --name 设定名字
发现问题1:外网无法通过http://ip:端口访问
发现问题2:Tomcat是访问到了,但是报404页面
Portainer
docker图形化管理工具,提供一个后台面板供我们操作
Rancher
后续会讲,主要用于CI/CD操作
#下载镜像,并启动容器
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# -d 后台运行
# -p 端口映射
# -v 卷映射
然后通过http://ip:8088 便可访问
并且首次访问要设置管理密码
选择Local,然后Connect连接上。因为docker在本地,所以用不上远程
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件
所有应用,直接打包docker镜像,就可以直接跑起来
如何得到镜像:
当我们在下载一个镜像时,会发现该镜像存在很多的layer层级
而其中Already exists表示该层级已存在,是因为docker镜像会共用层级(sha256相同情况下)。在我们之前下载的镜像当中已经下载过该层级。所以可以直接拿过来用,大大节约空间。
其实docker镜像都是只读的,不可修改,当容器启动时,一个新的可写层被加载到镜像的内部,我们所作的所有操作、配置都在新的可写层。这一层就是我们通常说的容器层,容器层之下的都叫镜像层。
我们对容器操作之后可以再次打包层镜像,给他人操作。也就时提交一个镜像commit
docker commit 提交容器成为一个新的镜像
通常用法是:保存当前的容器状态吗,相当于快照,随时可以回滚
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
例子:打包一个自己修改过的镜像
# 前台方式启动一个centos容器
[root@localhost ~]# docker run -it --name centos01 centos /bin/bash
# 原先容器的目录
[root@cee7a3b261a1 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 创建一个新的目录 xzlyf
[root@cee7a3b261a1 /]# mkdir xzlyf
# 验证
[root@cee7a3b261a1 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var xzlyf
# 查看当前正在运行的容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cee7a3b261a1 centos "/bin/bash" 2 minutes ago Up 2 minutes centos01
# commit提交镜像
# -m 描述信息
# -a 作者
# 容器id
# 新镜像名字:[版本]
[root@localhost ~]# docker commit -m="make private directory" -a="xzlyf" cee7a3b261a1 centos-test:0.1
sha256:2935bf71fe7c24f7f371a3782f8a801be3f6688546ec71f1c961b42647f858a9
# 制作成功,查看镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-test 0.1 2935bf71fe7c 3 seconds ago 231MB
tomcat 9.0 ae6026892279 2 days ago 680MB
redis latest dd8125f93b94 3 days ago 117MB
nginx latest 0e901e68141f 2 weeks ago 142MB
portainer/portainer latest 12b0b8dced14 4 weeks ago 75.4MB
centos latest 5d0da3dc9764 8 months ago 231MB
# 然后我们使用刚才提交的镜像运行容器测试下
[root@localhost ~]# docker run -it --name centos02 centos-test:0.1 /bin/bash
# 可以看到目录已存在
[root@3faec46c2918 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var xzlyf
通过查看元素据命令
# 查看自己打包的镜像元数据
docker image inspect centos-test:0.1
# 查看原先centos镜像的元数据
docker iamge inspect centos
可以看到我们自己打包镜像的层级时多了一层的
自己打包的centos层级信息
原先版本的centos层级信息
数据都不应该放在容器里,容器删除后数据就会丢失!
卷技术就是:docker容器中产生的数据,同步到本地。
简单理解就是:目录的挂载,将容器内的目录,挂载到Linux上面。
还有一点:容器间数据可以共享的,也就是可以挂载同一个目录
指定容器内某个目录映射给宿主机目录
docker run -v 宿主机目录1:容器内目录1 -v 宿主机目录2:容器内目录2
# -v 目录映射
# 注意:一个 -v表示挂载一个目录,多个 -v可以挂载多个目录
例子
# 启动容器,并挂载容器/home目录到宿主机/home/centos-test目录下
[root@localhost ~]# docker run -it -v /home/centos-test:/home centos /bin/bash
# 进入容器/home目录下
[root@c536c8735c69 /]# cd /home/
# 创建一个文件测试下同步
[root@c536c8735c69 home]# vi hello.txt
# 退回宿主机,并进入宿主机/home目录
[root@localhost ~]# cd /home/
# ls查看发现多了centos-test的挂载目录,该目录是挂载会自动创建
[root@localhost home]# ls
centos-test
# 进入挂载目录,发现存在测试文件
[root@localhost home]# cd centos-test/
[root@localhost centos-test]# ls
hello.txt
[root@localhost centos-test]# cat hello.txt
hello master
[root@localhost centos-test]#
使用命令docker inspect 查看容器元数据
docker inspect c536c8735c69(容器id)
可以看到挂载信息,如果没有信息表明挂载失败
解释:
Type 绑定
Source 宿主机目录
Destination 容器内目录
注意:其实就是容器内的/home目录内存地址指向的宿主机的/home/centos-test目录下,就是一份文件来的,不管容器是否在运行,该文件依旧可以操作。就算容器删除,宿主机的下挂载目录也不会受到影响
mysql数据的持久化,拒绝删库跑路(容器删除后,数据也就没了)
docker run -d -p 3310:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 mysql:5.7
# -d 后台运行
# -v 挂载容器内/etc/mysql/conf.d/目录到宿主机/home/mysql/conf目录
# -v 挂载容器内/var/lib/mysql目录到宿主机/home/mysql/data目录
# -e 环境配置,配置容器的MYSQL_ROOT_PASSWORD变量,这是mysql自定义的变量,是mysql的root初始密码,详情看Docker Hub的mysql文档
# --name 给容器命名
# 在宿主机内查看/home目录以及存在mysql的文件
[root@localhost home]# ls /home/mysql/conf/ /home/mysql/data/
/home/mysql/conf/:
/home/mysql/data/:
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem
通过命令docker inspect mysql01查看容器元数据
可以看到已近挂载了两个目录
不指定宿主机目录,只指定容器的目录路径,以名字进行辨认。Docker默认会将所有容器的卷统一放在宿主机的一个目录下,以名字进行区分。该目录在宿主机的位置:/var/lib/docker/volumes/xxx/_data
注意:通过映射宿主机路径挂载的方式(方法一),数据卷并不会在该目录存在,只会在指定路径的目录下存在。
匿名挂载
# 匿名挂载,就是在-v时只写容器内部地址,没有写外部路径
# -v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx
#使用docker volume 查看docker卷情况
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local 70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
# 通过docker卷查看情况时,发现一个卷名是随机码
# 通过卷名随机码,获取在宿主机挂载的真实路径
# 命令:docker volume inspect 卷名
[root@localhost home]# docker volume inspect 70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
[
{
"CreatedAt": "2022-06-13T09:02:16-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd/_data",
"Name": "70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd",
"Options": null,
"Scope": "local"
}
]
# 查看卷信息,可以发现该卷在宿主机挂载的真实地址
具名挂载(一般都使用这个)
指定挂载名字,解决随机码难以辨认
# 具名挂载
# 名字:容器内部路径 (注意:名字前没有/斜杆,有斜杠是映射宿主机地址)
docker run -d --name nginx01 -v nginx01-data:/etc/nginx nginx
# 通过docker volume查看卷
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local nginx01-data
# 发现容器卷名字是自己定义的
# 查看卷真实地址
[root@localhost home]# docker volume inspect nginx01-data
[
{
"CreatedAt": "2022-06-13T09:13:04-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx01-data/_data",
"Name": "nginx01-data",
"Options": null,
"Scope": "local"
}
]
给目录加权限用法
用法
docker run -d -P -v centos-data:/etc/nginx:ro ngxin
docker run -d -P -v centos-data:/etc/nginx:rw ngxin
Dockerfile初体验
Dockerfile就是用来构建docker镜像的构建文件,也就是命令脚本
通过这个脚本可以生成镜像,镜像是一层层的,每个命令都是一层
dockerfile文件:
# 建一个dockerfile文件,名字可以随机,但是推荐dockerfile
# 文件中的命令都必须是大写
# 以centos作为基础
FROM centos
# 载两个目录,两个都是匿名挂载方式,随机码文件夹名
# 挂载容器/volume01目录到宿主机/var/lib/docker/volumes/xxx/_data
# 挂载容器/volume02目录到宿主机/var/lib/docker/volumes/xxx/_data
VOLUME ["volume01","volume02"]
# 打印输出
CMD echo "----end----"
#进入方式是以控制台
CMD /bin/bash
开始构建
# docker build 构建命令
# -f 以dockerfile构建脚本进行构建(刚才创建的脚本)
# -t 镜像信息 镜像名:版本(注意镜像名前面不要加斜杠,中间可加)
# . 在当前目录下生成
[root@localhost centos-test]# docker build -f dockerfile -t xzlyf/centos:0.1 .
# 可以看到构建是以4步走的
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in f957993b695c
Removing intermediate container f957993b695c
---> 234224acf0e4
Step 3/4 : CMD echo "----end----"
---> Running in cd61faad4888
Removing intermediate container cd61faad4888
---> ec7fa7de0651
Step 4/4 : CMD /bin/bash
---> Running in 09eebb326e22
Removing intermediate container 09eebb326e22
---> 55f93c8af084
Successfully built 55f93c8af084
Successfully tagged xzlyf/centos:0.1
# 查看本地镜像
[root@localhost centos-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xzlyf/centos 0.1 55f93c8af084 32 seconds ago 231MB
使用镜像
# 用刚才制作的镜像启动容器
[root@localhost centos-test]# docker run -it --name centos-xz 55f93c8af084 /bin/bash
# 容器内发现已近挂载上volume1、2的数据卷
# 我们在启动时并没有 -v 手动挂载数据卷
# 是应为我们在构建镜像时加载VALUME[]命令,设置了容器启动时自动挂载数据卷
[root@e19931d115a8 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
#我们退回宿主机,查看数据卷信息,发现是多了两个卷,并且是匿名创建的
[root@localhost centos-test]# docker volume ls
DRIVER VOLUME NAME
local 3d1218071c2a9040367c60b5229f4170a371806ec6673facc47cb220efa8b6e0
local e739f67e82c10654fee986565f3616f01ca1204ac93361e1427eb814fbc994f7
两个或多个容器之间实现数据共享
# 命令: --volumes-from 父容器
# 示例:
# 启动父容器,并挂载容器的/var/lib/mysql目录(匿名挂载方式)
docker run -d -P -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:7.5
# 启动子容器,不需要指定挂载目录,因为使用了--volumes-from 指定了父容器,它们的挂载目录是一致的
docker run -d -P -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:7.5
# 这时候就可以实现两个容器数据同步
# 启动父容器可以被多个子容器挂载
# 谁挂载谁,被挂载的那个就是父容器。子容器可以被挂载,相对于挂载那个容器,它就是父容器。
结论:不管父容器是否删除还是停止,子容器的同步过的文件是不会丢失的。他们是一种拷贝机制,不是文件的路径的指向。数据卷容器的生命周期一直持续到没有容器使用为止,类似病毒式传播。
关于docker volume的常用命令
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local 8c0f70022be0acea15671685df3c5c37f850f46db27ebc1441b3ae850a943263
local 70dd80c50a02b7efba2f8d9a439de13a36d66f331d6ba16636047ad348a025cd
local a52de3ed1daad2b733772f
#命令:docker volume inspect 卷名字
[root@localhost home]# docker volume inspect nginx01-data
[
{
"CreatedAt": "2022-06-13T09:13:04-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx01-data/_data",
"Name": "nginx01-data",
"Options": null,
"Scope": "local"
}
]
docker volume rm 卷名字
默认删除容器卷并不会删除,会一直存在
docker rm -v 容器id
删除不了容器正在使用的卷,其他无用卷全被删除
docker volume prune
dockerfile是用来构建docker镜像的文件!它是一个命令参数脚本。
构建步骤:
FROM #基础镜像,一切从这里开始,centos ubuntu scratch
MAINTAINER #镜像是谁写的,姓名 邮箱
RUN #镜像构建的时候需要运行的命令,不如构建时要安装vim等命令或rm删除一些文件
ADD #添加内容,比如tomcat、redis、mysql
WORKDIR #镜像工作目录,就是指初次进入时的目录,比如mysql初始进入就在/etc/mysql目录下
VOLUMES #挂载的目录,自动挂载到宿主机的目录,不用启动容器时 -v 手动挂载,但是只能匿名挂载
EXPOSE #暴露端口,启动容器时-p进行端口映射。比如暴露3306端口,容器启动时-p 3300:3306就可映射
CMD #CMD在Dockerfile中只能出现一次,有多个,只有最后一个会有效。其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令。没提供就会使用构建时的命令。
ENTRYPOINT #这个命令和CMD命令一样,唯一的区别是不能被docker run命令的执行命令覆盖,如果要覆盖需要带上选项--entrypoint,如果有多个选项,只有最后一个会生效。
ENV #设置容器的环境变量,可以让其后面的RUN命令使用,容器运行的时候这个变量也会保留。
COPY #与ADD的区别,COPY的只能是本地文件,其他用法一致
ONBUILD #这个命令只对当前镜像的子镜像生效。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
#Docker Hub 中99%的镜像都是从这个基础镜像开始的,然后配置需要的软件来进行构建
FROM scratch
# 添加了一个centos 7的压缩包,这个就是centos7超级精简版镜像,少了很多命令
ADD centos-7-x86_64-docker.tar.xz
# 创建一个文件夹,存放镜像需要用到的所有资源
[root@localhost home]# mkdir DockerImage-xz
[root@localhost home]# cd DockerImage-xz/
# 创建dockerfile构建文件脚本
[root@localhost home]# vi dockerfile
# 从centos7镜像开始(注意centos8是在21年12月31日停止了源的服务,会出现无法yum下载)
FROM centos:7
# 作者信息 名字<邮箱> 这种格式
MAINTAINER xzlyf
# 配置环境变量,变量名MYPATH
ENV MYPATH /usr/local
# 默认工作目录,通过$取变量值
WORKDIR $MYPATH
# 构建时候安装vim和net-tools程序,原先centos精简过是不带这两个命令的
RUN yum -y install vim
RUN yum -y install net-tools
# 暴露80端口
EXPOSE 80
# 以命令行方式进入
CMD /bin/bash
# 构建命令:docker build
# -f 指定构建文件路径
# -t 镜像名字:版本标签
# . 在当前目录构建
docker build -f dockerfile -t centos-xz:0.1 .
...
Successfully built dd764fbcf302
Successfully tagged centos-xz:0.1
#出现Successfully表示构建成功
#运行测试镜像,这里要指定版本号,不然docker回去找最新版laster的
docker run -it centos-xz:0.1
#进入容器后发现,vim和ifconfig命令已经成功装上了
CMD #CMD在Dockerfile中只能出现一次,有多个,只有最后一个会有效。其作用是在启动容器的时候提供一个默认的命令项。如果用户执行docker run的时候提供了命令项,就会覆盖掉这个命令。没提供就会使用构建时的命令。
ENTRYPOINT #这个命令和CMD命令一样,唯一的区别是不能被docker run命令的执行命令覆盖,如果要覆盖需要带上选项--entrypoint,如果有多个选项,只有最后一个会生效。
# dockerfile文件
FROM centos:7
CMD ["ls","-a"]
#运行生成的镜像,ccos为镜像名
dockert run ccos
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
#可以看到启动容器时,会自动执行ls -a 命令
#加入命令启动
docker run ccos -l
docker:Error response from daemon :OCI runtime create failed:container_linux.go:349:starting container process caused "exec: \"-l"\"":executable file not found in $PATH": unknow.
# 可以看到启动报错了,说找不到 -l 命令
# 确实,Centos没有-l
# CMD是否覆盖原有的”ls -a"命令,直接替换成“-l"命令
# 如果想追加变成”ls -al“命令,只能完整写出来,直接覆盖,这样是没问题的
# 例如: docker run ccos ls -al
# 如果想追加,只能使用ENTRYPOINT命令
# dockerfile文件
FROM centos:7
ENTRYPOINT ["ls","-a"]
#运行生成的镜像,ccos为镜像名
dockert run ccos
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
#可以看到启动容器时,会自动执行ls -a 命令
#加入命令启动
docker run ccos -l
#此时发现命令是以 ls -a -l执行,可以追加命令
编写Dockerfile文件,推荐使用官方命名Dockerfile,这样可以不用加-f指定了
# 以centos7作为第一层
FROM centos:7
# 作者信息
MAINTAINER xzlyf
# 复制readme.md到容器内部目录
COPY readme.md /usr/local/readme.md
# 添加JDK包、Tomcat包,ADD命令会在构建镜像时自动解压,解压到目标路径/usr/local
ADD jdk-8u333-linux0x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.64.tar.gz /usr/local/
# 安装vim命令
RUN yum -y install vim
# 环境变量,默认工作目录
ENV MYPATH /usr/local
# 设定默认工作目录,用$调用环境变量
WORKDIR $MYPATH
# 配置JDK环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_333
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# 配置tomcat环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.64
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.64
# 配置path,这样启动命令不用进bin目录下了
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 暴露端口
EXPOSE 8080
# 容器启动时,自动启动tomcat,并监听tomcat日志,使用&& 可以拼接无数个命令
CMD /usr/local/apache-tomcat-9.0.64/bin/startup.sh && tail -F /usr/localapache-tomcat-9.0.64/bin/logs/catalina.out
开始构建镜像
# 因为使用了Dockerfile作为文件名,所以可以不用-f指定构建脚本,docker会在当前目录搜索Dockerfile文件
docker build -t tomcatdiy .
测试镜像
# 启动刚才生成的镜像,并映射端口
# -v 挂载webapps目录到宿主机的目录下,以后部署项目只需要在宿主机目录下修改即可
# -v 同时挂载tomcat的日志目录到宿主机下,方便查看
[root@localhost DockerImage-tomcat]# docker run -d -p 9090:8080 \
-v /home/DockerImage-tomcat/test:/usr/local/apache-tomcat-9.0.64/webapps/ROOT \
-v /home/DockerImage-tomcat/tomcat-logs:/usr/local/apache-tomcat-9.0.64/logs \
tomcatdiy
# 进入容器看看
[root@localhost DockerImage-tomcat]# docker exec -it 6b6618cbea00 /bin/bash
[root@6b6618cbea00 local]# pwd
/usr/local
# 可以看到默认工作路径是我们自己指定的
# 回到宿主机,进入/home/DockerImage-tomcat/test目录
# 这里可以直接发布项目
[root@localhost test]# ls
index.html
[root@localhost test]# cat index.html
Document
hhhhhhh
# 宿主机ip:9090/test 便可进入访问该项目
hub.docker.com
[root@localhost home]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Options:
-p, --password string 密码
--password-stdin Take the password from stdin
-u, --username string 用户名,邮箱不行
#示例
docker login -u aromz
password:*******
Login Succeeded
#命令:docker push 作者/镜像名:版本tag
docker push aromz/centos-xz:0.1
#如果报没有找到镜像文件,用docekr images查看镜像文件是否存在
[root@localhost home]# docker push aromz/centos-xz:0.1
The push refers to repository [docker.io/aromz/centos-xz]
An image does not exist locally with the tag: aromz/centos-xz
#已经制作好的镜像可以使用tag标签重新修改镜像信息
[root@localhost home]# docker tag dd764fbcf302 aromz/centos-xz:0.1
[root@localhost home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
aromz/centos-xz 0.1 dd764fbcf302 2 days ago 601MB
centos-xz 0.1 dd764fbcf302 2 days ago 601MB
#然后就可以发现多了个镜像文件,原先的镜像也还在
#然后再次push就可以了
[root@localhost home]# docker push aromz/centos-xz:0.1
The push refers to repository [docker.io/aromz/centos-xz]
bc9a0af675d3: Pushed
e8b9580b2039: Pushed
174f56854903: Mounted from library/centos
0.1: digest: sha256:d83ba3f879ad9f21714a13b478b7130e78cf2d628242bfb4a1d9054f15483357 size: 953
命名空间
个人版只能拥有3个,可以把命名空间看作一个大项目,一个命名空间包含多个镜像,命名空间之间相互隔离。
镜像仓库
个人版有300个镜像,每个镜像需要指定一个命名空间,通过命名空间隔离。每个镜像可以上传多个版本。
# 先docker logout退出登录
[root@localhost home]# docker logout
Removing login credentials for https://index.docker.io/v1/
# 登录阿里云镜像中心
[root@localhost home]# docker login [email protected] registry.cn-guangzhou.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
# 给镜像修改信息,修改成官方要求,可以看到修改后镜像id没有变,值修改了名字和版本
[root@localhost home]# docker tag dd764fbcf302 registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:0.1
[root@localhost home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-xz 0.1 dd764fbcf302 2 days ago 601MB
registry.xxxxxom/xzlyf/test_depot 0.1 dd764fbcf302 2 days ago 601MB
# 推送修改信息后的镜像
[root@localhost home]# docker push registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot:0.1
The push refers to repository [registry.cn-guangzhou.aliyuncs.com/xzlyf/test_depot]
bc9a0af675d3: Pushed
e8b9580b2039: Pushed
174f56854903: Pushed
0.1: digest: sha256:d83ba3f879ad9f21714a13b478b7130e78cf2d628242bfb4a1d9054f15483357 size: 953
可以看到已经上传成功了
push:
把镜像推送到容器中心(DockerHub、阿里容器镜像)
pull:
从容器中心拉取镜像下载
run:
运行一个镜像,运行后的环境称为容器
stop:
start:
restart:
控制容器的生命,启动运行和重启
commit:
把当前容器的状态保持,相当于一个快照。提交后会生成一个镜像。
tag:
镜像重新修改名称和tag版本信息,一般镜像是以“作者/镜像名:[版本tag]"命名
build:
制作一个镜像,通过dockerfile脚本文件生成
save:
打包镜像成tar压缩包,用于开发者直线相互共享或备份
# 用法:$ save -o 路径 镜像id
load:
加载打包后的tar压缩包镜像
# 用法:$ load -i 路径
在纯净的docker环境中(没有启动任何容器),宿主机一般只有这三个网卡。
网卡:
lo:本地回环地址
ens33:本地内网地址
docker0:docker0地址
当我们启动一个容器后(没有–net指定网络),docker会默认分配docker0的网络给容器(上图:172.17.0.0/16网段)
# 启动一个容器
[root@localhost home]# docker run -it centos-net /bin/bash
# 执行容器内 ip addr命令
[root@localhost home]# docker exec -it 17bcb991db3f ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
6: eth0@if7: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 通过 ip addr 命令可以看到,
# 1:lo 容器回环地址
# 6:eth0@if7 docker0网络,符合172.17.0.0/16的网络,宿主机与容器通信是通过该ip
宿主机ping容器,可通
[root@localhost home]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.090 ms
容器ping宿主机,可通
[root@localhost home]# docker exec -it 17bcb991db3f ping 192.168.7.125
PING 192.168.7.125 (192.168.7.125) 56(84) bytes of data.
64 bytes from 192.168.7.125: icmp_seq=1 ttl=64 time=0.100 ms
64 bytes from 192.168.7.125: icmp_seq=2 ttl=64 time=0.100 ms
回到宿主机ip addr,可以发现多了个网卡,这个网卡就是连接容器的介质
同理,我们再启动一个容器,让容器相互ping,也是额可以通的。
[root@localhost home]# docker run -it centos-net /bin/bash
[root@44db2975dc87 /]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.084 ms
但是,它们是怎么工作的呢?详情看下面
我们每启动一个docker容器,docker就会给容器分配一个ip。如果没有指定docker网络,docekr就会给容器分配docker0的网络。
而docker0是以桥接模式工作的,这里涉及到一个evth-pair技术
在宿主机ip addr可以看到,容器的网络名是 7:vethc7c394f@if6
然后我们进入容器内部查看ipaddr,网络名是6:eth0@if7
可以看到它们是成对出现的,这就是evth-pair技术,它们就是一对的虚拟设备接口。
evth-pair充当一个桥梁,连接各种虚拟网络设备。
容器之间相互ping,容器会在docker0中找路由表,通过ip找到下一条的虚拟接口地址。虚拟接口之间有着它们的通信协议,从而完成通信。
注意:在删除容器时,docker会自动删除对应的网络接口和路由表,用户无需操作。
注意2:容器启动时,没有指定网络(–net)的情况下, 都会使用docker0网络随机分配一个可用ip。
一般比较少用,用自定义网络可实现
在容器启动时,使用命令–link连接到另一个容器的网络
# 命令
# --link 容器名或容器id
[root@localhost home]# docker run -it --name centos03 --link centos02 fb46382c1acf
# 通过--link连接后可以直接通过centos02 ping通
[root@1c8dbf8b0f9d /]# ping centos02
PING centos02 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.093 ms
centos03可以直接通过容器名centos02 ping通。
但是,centos02 无法使用centos03 ping通。
其实,–link的原理很简单。就是通过修改hosts来实现容器访问
centos03容器在启动时,修改了hosts,但是centos02并没有修改,所有centos02无法通过服务名来访问centos03。
还有一点,通过 docker inspect centos03可以看到,这里多了个Links
综上所述,这种连接方式一般很少用。一般通过自定义网络来实现,就是不再使用docker0
[root@localhost home]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e7cf25ea27a2 bridge bridge local
61b7289abf4d host host local
8cd18ec10e2e none null local
docker网络模式
bridge 桥接
none 不配置网络
host 和宿主机共享网络
container 容器网络连通(用得少)
创建docker网络
命令:docker network create
# 命令
# --diver 网络模式 bridge
# --subnet 子网网段 192.168.1.0/24
# --gateway 网关 192.168.1.1
# mynet docker网络名字
[root@localhost home]# docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.1 mynet
3b205223b27709a6d102cd82ecdad281a7b394ba7ba074cbbafcc3fd2e3a56d7
# 通过查看网络可以看到已经创建成功
[root@localhost home]# docker network ls
NETWORK ID NAME DRIVER SCOPE
274d1929871b bridge bridge local
61b7289abf4d host host local
3b205223b277 mynet bridge local
注意:不要创建和自己物理网卡相同的网段。
比如物理网卡的内网地址是192.168.0.1/24,自定义网络的网段就不能使用这个了
查看docker网络
命令:docker network inspect 网络id或网络名
[root@localhost home]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "3b205223b27709a6d102cd82ecdad281a7b394ba7ba074cbbafcc3fd2e3a56d7",
"Created": "2022-06-18T08:06:49.861071541-04:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.1.0/24",
"Gateway": "192.168.1.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
使用刚才创建的docker网络
[root@localhost home]# docker run -it --name centos01 --net mynet centos-net
WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@1da090c5e3f7 /]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
8: eth0@if9: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c0:a8:01:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.2/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
自定义网络无需任何配置,可以直接通过容器名互ping通
而默认docker0是不支持的
这不是通过hosts实现,而是路由器(即自定义网络)实现的
注意docker0不支持指定ip启动
# 命令
# --net 指定网络
# --ip 指定ip,要求符合指定网络的网段
[root@localhost home]# docker run -it --name centos01 --net mynet --ip 192.168.1.125 centos-net
[root@aec043fce68f /]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
25: eth0@if26: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:c0:a8:01:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.125/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
命令:docker network connect 网络名或网络id 容器名或容器id
这个命令对应单个容器跨网段通信的!
比如使用docker0网络的一个容器,需要和mynet网段的容器通信。
使用命令docker connect mynet 容器2
这个时候容器2便可以和mynet的任意一容器通信了。但是这条命令只是对于容器2生效,容器1并不可以与mynet网络通信。
而这个命令的原理很简单,就是把容器2加入mynet网络,我们通过命令docker network inspect mynet可以发现,容器2在网络中分配到一个可用ip。而此时容器2拥有两个网络,一个是docker0的,另一个是mynet的。
常见用法:
redis 不同的集群使用不同的网络,保证安全和健康
mysql 不同的集群使用不同的网络,保证安全和健康
在target目录得到xxx.jar包,如果打包jar包查看以前的笔记…
# 项目用java8构建的,所有制作dock镜像可以直接用java8的镜像
FROM java:8
# 把当前目录下的所有jar包都拷贝到镜像里,并命名为app.jar,位置在/目录下
COPY *.jar /app.jar
# 修改springboot项目启动端口,后续启动容器时可以用此命令指定其他端口
CMD ["--server.port=8080"]
# 暴露8080端口,让宿主机自行觉得映射端口
EXPOSE 8080
# 启动容器是同时启动jar包(即项目)
ENTRYPOINT ["java","-jar","/app.jar"]
打包后,在开发本地使用命令java -jar docker-0.0.1-SNAPSHOT.jar 测试是否能正常运行业务
把上面两个文件(jar包、Dockerfile)文件上传到centos(docker环境)下打包成镜像
# docker build 构建命令
# -t 镜像信息:[TAG0.1]
# -f 没有指定是因为名字符合官方要求,docker将自动搜索到构建脚本Dockerfile
# . 当前目录(必备)
[root@localhost springboot]# docker build -t hello:0.1 .
Sending build context to Docker daemon 17.61MB
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
---> e386fbf252eb
Step 3/5 : CMD ["--server.port=8080"]
---> Running in 0a21491b3b93
Removing intermediate container 0a21491b3b93
---> dc8823778613
Step 4/5 : EXPOSE 8080
---> Running in e1c6b8ea92ab
Removing intermediate container e1c6b8ea92ab
---> 52b3890a484e
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in 598cfa442b38
Removing intermediate container 598cfa442b38
---> 17966c49a5d6
Successfully built 17966c49a5d6
Successfully tagged hello:0.1
# 构建成功,查看镜像
[root@localhost springboot]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello 0.1 17966c49a5d6 About a minute ago 661MB
# 启动镜像测试
[root@localhost springboot]# docker run -d -p 8080:8080 --name hello01 hello:0.1
# 请求测试接口
[root@localhost springboot]# curl localhost:8080/hello
# 数据返回正常
{"msg":"success","code":1,"data":1655560180074}
此时docker 镜像已经制作完毕,并测试正常。
通过该镜像可以进项项目交付、上传到DockerHub和阿里云镜像服务中心等工作
# 项目用java8构建的,所有制作dock镜像可以直接用java8的镜像
FROM java:8
# 把当前目录下的所有jar包都拷贝到镜像里,并命名为app.jar,位置在/目录下
COPY *.jar /app.jar
# 修改springboot项目启动端口,后续启动容器时可以用此命令指定其他端口
CMD ["--server.port=8080"]
# 暴露8080端口,让宿主机自行觉得映射端口
EXPOSE 8080
# 启动容器是同时启动jar包(即项目)
ENTRYPOINT ["java","-jar","/app.jar"]
打包后,在开发本地使用命令java -jar docker-0.0.1-SNAPSHOT.jar 测试是否能正常运行业务
把上面两个文件(jar包、Dockerfile)文件上传到centos(docker环境)下打包成镜像
# docker build 构建命令
# -t 镜像信息:[TAG0.1]
# -f 没有指定是因为名字符合官方要求,docker将自动搜索到构建脚本Dockerfile
# . 当前目录(必备)
[root@localhost springboot]# docker build -t hello:0.1 .
Sending build context to Docker daemon 17.61MB
Step 1/5 : FROM java:8
---> d23bdf5b1b1b
Step 2/5 : COPY *.jar /app.jar
---> e386fbf252eb
Step 3/5 : CMD ["--server.port=8080"]
---> Running in 0a21491b3b93
Removing intermediate container 0a21491b3b93
---> dc8823778613
Step 4/5 : EXPOSE 8080
---> Running in e1c6b8ea92ab
Removing intermediate container e1c6b8ea92ab
---> 52b3890a484e
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in 598cfa442b38
Removing intermediate container 598cfa442b38
---> 17966c49a5d6
Successfully built 17966c49a5d6
Successfully tagged hello:0.1
# 构建成功,查看镜像
[root@localhost springboot]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello 0.1 17966c49a5d6 About a minute ago 661MB
# 启动镜像测试
[root@localhost springboot]# docker run -d -p 8080:8080 --name hello01 hello:0.1
# 请求测试接口
[root@localhost springboot]# curl localhost:8080/hello
# 数据返回正常
{"msg":"success","code":1,"data":1655560180074}
此时docker 镜像已经制作完毕,并测试正常。
通过该镜像可以进项项目交付、上传到DockerHub和阿里云镜像服务中心等工作