目录
安装: 2
获取: 3
操作容器: 4
数据管理 5
数据卷 5
启动一个挂载数据卷的容器 5
挂载一个主机目录作为数据卷: 5
挂载一个本地文件作为数据卷 6
docker网络配置 6
默认bridge网络配置 6
用户自定义网络 6
定制镜像: 8
使用docker commit命令进行对容器的修改 8
使用dockerfile定制镜像: 9
手动创建dockerfile 9
dockerfile指令详解 10
copy复制文件 10
ADD更高级的复制文件 11
CMD容器启动命令 12
ENTRYPOINT入口点 12
ENV设置环境变量 13
ARG构建参数: 13
VOLUME定义匿名卷 14
EXPOSE暴露端口 14
WORKDIR指定工作目录 14
USER指定当前用户 15
HEALTHCHECK 健康检查 15
ONBUILD 延迟执行 15
Docker compose 16
简介 16
安装与卸载 16
使用 16
安装:
apt install \
apt-transport-https \ #允许apt包管理器通过https协议下载软件包
ca-certificates \ #提供权威的CA证书
curl \ #命令行工具,用于从网络上下载文件
gnupg \ #提供GPG加密/签名工具,用于验证软件包的完整性和来源
lsb-release #查询Linux发行版本的详细信息
安装第三方软件源的详细的前置步骤
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
使用curl从阿里云镜像站下载Docker的GPG公钥
使用gpg命令将下载的公钥转换为debian包管理系统可以使用的格式
将转换后的密钥保存到/usr/share/keyrings/docker-archive-keyring.gpg
这是一个标准的添加Docker官方源的步骤。
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
获取系统架构
使用刚添加的GPG密钥
添加阿里云镜像站的Docker CE源到系统中
apt update #更新包索引
sudo apt install docker-ce docker-ce-cli containerd.io#用于安装Docker社区版及其相关组件
安装docker
systemctl start docker #运行docker
systemctl status docker #查看docker运行状态
systemctl enable docker #设置docker为自启动
vim /etc/docker/daemon.json #进入docker的配置文件
{
"registry-mirrors": ["https://id4gc2ys.mirror.aliyuncs.com"]
} #中括号内的是docker的国内镜像加速器,阿里云的
{
"registry-mirrors": ["https://docker.1panel.live/","https://docker.m.daocloud.io", "https://noohub.ru", "https://huecker.io", "https://dockerhub.timeweb.cloud"]
}
国内加速器
获取:
docker pull 容器 #获取镜像
docker run –it --rm 镜像名 /bin/bash exit #退出容器
docker run 运行容器
-i 交互式操作 –t 终端 --rm 退出容器后自动删除该容器
镜像名 以这个镜像为基础启动容器 bash 命令,交互式shell
docker ps –a #查看所有容器
docker ps #只显示运行中的容器
docker iamge ls #查看所有下载好的镜像
docker rm 容器名 #删除该容器
查看容器(筛选)
--filter或是-f 用于在列表类命令(如docker ps、docker image中)根据特定条件筛选结果,不同命令支持的过滤条件不同。下面是一些常用的选项,
- status 按容器状态过滤(created,running,paused,exited,dead)示例:--fliter “status=exited”
- name 按照容器名称过滤(支持通配符:)示例:--fliter “name=myapp”
- ID 按照容器id进行过滤 --fliter “ID=12123”
- before/since 按照时间过滤,(在/自某个容器之后创建)--fliter “before=容器名”
- exited 按照退出码过滤已停止的容器 –filter”exited=0”筛选成功退出的容器
- health 按照健康状态过滤,(healthy,unhealthy)--filter "health=unhealthy"
镜像相关的筛选 - dangling 悬空镜像(无标签且未被容器使用)(true/false)--filter "dangling=true"
- refernce 按照镜像名过滤(支持通配符)--filter "reference='ubuntu:*'"
删除本地镜像
docker iamge rm [选项] 镜像1 镜像2
可以使用ID ,镜像名,镜像摘要来删除镜像
常见选项:
-f 强制删除镜像
--no-prune 禁止自动删除未被引用的父镜像, 默认情况下:当删除一个镜像时,docker会自动检查其父镜像是否还有其他子镜像引用,若无则删除这个父镜像。
使用此选项后,只删除目标镜像,不删除父镜像
还可以跟docker image ls 命令配合使用,
Ps: docker image rm $(docker image ls -q redis) #删除所有名字为redis的镜像
$ docker image rm $(docker image ls -q -f before=mongo:3.2) #或者删除所有在 mongo:3.2 之前的镜像
操作容器:
启动:
新建并启动:docker run
示例:docker run 镜像名 /bin/echo ‘hello ,world’ #启动一个新容器并打印出hello,world
启动已终止的容器: docker container start
示例:docker container start 161b2eafd8ad
守护态运行:
docker run –d --name ddd ubuntu:22.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
守护态运行:在docker run 后面加 –d,会让该容器后台运行,运行的相关结果不显示在前台。
查看守护态运行:
docker logs 容器名称/容器id #查看容器所有日志
docker logs -f 容器名称/容器id #实时查看容器日志
docker logs --tail 100 容器名称/容器id #仅显示容器日志的最新100行
docker logs –t 容器名称/容器id #显示带时间戳的日志
docker logs --since “5m” 容器名称/容器id #查看5分钟内的日志
dockers logs --since “时间” --until “时间” 容器名称/容器id #查看这个时间段内的日志
还可以加上管道符筛选
临时进入守护态运行的容器:
docker exec -it 容器名/容器id 命令 #在守护态运行的容器中执行命令
docker exec -it 容器名/容器id /bin/bash #在守护态运行的容器中获取交互式shell
终止:
docker container stop 容器名/容器id #终止运行中的容器
启动了交互式终端的容器可以用exit/ctrl+d 终止
docker container ls -a #可以查询终止的容器
docker container start 容器名/容器id #启动被终止的容器
docker container restart 容器名/容器id #重启容器
进入容器:
docker attach 容器名/容器id #进入在后台运行的容器(此时退出交互终端会导致容器终止)
docker exec -it 容器名/容器id /bin/bash #在守护态运行的容器中获取交互式shell(在这个交互终端界面使用exit退出,不会导致容器终止)
导入和导出:
docker export 容器id/容器名 > tar包名 #将容器导出到tar包
cat tar包名 | docker import - image名字:tag #将tar包中的容器导入为镜像
删除容器
docker container rm #删除处于终止状态的容器
docker container rm -f #强制删除运行中的容器
docker container prune #删除所有处于终止状态的容器
数据管理
数据卷:是一个可供多个容器使用的特殊目录,他绕过UnionFS
特性:
- 数据卷可以在容器之间共享和复用
- 对数据卷的修改可以立即生效
- 对数据卷的更新不会影响到镜像
- 数据卷会默认一直存在,即使容器被删除
docker volume create 数据卷名 #创建一个数据卷
docker volume ls #查看数据卷
docker volume inspect 数据卷名称 #查看这个数据卷的详细信息
docker run -d -P\
--name 容器名称\
--mount source=数据卷名称,target=路径(容器内部的路径)\
镜像名
-P 自动端口映射,将容器内的这个服务声明的端口映射到主机的高端口上,整个命令的含义是,使用创建一个基于xx镜像的容器,并将数据卷挂载到容器内的指定路径
启动一个挂载数据卷的容器
docker volume rm 数据卷名曾 #删除这个数据卷
数据卷如果被引用时,无法删除数据卷,如果删除引用这个数据卷的容器时,该数据卷会自动解除挂载,这时可以删除数据卷。
docker rm -v 容器名称 #在删除容器时同时移除匿名数据卷
docker volume prune #清理无主卷
挂载一个主机目录作为数据卷:
docker run -d -P \
--name web \
--mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
nginx:alpine
type=bind,表示使用BindMount挂载方式将主机上的目录挂载到容器中,
type=volume,表示使用数据卷挂载
source=绝对路径,表示源文件位置,target=绝对路径,表示将源路径的目录挂载到容器内的位置
这个命令的含义是将主机中的/src/webpp目录挂载到容器中,本地目录的路径必须是绝对路径,--mount挂载时,本地路径不存在的话会报错。挂载的主机的目录的默认权限是读写
--mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \
挂载时主机目录的默认权限时只读
docker inspect 容器名 #查看容器的信息
挂载一个本地文件作为数据卷
docekr run --rm -it \
--mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
ubuntu:22.04 \
bash
跟挂载一个目录作为数据卷一致,标红位置表示 $HOME是一个环境变量,是指指向当前用户家目录下的home history
docker网络配置
默认bridge网络配置
在docker启动时,他会自动在主机上配置一个docekr0虚拟网桥,实际上就是Linux中的一个bridge,同时docker会随机分配一个本地未占用的私有网段给bridge0接口,后续启动的容器内的网口也会自动分配一个同网段的地址。
当创建一个docker容器时,同时创建了一对 veth pair接口,这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
docker数据包的通信方式:
数据包从容器中发出--通过veth pair接口进行传播--到达宿主机网桥--转发到外部网络
用户自定义网络
使用默认的网络配置时,两个容器之间剋通过IP地址通信,但是不能通过容器名通信,所有可以自己创建自定义网络
创建一个自定义的bridge网络:
docker networks create 网络名称
这个桥接网络有哪些配置:
网络参数:子网:docker自动分配一个未使用的私有的IP网段(通常为172.xx.xx.xx格式)
网关:自动设置为该子网的第一个IP地址
IP地址池:自动从子网中分配可用的IP范围
MTU:继承docker守护进程的默认MTU
容器间可以互相通信:连接到此网络的所有设备可以互相通信
服务发现:docker内置DNS服务,允许容器通过容器名称互相解析
网络隔离:与其他docker网络隔离,提供安全边界
无ingress模式:不支持跨docker守护进程的网络通信
创建容器时指定到自己使用的网络
docker run -d --name 容器名 --network 自定义网络名 镜像名 sleep infinity
sleep infinity 表示该容器进入休眠状态,但是可以被命令唤醒,可以响应命令
高级网络配置:配置DNS
在容器中可以使用mount命令来查看挂载信息
tmpfs on /etc/resolv.conf type tmpfs #这个文件中时容器的dns配置信息
如果想要配置所有容器的dns服务器地址可以在Linux中的/etc/docker/daemon.json文件下进行添加下面的内容:
{
“dns” : [
“dns服务器地址”
“dns服务器地址”
]
}
修改完这个文件之后,每次新建启动容器时,容器的dns服务器地址就会默认为这个地址
如果想要修改手动指定的容器的配置,可以在使用docker run 新建容器时加入下面的参数
--hostname=主机名 它会被写入到容器内的/etc/hostname和/etc/hosts,它在容器外部看不到,不会在docker ls中显示
--dns=IP地址 添加DNS服务器到容器的/etc/resolv.conf中,让这个容器使用这个服务器来解析所有不在/etc/hosts中的主机名
--dns-search=DOMAIN 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com
定制镜像:
使用docker commit命令进行对容器的修改
docker run -d -p 9000:80 --name webserver nginx:latest
其中-p 9000:80是指将容器的80端口映射到宿主机的9000端口上,此时如果想访问这个容器中的nginx服务则需要在浏览器中搜索http://宿主机IP地址:9000才可以访问。
易错点:
在浏览器中访问http://宿主机IP地址:9000无法访问容器的nginx服务,需要先看一下宿主机的防火墙的9000端口是否开放,如果不开放则无法访问这个服务。
nginx服务的默认界面如何修改
在CentOS/RHEL 系统中nginx的默认界面的文件是/usr/share/nginx/html/index.html
在Debian/Ubuntu 系统 中nginx的默认界面的文件是/var/www/html/index.nginx-debian.html
在里面修改内容后,重新刷新界面即可看到新的默认界面
通过使用docekr diff 容器名可以看到容器中的改动
保存下来形成镜像:
当我们运行一个容器时(不适用卷),我们对这个容器所做的所有修改会记录于容器存储层里面,Docker 提供了一个docker commit命令,可以将容器的存储层保存下来形成新的镜像,我们后续运行这个新的镜像之后,就会拥有原有容器的最后的变化。
docker commit命令的语法:
docker commit [选项] <容器id或容器名> [<仓库名>[:<标签>]]
例子:
docker commit \
--author “作者名称” \
--message “记录本次的修改内容” \
webserver \
nginx:v2.0
--author指定了修改的作者,--message指定了修改的内容
docker commit并不适用于修改镜像:
docker commit 对镜像的操作时黑箱操作,生成的镜像也是黑箱镜像,除了制作这个镜像的人,其他人根本不知道这个镜像进行了什么样的操作,并且使用docker commit命令修改镜像后会导致除了需要修改的内容还有其他许多的内容也会被更改,每一次修改镜像都会让这个镜像更加臃肿。
使用dockerfile定制镜像:
手动创建dockerfile
创建docekrfile文件
在一个空白的目录中创建一个文本文件,命名为docekrfile
dockerfile文件中必须有的指令:
FROM 容器名
RUN 命令
示例:
FROM nginx
RUN echo '
Hello, Docker!
' > /usr/share/nginx/html/index.htmlfrom表示指定基础镜像,你想以哪个镜像为基础构建新的镜像,就在from后加上镜像名称,还有一种特殊情况,scratch,虚拟镜像,表示空白的镜像,如果一scratch为基础镜像的话,意味着将不以任何镜像为基础,后面所写的指令将作为镜像的第一层开始存在。
run指令是用来执行命令行命令的有两种格式:
格式一:run <命令> 刚才示例中的格式就是这种。
格式二:run [“可执行文件”,“参数1“,”参数2”]这更像是函数调用中的格式。
Dockerfile中的每一个指令都会建立一层,每一个run都会新建立一层,然后在它上面执行命令,执行结束后commit这一层的修改,构建成新的镜像。
Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。
所以建立镜像时,最好是使用run指令,并使用&&将各个所需的命令串联起来,要提示自己 并不是再写shell脚本,而是在构建镜像。
构建镜像
需要在docekrfile文件所在目录执行 docekr build -t 新镜像名 .
在外部执行命令:
docekr build -f docekrfile文件所在目录 -t 新镜像名 docekrfile文件所在目录
想要运行docker build 创建新的镜像必须在docekrfile 文件所在的目录下执行命令(指定上下文)
上下文:docker build命令构建镜像,不是在本地构建,而是在服务器端构建,当用户构建镜像时,用户会指定构建镜像的上下文路径,docker build 命令得知这个路径后,会将该路径下的所有内容打包上传给docekr引擎,这样,docker引擎收到这个上下文包后,就会展开获得构建镜像所需的一切文件
docker build 的其他用法
直接用Git repo进行构建:
docekr build还支持从URL构建,比如可以直接从Git repo中构建
docker build -t hello-world https://github.com/docker-library/hello-world.git#master:amd64/hello-world
这行命令指定了构建所需的 Git repo,并且指定分支为 master,构建目录为 /amd64/hello-world/,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建。
使用给定的tar压缩包构建:
docker build http://server/context.tar.gz
---
- 首先从http://server/context.tar.gz下载tar归档文件。
- 将该归档文件解压到临时目录作为构建上下文
- 在解压后的跟目录中查找dockerfiel文件
- 使用找到的dockerfiel文件构建镜像
- 构建完成后自动清理临时文件
从标准输入中读取dockerfile进行构建:
docker build - < Dockerfile 或 cat Dockerfile | docker build -
只提供Dockerfile 内容作为标准输入,但没有提供构建上下文。
仅适用于:
极简镜像(只包含from,run)
测试docekrfile语法,不能用于实际构建,不能进行copy等操作。
从标准输入中读取上下文压缩包进行构建:
docker build - < context.tar.gz
如果发现标准输入的文件格式是 gzip、bzip2 以及 xz 的话,将会使其为上下文压缩包,直接将其展开,将里面视为上下文,并开始构建。(里面必须有docekrfile,没有dockerfile是无法构建的)
dockerfile指令详解
copy复制文件
1.格式:
copy [--chown=:] [--chmod=]<源路径> <目标路径>
命令行格式,简写: copy <源路径><目标路径>
copy [--chown=:] [--chmod=][“<源路径1>”,”< --2>”…”<目标路径>”]
数组模式(函数调用模式)简写:copy [“<源路径>””<目标路径>”]
2.可选参数:
--chown=::设置复制后文件的所有者和所属组,目标用户/组必须在镜像中存在。
--chmod=:设置复制后的文件的权限。
例子:copy --chmod=644 config.json /app/
- 路径规则:
源路径:
相对于构建上下文根目录的路径
可以是单个文件,多个文件或目录
支持通配符(需要遵循Go的filepath.Match规则)
COPY hom* /mydir/(复制所有以hom开头的文件)
COPY hom?.txt /mydir/(?匹配单个字符)
目标路径:
可以是镜像中的绝对路径
也可以是相对于workdir的相对路径
如果目标路径不不存在,docker会自动创建目录结构
例子:
创建dockerfile文件:vim dockerfile
在dockerfile文件中输入:
FROM 基础镜像名
COPY 源文件 目标文件
创建镜像:docker build -t 新镜像名 .
创建容器:docker run -d --name 容器名 镜像名 sleep infinity
注意:在使用copy指令后源文件的各种元数据都会保留,如:权限,文件修改时间,如果源路径为文件夹,复制时不是直接复制该文件夹,而是将该文件夹中的内容复制到目标路径。
- 使用--link优化多阶段构建
COPY --link --from=builder /app/dist /usr/share/nginx/html--link时docker buildkit特有的优化参数,不是标准的docker的常规功能,主要作用是:
启用硬链接复制:当从一个构建阶段复制到另一个构建阶段时,如果可能,docker会创建硬链接而不是文件内容。
显著提高构建速度:避免大文件的实际复杂操作
减少硬盘的空间使用:硬链接共享相同的inode,不会占用额外的磁盘空间。
ADD更高级的复制文件
ADD跟copy的格式性质基本一致,但是在copy上添加了一些功能
例子:<源路径>可以是一个url,此时,docker会尝试下载这个连接文件放到<目标路径>去,下载的文件自动设置权限为600,如果这个权限不是想要的权限,还需要额外增加一层RUN命令来进行权限调整,如果下载的是一个安装包,需要解压,也同样需要一个RUN命令来进行解压缩,此时,可以直接使用ADD命令,自动解压<源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz这种情况,会自动解压到<目标路径>中。
其余的情况尽可能使用copy.
使用方式与copy相同
CMD容器启动命令
1.格式:
cmd指令的格式与run相似,也是两种格式:
shell格式:cmd <命令>
exec格式:cmd [“可执行文件”,”参数1”,“参数2”…]
参数列表格式:cmd[“参数1”,”参数2”…]在指定了entrypoint指令后,使用cmd指定具体的参数。
cmd指令是用于指定默认的容器主进程的启动命令的。
2.特点:在运行时可以指定新的命令来代替镜像设置中的这个默认命令,如:直接docker run -it ubuntu 的话会进入bash界面,也可以在运行时指定运行别的命令。
3.使用时注意的点:
在正常使用中一般建议使用exec格式,这类格式在解析时会解析为json数组,因此一定要用”不要用‘
使用命令格式容易出现错误比如:
CMD service nginx start
使用这条命令后会发现容器执行后就立即退出了,因为容器就是为了主进程存在的,主进程结束,容器就退出了, 这条命令会被系统理解为 CMD [“sh”,”-c”,”service nginx start”],docker会将这个容器的主进程理解为启动nginx服务这条命令,这条命令完成后,主进程结束,容器退出
ENTRYPOINT入口点
格式:
ENTRYPOINT的格式与RUN的格式一致,分为exec和shell格式。
ENTRYPOINT的目的和cmd一致,都是在指定容器启动程序及参数,ENTRYPOINT 在运行时也可以替代,需要通过docker run 的参数 --entrypoint 来指定。
当指定了ENTRYPOINT之后,cmd的含义就发生了变化,不再是直接执行的命令,而是将cmd的内容作为参数传给了ENTRYPOINT指令,格式为: ""与CMD的区别:
CMD指定的命令可以使用 docker run 镜像名 其他命令 替代,但是ENTRYPOINT无法使用这种方式被替代,使用docker run 镜像名 其他命令 会附加到ENTRYPOINT这个指令后面,除非使用docker run 的参数 --entrypoint来进行替代。- 使用ENTRYPOINT命令启动脚本
FROM alpine:3.4
RUN addgroup -S redis && adduser -S -G redis redis
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "redis-server" ]
这个dockerfile的配置指令的含义是,将CMD指令里面的内容作为参数,放进docker-entrypoint.sh这个脚本中执行。
ENV设置环境变量
- 格式
格式有两种分别是:
ENV
ENV = =...
这个命令很简单,定义了一个环境变量,它后面的所有指令,运行时都可以直接调用这里定义的的环境变量。
注意:在使用过程中,不能将此条命令写在FROM前面。
ARG构建参数:
- 格式
ARG <参数名>[=<默认值>]
ARG构建参数和ENV效果一致,但是ARG所构建的环境的环境变量,在容器运行的时候是不会存在的。但是不要使用ARG保存密码之类的,因为docker history 是可以看到的。
ARG指令是定义参数名称以及其默认值的,该值可以被在构建镜像的过程中使用命令docker build --build-arg <参数名>=<值>来覆盖。
- 使用范围
ARG构建参数可以在from之前定义构建参数,也可以在from之后构建定义参数,效果不同,在多阶段构建时,如果使用docker build --build-arg <参数名>=<值>来覆盖这个参数的话,会在每个阶段都覆盖这个值。
ARG在from前构建定义参数:
只作用于from这一个指令,不能嵌套使用ARG,只能定义一个ARG参数,并且如果多阶段构建的话,阶段二无法识别这个构建参数,需要重新定义。
ARG在FROM后构建定义参数:
作用于当前阶段的后续指令,仅在当前阶段生效,可以嵌套使用ARG参数,可以定义多个ARG指令,但是如果多阶段构建的话,需要重新声明这个定义。
例子:
docker build --build-arg DDD=nginx:latest -t nginx:v5 .
这个是覆盖ARG构建的参数的指令
VOLUME定义匿名卷
- 格式
volume 路径1,路径2可以将路径1和路径2挂在为匿名卷,不用在容器外使用复杂的命令挂载。
注意:在docekrfile中无法指定特定的目录作为匿名卷,但是可以使用docker run -d -v 命令将命名卷挂载到匿名卷的位置,替代了dockerfile中的匿名卷的挂载配置。
EXPOSE暴露端口 - 格式
EXPOSE 端口1 端口2 - 作用
声明服务运行时提供服务的端口,这只是一个声明,在容器运行时不会因为这个声明应用就开启这个端口。只是声明这个容器打算使用什么端口
如果在运行容器时使用随即映射端口时,docker run -p时,会自动随机映射到expose端口。
WORKDIR指定工作目录
1.常见错误示例
dockerfile不等于shell脚本,常见错误示例:
RUN cd /app
RUN echo “hello” > work.txt
如果将这个dockerfile构建镜像并运行之后,会发现找不到/app/work.txt文件,或者其内容不是hello,原因是:dockerfile的RUN命令是启动一个容器,执行命令,然后提交存储层文件变更,形成新的一层,到第二个RUN执行时启动的是一个新的容器,跟第一个容器没有任何关系,所以运行失败。
所以这个指令可以改为:
WORKDIR /app
RUN echo “hello” > work.txt
此处使用绝对路径。
2.格式
WORKDIR 绝对路径
USER指定当前用户
- 格式
USER 用户名 #这种情况下是默认使用该用户名的主组。
USER 用户名:用户组
注意,这个用户必须是事先建立好的,否则无法切换。 - 作用
USER指令和WORKDIR相似,都是改变环境状态并且影响后续的层,WORKDIR是改变工作目录,USER是改变之后的层运行命令的身份。
使用gosu在脚本中按需切换
HEALTHCHECK 健康检查
- 格式
HEALTNCHECK 选项 CMD 命令 #设置检查容器健康状态的命令
HEALTHCHECK NONE 如果基础镜像有检查命令,使用该指令可以屏蔽掉检查指令。
HEALTHCHECK 支持一下选项:
--interval=<间隔> # 两次检查的时间间隔,默认为30S
--timeout=<时间>#健康检查命令运行超时,时间超过这个时间检查视为失败,默认时间30S
--retries=<次数>#当连续失败指定次数后,容器视为unhealthy,默认次数为3次。
和CMD,ENTRYPOINT一样,HEALTHCHECK只能出现一次,出现多次的话只有最后一个生效 - 例子
FROM nginx:latest
RUN apt update && apt install -y curl && rm -rf /var/lib/apt/lists/* #清理ATP包管理器的缓存索引文件,以减小镜像体积。
HEALTHCHECK --interval=5s --timeout=3s #设置检查的间隔时间为5S,超时时间为3S
CMD curl -fs http://localhost/ || exit 1 #使用crul来判断健康值。
运行这个容器之后,我们可以通过docker container ls 查看最初的状态为 health:starting
再等几秒后再次使用这个指令,可以看到状态为:healthy
为了排除故障,健康检查命令的输出(包括stdout,stdeer)都会储藏在健康状态里面,可以使用docker inspect来查看
ONBUILD 延迟执行 - 格式
ONBUILD <其他指令>
当使用这个指令时,在当前构建镜像的过程中该指令后面的其他指令并不会运行,但是当使用这个镜像为基础搭建一个新的镜像时,这个指令后面的指令会执行。
Docker compose
简介
compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关的应用容器为一个项目。
Compose模板文件采用YAML格式,扩展名为.yml或.yaml。
Compose中有两个重要的概念:
服务(service):一个应用的容器,实际上可以包含若干运行相同镜像的容器实例。
项目(project):由一组相关联的应用容器组成的一个完整的业务单元,在docker-compose.yml模板文件中定义。
Compose默认管理的对象是项目,通过子命令对项目中的一组容器进行便捷的生命周期管理
安装与卸载
安装:apt install docker-compose
查看版本信息:docker-compose -version
卸载docker-compose : rm /usr/local/bin/docker-compose
使用
想要使用docker compose运行服务,需要先新建文件夹,在目录中编写app.py文件,然后编写Dockerfile文件,最后编写docker-compose.yml文件。
- 编写app.py文件的作用是:
包含实际要运行的应用程序逻辑(例如一个简单的flask应用)
是整个项目的核心内容,没有它容器就没有实际功能 - 为什么先创建它:
要先有应用程序代码,才能将其容器化,这是整个流程的起点-先有应用再考虑如何部署 - 编写Dockerfile文件的目的是:
定义如何从基础镜像中构建出你的应用程序的镜像
指定环境配置,依赖安装和启动命令
将应用程序文件复制到最终镜像里面 - 为什么接下来创建它:
Dockerfile知道你的应用文件(app.py)在哪里,以及如何运行它,它将应用程序打包成一个可以移植的镜像 - docker-compose.yml(编排配置文件)的作用:
指定多容器应用的配置和服务关系
指定如何构建和运行容器(端口映射,环境变量等)
简化复杂的docker run 指令 - 为什么最后创建它:
Docker compose配置依赖于前两个文件-他要知道Dockerfile在哪里,而Dockerfile又依赖于app.py
docker compose 命令的运行原理:
在使用docker compose up 指令时,docker-compose.yml文件中的build指令并不会构建镜像,只是声明镜像时如何构建的,实质上在运行docker compose up 命令时,并不会创建一个新的镜像,会基于已有的镜像去创建服务,如果dockerfile文件中声明的镜像不存在,那么命令会退出,并不会自己创建镜像,当使用docker compose up --build(docker compose build)命令时,会跟据dockerfile文件中的声明创建镜像。
命令说明
运行compose项目:docker compose up
需要跟docker-compose.yml等文件在同一目录
后台运行:docker compose up -d
停止: docker compose stop
启动: docker compose start
删除: docker compose down
进入服务:docker compose exec 项目名 sh
查看日志:docker compose logs -f # -f是指持续监听
构建镜像:docker compose build #根据Dockerfile 文件中的声明来创建镜像
运行一次性命令:docker compose run web python app.y
注意:这个命令会基于web服务的配置(来自docker-compose.yml)创建一个全新的,独立的容器,这个容器只执行这一个命令,当命令完成之后(无论成功还是失败),这个容器都会自动停止,不会自动删除。格式:docker compose run 选项 服务名 命令
验证docker-compose.yml文件:docker compose config #错误会显示原因
docker compose --help查看其他的docker compose命令
列出compose文件中包含的镜像:docker compose images
强行停止服务:docker compose kill -选项 服务 可以通过-s指令来指定发送的信号。
暂停服务:docker compose pause
暂停与停止的区别:暂停时端口依旧被占用,进程依旧在内存中,只是不运行,恢复速度较快;停止是端口释放,释放全部内存资源,恢复速度较慢。
打印某个容器所映射的公共端口:docker compose port 服务 端口号
这个命令的实际含义是查看该服务的这个端口映射到宿主机上的哪个端口
选项 --protocol=TCP/UDP指定端口协议
拉取服务所依赖的镜像:docker compose pull
这个命令的作用是在docker compose up之前拉取所需镜像,防止因为网络问题或镜像问题而导致up失败
docker compose push :是将这个服务的所有依赖的镜像推送到docker 仓库中,方便后续有任何问题,进行回退,这个命令值推送镜像,不推送docker-compose.yml配置文件。