1 安装步骤
1.1 安装Docker
1.1.1 安装说明
- 系统版本:64位ubuntu操作系统的18.04.2版本(ubuntu-18.04.2-desktop-amd64)。
- 安装步骤:如果系统中已经安装有其它较低版本的Docker,则需要先卸载掉,安装新版本之前需要先设置Docker仓库,设置完Docekr仓库之后再安装Docker引擎,安装完之后再进行用户设置。
1.1.2 卸载旧版
- 卸载旧版:
$ sudo apt-get remove docker docker-engine docker.io containerd runc
1.1.3 设置Docker仓库
- 步骤一:更新apt包索引:
sudo apt-get update
- 步骤二:安装相应的包使得apt能够通过HTTPS使用Docker仓库:
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
- 步骤三:添加Docker官方GPG Key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- 步骤四:验证GPG Key:
如果打印如下结果则成功:sudo apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ unknown] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]
- 步骤五:设置Docker的APT仓库:
sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
1.1.4 安装Docker引擎
- 步骤一:更新apt包索引:
sudo apt-get update
- 步骤二:安装最新版本的Docker(步骤二和步骤三根据需求选其一):
sudo apt-get install docker-ce docker-ce-cli containerd.io
- 步骤三:安装指定版本的Docker(步骤二和步骤三根据需求选其一):
查看可用的版本:
安装指定版本:apt-cache madison docker-ce
sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
- 步骤四:查看Docker版本:
docker version
- 步骤五:运行Docker示例:
sudo docker run hello-world
1.1.5 实用设置
- 步骤一:建立docker组:
sudo groupadd docker
- 步骤二:将当前用户追加到docker组(设置的是当前用户的附加组):
sudo usermod -aG docker ${USER}
- 步骤三:设置开机启动:
sudo systemctl start docker sudo systemctl enable docker
- 步骤四:重启Docker服务
sudo service docker restart
- 步骤五:切换当前用户到docker组
newgrp - docker
1.2 升级Docker
- 步骤一:更新apt包索引:
sudo apt-get update
- 步骤二:参照上述的Docker安装步骤,选择一个新的版本进行安装。
1.3 卸载Docker
- 步骤一:卸载Docker(不会删除镜像等文件,可使用步骤二进行删除):
sudo apt-get purge docker-ce
- 步骤二:删除Docker相关的文件:
sudo rm -rf /var/lib/docker
2 组成架构
- 仓库(Repository)、镜像(Image)和容器(Container)是Docker的三大核心概念。
2.1 仓库
- Docker仓库是集中存放镜像文件的场所,类似到Git仓库是集中存放项目代码的场所。
- 通常情况下,每个项目工程的镜像文件都保存在同一个Docker仓库中,而不同的项目工程的镜像文件则保存在不同的Docker仓库中。例如,在Docker Hub官方仓库中,mysql项目工程的镜像文件都保存在名称为mysql的这个Docker仓库中,而openjdk项目工程的镜像文件都保存在名称为openjdk的这个Docker仓库中。
- 根据所存储的镜像是否公开,Docker仓库可以分成公开仓库和私有仓库两种。目前最大的公开仓库是Docker官方提供的Docker Hub。
- 用户创建了自己的镜像之后 ,就可以使用 push 命令将自己创建的镜像文件上传到指定的公有仓库或私有仓库,当然也可以使用 pull 命令从公有仓库或私有仓库中下载已有的镜像文件到本地。
2.2 镜像
- Docker镜像是项目工程的一个特定的版本,一般由Docker仓库名称和Docker镜像标签共同来确定一个镜像。
- 通常情况下,每个项目工程都会有多个不同的版本,而同一个项目工程的镜像文件全都保存在同一个Docker仓库中,所以镜像文件之间需要使用镜像标签来进行区分。例如,在Docker Hub官方的名称为openjdk的仓库中保存了openjdk镜像的多个版本(openjdk:8-jdk-alpine、openjdk:12-jdk-alpine等)。
- Docker镜像是创建Docker容器的基础。
2.3 容器
- Docker容器是由Docker镜像创建的可运行实例,可以执行启动、开始、停止、删除等操作。
- 通常情况下,同一个Docker镜像可以创建多个Docker容器(通常也叫作 “服务”),这些Docker容器之间都是相互隔离、互不可见的。
3 镜像仓库
3.1 公共仓库
- 官方仓库:Docker Hub是Docker官方提供的最大的公共镜像仓库,官方地址为:https://hub.docker.com。
- 基本操作:用户无须登录即可通过 docker search 命令来查找官方仓库中的镜像,并通过 docker pull 命令来将官方仓库中的镜像下载到本地,但想要把本地的镜像上传到Docker Hub仓库中则需要进行登录。
3.2 登录仓库
- 注册账号:用户需要先在Docker Hub官方网站注册Docker Hub账号,然后才能使用 docker login命令进行登录。
- 命令语法:
docker login [OPTIONS] [SERVER]
- 命令选项:
选项 说明 -u username 账户名 -p password 账户密码 - 命令示例:
# 登录到Docker Hub注册服务器中的个人仓库(运行命令后根据提示输入Docker Hub账户和密码) docker login # 登录到registry.mind.cn注册服务器中的私有仓库(运行命令后根据提示输入账户和密码) docker login registry.mind.cn
3.3 登出仓库
- 命令语法:
docker logout [SERVER]
- 命令示例:
# 登出Docker Hub注册服务器中的个人仓库 docker logout # 登出registry.mind.cn注册服务器中的私有仓库 docker logout registry.mind.cn
4 镜像命令
- Docker镜像的存储路径:
/var/lib/docker
4.1 创建镜像 build
-
命令功能:通过DockerFile文件创建Docker镜像。
-
命令语法:
docker build [OPTIONS] PATH | URL | -
-
命令选项:
选项 说明 -f, --file=“path/DockerFile” 指定用于构建镜像的DockerFile文件 -t, --tag=“name:tag” 指定构建出的镜像的名称和标签 --build-arg 设置构建变量 --force-rm=false 是否总是删除已经终止的容器 --no-cache=false 构建镜像的时候是否使用缓存 --pull=false 是否总是尝试拉取这个镜像的一个新版本 -q, --quiet=false 只打印镜像ID --rm=true 镜像构建成功后删除中间层容器(默认为true) -
命令说明:必须先有DockerFile文件。PATH用于指定生成镜像的DockerFile文件的路径;URL可以是Git仓库、压缩包文件、文本文件这三种类型的资源。- 用于指定根据标准输入中的DockerFile指令来生成镜像。
-
命令示例:
DockerFile文件如下:# Docker File Demo FROM ubuntu:14.04 MAINTAINER admin "admin@163.com" RUN apt-get update RUN apt-get install -y nginx EXPORT 80
构建Docker镜像:
# 根据路径来创建镜像 # 根据当前目录下的DockerFile文件创建一个镜像 docker build . # 根据当前目录下的DockerFile文件创建一个镜像:指定生成的镜像名称为myrepository/commit_test1 docker build -t myrepository/commit_test1 . # 根据当前目录下的DockerFile文件创建两个镜像:指定生成的镜像名称分别为myrepository/commit_test1和myrepository/commit_test2 docker build -t myrepository/commit_test1 -t myrepository/commit_test2 . # 根据/home/admin目录下的DockerFile文件创建一个镜像 docker build -f /home/admin/Dockerfile . # 根据URL来创建镜像 # 根据Git仓库类型的URL来创建一个镜像:根据rootfs.git这个Git仓库的container分支中的docker目录来创建镜像 docker build https://github.com/docker/rootfs.git#container:docker # 根据压缩包文件类型的URL来创建一个镜像 docker build http://server/context.tar.gz # 根据纯文本文档类型的URL来创建一个镜像:使用的是ctx.tar.gz压缩包中的ctx/DockerFile文件 docker build -f ctx/Dockerfile http://server/ctx.tar.gz # 根据标准输入来创建镜像 # 根据标准输入中的指令来创建镜像:指令来源于本地DockerFile文件 docker build - < Dockerfile # 根据标准输入中的指令来创建镜像:指令来源于压缩包文件 docker build - < context.tar.gz # 根据标准的指令来创建镜像:指令来源于URL地址 curl example.com/remote/Dockerfile | docker build -f - . # 创建镜像时指定构建参数 docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 --build-arg FTP_PROXY=http://40.50.60.5:4567 .
4.2 搜索镜像 search
- 命令功能:从远程的Docker仓库中搜索Docker镜像。
- 命令语法:
docker search [OPTIONS] TERM
- 命令选项:
选项 说明 -f, --filter 搜索符合指定过滤条件的镜像 --format="" 使用go模板格式化的打印出搜索到的镜像信息 --limit 搜索结果的最大数量 –no-trunc=false 不使用截断的形式显示搜索到的镜像信息 - 命令说明:还可以直接手动从Docker Hub中直接搜索Docker镜像:https://registry.hub.docker.com
- 命令示例:
# 搜索名称为openjdk的镜像 docker search openjdk # 搜索名称为openjdk且是自动构建的镜像 docker search --filter is-automated openjdk # 搜索名称为openjdk且是官方的镜像 docker search --filter "is-official=true" openjdk # 使用go模板格式化的打印出搜索到的名称为nginx的的镜像的信息,只打印镜像名称和镜像获得的Star数量等信息 docker search --format "{{.Name}}: {{.StarCount}}" nginx # 使用go模板格式化的打印出搜索到的名称为nginx的的镜像的信息,只打印镜像名称、是否是自动构建的镜像、是否是官方镜像等信息 docker search --format "table {{.Name}}\t{{.IsAutomated}}\t{{.IsOfficial}}" nginx
4.3 拉取镜像 pull
- 命令功能:从远程的Docker仓库中拉取Docker镜像。
- 命令语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
- 命令选项:
选项 说明 -a, --all-tags=false 拉取仓库中所有有标签的指定镜像 --disable-content-trust 跳过镜像验证过程 -q, --quiet 不打印详细输出 - 命令说明:可以设置从国内的镜像仓库中拉取,可以提高速度。
- 命令示例:
# 从Docker Hub官方注册服务器中的ubuntu仓库中拉取镜像 docker pull ubuntu # 从Docker Hub官方注册服务器中的ubuntu仓库中拉取标签为14.04的镜像 docker pull ubuntu:14.04 # 从Docker Hub官方注册服务器中的ubuntu仓库中拉取摘要为sha256:45b23dee08af5e43a7fea6c...的镜像 docker pull ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2 # 从registry.mind.cn这个注册服务器的openjdk仓库中拉取标签为8-jdk-alpine的镜像 docker pull registry.mind.cn/openjdk:8-jdk-alpine # 从javabigdata这个注册服务器的openjdk仓库中拉取标签为8-jdk-alpine的镜像(javabigdata是Docker Hub账户ID) docker pull javabigdata/openjdk:8-jdk-alpine # 从Docker Hub官方注册服务器中的ubuntu仓库中拉取所有有标签的镜像 docker pull --all-tags ubuntu
4.4 推送镜像 push
- 命令功能:把本地的Docker镜像推送到远程的Docker仓库中。
- 命令语法:
docker push [OPTIONS] NAME[:TAG]
- 命令选项:
选项 说明 --disable-content-trust 跳过镜像签名 - 命令说明:推送镜像之前,需要先使用 docker tag 命令把要上传的镜像打标签,打的标签名称格式为:注册服务器地址/仓库名称/标签,然后再推送打标签后的镜像。
- 命令示例:
# 把本地的名称为openjdk:8-jdk-alpine的镜像推送到Docker Hub官方注册服务器中的openjdk仓库中 docker push openjdk:8-jdk-alpine # 把本地的名称为ubuntu/nginx的镜像推送到ubuntu这个注册服务器中的nginx仓库中 docker push ubuntu/nginx # 把本地的名称为openjdk:8-jdk-alpine的镜像推送到registry.mind.cn这个注册服务器中的openjdk仓库中 docker push registry.mind.cn/openjdk:8-jdk-alpine # 把本地的名称为openjdk:8-jdk-alpine的镜像推送到javabigdata这个注册服务器中的openjdk仓库中(javabigdata是Docker Hub账户ID) docker push javabigdata/openjdk:8-jdk-alpine
4.5 镜像列表 images
- 命令功能:查看本地的Docker镜像列表。
- 命令语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
- 命令选项:
选项 说明 -a, --all=false 显示所有镜像,默认不显示中间层镜像 -f, --filter=[] 过滤条件 --format 使用go模板格式化地打印镜像列表 --no-trunc=false 不使用截断的形式显示数据 -q, --quiet=false 只显示镜像的ID - 命令示例:
# 查看本地所有的镜像 docker images # 查看本地所有的名称为openjdk的镜像 docker images openjdk # 查看本地所有的名称和标签为openjdk:8-jdk-alpine的镜像 docker images openjdk:8-jdk-alpine # 查看本地所有的镜像的完整信息 docker images --no-trunc # 查看符合过滤条件的所有镜像的信息 docker images --filter "dangling=true" docker images --filter "label=com.example.version" docker images --filter "label=com.example.version=1.0" # 使用go模块格式化地打印出所有镜像的信息,只打印镜像ID和镜像仓库等信息 docker images --format "{{.ID}}: {{.Repository}}"
4.6 镜像详情 inspect
- 命令功能:查看指定的本地的Docker镜像的具体信息。
- 命令语法:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
- 命令选项:
选项 说明 -f, --formate 使用go模板格式化地打印镜像的具体信息 --type 返回指定类型的JSON数据 - 命令示例:
# 查看openjdk:8-jdk-alpin这个镜像的具体信息 docker inspect openjdk:8-jdk-alpine # 查看镜像的IP地址 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' openjdk:8-jdk-alpine # 查看镜像的日志路径 docker inspect --format='{{.LogPath}}' openjdk:8-jdk-alpine # 查看openjdk:8-jdk-alipne这个镜像的摘要信息 docker inspect --format='{{.Config.Image}}' openjdk:8-jdk-alpine # 查看指定端口映射 docker inspect --format='{{(index (index .NetworkSettings.Ports "8787/tcp") 0).HostPort}}' openjdk:8-jdk-alpine # 返回JSON格式的数据 docker inspect --format='{{json .Config}}' openjdk:8-jdk-alpine
4.7 镜像历史 history
- 命令功能:把本地的Docker镜像的各层的创建信息。
- 命令语法:
docker histroy [OPTIONS] IMAGE
- 命令选项:
选项 说明 --no-trunc 不使用截断的形式显示镜像的各层的创建信息 -H 使用易于理解的格式打印镜像大小和日期等信息 - 命令说明:
- 命令示例:
# 查看本地的openjdk:8-jdk-alpine镜像的各层的创建信息 docker histroy openjdk:8-jdk-alpine # 查看本地的openjdk:8-jdk-alpine镜像的各层的创建信息 docker histroy --no-trunc openjdk:8-jdk-alpine
4.8 删除镜像 rmi
- 命令功能:删除本地的指定的Docker镜像。
- 命令语法:
docker rmi [OPTIONS] IMAGE [IMAGE...]
- 命令选项:
选项 说明 -f, --force=false 强制删除镜像 --no-prune=false 不删除没有标签的父镜像 - 命令说明:IMAGE即可以是REPOSITORY:TAG,也可以是IMAGE ID。使用REPOSITORY:TAG进行删除时,如果要删除的镜像有多个标签,则只会删除指定的标签,而不会删除镜像文件。使用IMAGE ID进行删除时,如果会先删除镜像的所有标签,然后删除镜像文件。
- 命令示例:
# 删除名称和标签为ubuntu:14.04的镜像 docker rmi ubuntu:14.04 # 强制删除ID为fd484f19954f的镜像 docker rmi -f fd484f19954f
4.9 清理镜像 prune
- 命令功能:清除本地Docker中的一些遗留的临时的镜像文件和一些没有使用的镜像。
- 命令语法:
docker image prune [OPTIONS]
- 命令选项:
选项 说明 -f, --force=false 强制删除镜像 -a 删除所有无用镜像,不光是临时镜像 --filter filter 只清理符合给定过滤器的镜像 - 命令示例:
# 强制清理所有没有使用的镜像 docker image prune -f
4.10 镜像标签 tag
- 命令功能:给镜像创建标签。
- 命令语法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- 命令示例:
# 根据镜像ID来创建TAG标签 docker tag 0e5574283393 fedora/httpd:1.0 # 根据镜像名称来创建TAG标签 docker tag httpd fedora/httpd:1.0 # 根据镜像名称和标签来创建TAG标签 docker tag httpd:1.0 fedora/httpd:1.0
4.11 提交镜像 commit
- 命令功能:把容器的文件或设置的更改提交到一个新的镜像中。
- 命令语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- 命令选项:提交操作不会包含挂载到容器的卷中的任何数据。默认情况下,提交映像时将暂停正在提交的容器及其进程,从而降低数据出错的概率。
选项 说明 -a, --auther="" 作者信息 -m, --message="" 提交信息 -c, --change="" 将DockerFile指令应用于创建的镜像 -p, --pause=true 提交的时候暂停容器(默认为true) - 命令说明:-c 选项支持的DockerFile指令包括CMD、ENTRYPOINT、ENV、EXPOSE、LABEL、USER、VOLUME、WORKDIR。
- 命令示例:
docker run -it -p 8080 --name commit_test ubuntu /bin/bash apt-get update apt-get install nginx exit # 提交一个容器 docker commit -a "admin" -m "install nginx" commit_test1 myrepository/commit_test # 提交容器时使用新的配置:设置ENV DEBUG为true docker commit --change "ENV DEBUG true" commit_test2 myrepository/commit_test # 提交容器时使用新的DockerFile指令 docker commit --change='CMD ["apachectl", "-DFOREGROUND"]' -c "EXPOSE 80" commit_test3 myrepository/commit_test
4.12 导入镜像 import
-
命令功能:导入内容并创建一个镜像。
-
命令语法:
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
-
命令选项:
选项 说明 -c, --change 将DockerFile指令应用于创建的镜像 -m, --message 为导入的镜像设置提交信息 --platform 如果服务器支持多平台,则设置平台 -
命令示例:
# 从远程地址导入镜像 docker import http://example.com/exampleimage.tgz # 通过管道或标准输入导入镜像 cat exampleimage.tgz | docker import - exampleimagelocal:new # 导入镜像时指定提交信息 cat exampleimage.tgz | docker import --message "New image imported from tarball" - exampleimagelocal:new # 从本地文件中导入镜像 docker import /path/to/exampleimage.tgz # 从本地目录中导入镜像 sudo tar -c . | docker import - exampleimagedir # 从本地目录中导入镜像并指定新的配置 sudo tar -c . | docker import --change "ENV DEBUG true" - exampleimagedir
4.13 加载镜像 load
- 命令功能:从压缩包文件或标准输入中加载镜像。
- 命令语法:
docker load [OPTIONS]
- 命令选项:
选项 说明 -i, --input 从压缩包文件中加载镜像,而不是从标准输入中加载镜像 -q, --quiet 不打印加载信息 - 命令示例:
# 从标准输入中加载镜像 docker load < busybox.tar.gz # 从压缩包中加载镜像 docker load --input fedora.tar
4.14 保存镜像 save
- 命令功能:把镜像保存到压缩包文件中。
- 命令语法:
docker save [OPTIONS] IMAGE [IMAGE...]
- 命令选项:
选项 说明 -o, --output 把镜像写入到文件中,而不是标准输出中 - 命令示例:
# 把名称为busybox的镜像写到标准输出中 docker save busybox > busybox.tar # 把名称为busybox的镜像写到归档文件busybox.tar中 docker save --output busybox.tar busybox # 把名称为fedora的镜像写到归档文件fedora-all.tar中 docker save -o fedora-all.tar fedora # 把名称为fedora:latest的镜像写到归档文件fedora-all.tar中 docker save -o fedora-latest.tar fedora:latest # 先把名称为myimage:latest的镜像写到标准输出中,然后再使用gzip把标准输出中的镜像写入到压缩包myimage_latest.tat.gz中 docker save myimage:latest | gzip > myimage_latest.tar.gz
5 容器命令
5.1 创建容器 run
-
命令功能:创建并启动一个新的Docker容器。
-
命令语法:
# 整体语法 docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...] # 创建并启动直接运行的Docker容器 docker run IMAGE [COMMAND] [ARG...] # 创建并启动交互式的Docker容器(使用 Ctrl + P 或 Ctrl + Q 则退出交互式容器的Bash并进入后台运行) docker run -i -t IMAGE /bin/bash # 创建并启动守护式的Docker容器 docker run -d IMAGE [COMMAND] [ARG...]
-
命令选项:
选项 说明 -i 始终保持STDIN开启(即启动交互式容器),不指定该选项则默认不开启 -t 分配一个TTY终端,不指定该选项则默认不分配 -d 以后台的形式运行命令(即启动守护式容器),但是在命令结束时,容器依然会停止 -a=[ ] 连接到STDIN、STDOUT、STDERR --name=“container_name” 指定生成的容器的名称 --rm 容器结束时清除该容器的文件系统,不指定该选项则默认不清除 -P 发布所有已暴露的端口 -p=[ ] 发布容器的端口或一系列端口
有效格式:[ ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort ]-u=“user”, --user=“user” 设置运行容器的默认用户,会覆盖DockerFile文件中的USER指令设置的默认用户。
有效格式:--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]-w=“dir” 设置容器的默认工作目录,会覆盖DockerFile文件中的WORKDIR指令设置的默认工作目录。 -
命令说明:还可以通过选项来配置网络、重启策略、运行环境等,更多选项请参见:
https://docs.docker.com/engine/reference/commandline/run/
-
命令示例:
# 创建并启动直接运行的Docker容器,命令运行完成后Docker容器就结束 docker run ubuntu /bin/echo "hello world!" # 创建并启动交互式的Docker容器,然后就可以在终端中输入指令,最后以exit退出 docker run -i -t ubuntu /bin/bash # 创建并启动守护式的Docker容器 docker run -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done" # 创建Docker容器时指定始终保持STDIN和STDOUT的连接 docker run -a stdin -a stdout -i -t ubuntu /bin/bash # 创建Docker容器时指定容器的名称,并指定容器结束时清除该容器的文件系统 docker run --name dc1 -rm -i -t ubuntu /bin/bash # 创建Docker容器时指定容器的名称,并指定为主机的ip和暴露的端口 docker run --name dc1 -p 127.0.0.1:8080:8080 i -t ubuntu /bin/bash # 创建Docker容器时指定用户和组 docker run -u root:root -t -t ubuntu /bin/bash # 创建Docker容器时指定工作目录 docker run -w /path/to/dir/ -i -t ubuntu /bin/bash
5.2 启动容器 start
- 命令功能:启动某个停止的Docker容器。
- 命令语法:
docker start [OPTIONS] CONTAINER [CONTAINER...]
- 命令选项:
选项 说明 -i, --interactive=true 始终保持STDIN开启,如果不指定该选项则默认不开启 -a, --attach=true 始终保持STDOUT、STDERR开启,如果不指定该选项则默认不开启 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 启动名称为dc1的容器 docker start -i dc1
5.3 重启容器 restart
- 命令功能:重新启动正在运行的某个Docker容器。
- 命令语法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
- 命令选项:
选项 说明 -t, --time 重启之前等待多少秒,默认等待10秒 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 重启名称为dc1的容器 docker restart -t 20 dc1
5.4 停止容器 stop
- 命令功能:向本地的某个正在运行的Docker容器发送停止信号,并等待该Docker容器结束。
- 命令语法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
- 命令选项:
选项 说明 -t, --time 发送停止信号之前等待多少秒,默认等待10秒 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
docker stop my_container
5.5 强停容器 kill
- 命令功能:强制结束本地的某个正在运行的Docker容器。
- 命令语法:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
- 命令选项:
选项 说明 -s, --signal 向容器发送的信号 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
docker kill my_container docker kill --signal=SIGHUP my_container docker kill --signal=HUP my_container docker kill --signal=1 my_container
5.6 删除容器 rm
- 命令功能:删除本地的某个已经停止的Docker容器。
- 命令语法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
- 命令选项:
选项 说明 -f, --force 强制删除正在运行的容器 -l, --link 删除指定的链接 -v, --volumes 删除与该容器相关的卷 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 删除/redis下的容器 docker rm /redis # 删除/webapp/redis下的容器 docker rm --link /webapp/redis # 强制删除名称为redis的容器 docker rm --force redis # 删除所有已停止的容器 docker rm $(docker ps -a -q) # 删除名称为redis的容器以及该容器的卷 docker rm -v redis
5.7 进入容器 attach
- 命令功能:重新进入到正在后台运行的某个Docker容器。
- 命令语法:
docker attach [OPTIONS] CONTAINER
- 命令选项:
选项 说明 --no-stdin 不开启STDIN - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 进入正在后台运行的名称为dc1的容器 docker attach dc1
5.8 容器列表 ps
- 命令功能:列出本地的Docker容器列表。
- 命令语法:
docker ps [OPTIONS]
- 命令选项:
选项 说明 -a, --all 列出所有的容器,默认只列出还正在运行的容器 -l, --latest 列出最新创建的容器,默认不列出最新创建的容器 -f, --filter 设置过滤条件 --no-trunc 设置显示完整的信息,而不是截断的部分信息 –quiet , -q 只显示容器的ID - 命令示例:
docker -ps docker -ps -al docker -ps -no--trunc -al docker ps --filter "label=color" docker ps --filter "name=nostalgic_stallman"
5.9 容器详情 inspect
- 命令功能:查看本地的某个Docker容器的具体信息。
- 命令语法:
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
- 命令选项:
选项 说明 -f, --format 使用给定的GO模板格式化输出 -s, --size 显示所有容器的总文件大小 --type 返回指定类型的JSON - 命令示例:
# 查看容器的IP地址 docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_ID # 查看容器的日志路径 docker inspect --format='{{.LogPath}}' $INSTANCE_ID # 查看构建容器的镜像的名称 docker inspect --format='{{.Config.Image}}' $INSTANCE_ID # 查看指定的端口映射 docker inspect --format='{{(index (index .NetworkSettings.Ports "8787/tcp") 0).HostPort}}' $INSTANCE_ID # 返回JSON格式的字段信息 docker inspect --format='{{json .Config}}' $INSTANCE_ID
5.10 容器状态 stats
- 命令功能:查看本地的某个Docker容器的CPU、内存、存储、网络等使用情况的统计信息。
- 命令语法:
docker stats [OPTIONS] [CONTAINER...]
- 命令选项:
选项 说明 -a, --all 输出所有容器的统计信息,默认仅输出在运行的容器的统计信息 --format string 格式化输出信息 --no-stream 不持续输出,默认会自动更新持续实时结果 --no-trunc 不截断输出信息 - 命令示例:
# 查看当前运行的所有容器的统计信息 docker stats
5.11 导出容器 export
- 命令功能:把容器导出为本地tar文件。
- 命令语法:
docker export [OPTIONS] CONTAINER
- 命令选项:
选项 说明 -o, --output 指定写出到文件而不是STDIN - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 使用输出重定向符号把red_panda容器导出为latest.tar文件 docker export red_panda > latest.tar # 使用选项指定把red_panda容器导出为本地latest.tar文件 docker export --output="latest.tar" red_panda
5.12 容器日志 logs
- 命令功能:查看本地的某个正在运行的Docker容器的运行日志。
- 命令语法:
docker logs [OPTIONS] CONTAINER
- 命令选项:
选项 说明 -f, --follows=true 跟踪日志变化并返回结果,不指定该选项则默认不跟踪日志变化 -t, --timestamps=true 返回结果加上时间戳,不指定该选项则默认不加时间戳 -- tail=“all” 表示返回日志文件结尾处多少行日志 --details 显示提供给日志的额外详细信息 --since 显示时间戳或相对时间戳之后的日志 --until 显示时间戳或相对时间戳之前的日志 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 显示最新的10行日志 docker logs -ft --tail 10 dc1 # 显示最新的1行日志 docker logs -ft --tail 0 dc1 # 显示相对当前时间之前2秒的日志,并持续跟踪日志变化 docker logs -f --until=2s
5.13 容器进程 top
- 命令功能:查看本地的某个正在运行的Docker容器内部的进程。
- 命令语法:
docker top CONTAINER [ps OPTIONS]
- 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 查看名称为dc1的容器的内部的进程 docker top dc1
5.14 创建进程 exec
- 命令功能:在本地的某个正在运行的Docker容器的内部创建一个新的进程。
- 命令语法:
docker exec [-d] [-i] [-t] 容器ID或名称 [COMMAND] [ARG...] docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- 命令选项:
选项 说明 -i, --interactive 始终保持STDIN开启(即启动交互式容器),不指定该选项则默认不开启 -t, --tty 分配一个TTY终端,不指定该选项则默认不分配 -d, --detach 以后台的形式运行命令(即启动守护式容器),但是在命令结束时,容器依然会停止 -e, --env 设置环境变量 -u, --user 设置执行用户 -w, --workdir 设置工作目录 - 命令说明:语法中的CONTAINER即可以是容器的名称,也可以是容器的ID。
- 命令示例:
# 前提条件:先创建一个名称为ubuntu_bash的交互式Docker容器 docker run --name ubuntu_bash --rm -i -t ubuntu bash # 在名称为ubuntu_bash的容器中创建一个文件/tmp/execWorks docker exec -d ubuntu_bash touch /tmp/execWorks # 在名称为ubuntu_bash的容器中创建一个交互式的Bash进程 docker exec -it ubuntu_bash bash # 在名称为ubuntu_bash的容器中创建一个交互式的Bash进程,并指定环境变量VAR(这个环境变量是在新建的这个Bash进程中有效) docker exec -it -e VAR=1 ubuntu_bash bash # 默认情况下在名称为ubuntu_bash的容器中创建的进程的工作目录与ubuntu_bash容器的工作目录相同 docker exec -it ubuntu_bash pwd # 在名称为ubuntu_bash的容器中创建一个进程,并指定创建的进程的工作目录 docker exec -it -w /root ubuntu_bash pwd
6 DockerFile
6.1 文件说明
- 文件格式:
# Comment INSTRUCTION arguments
- 格式说明:DockerFile文件是由一系列指令组成,且必须以FROM指令开始,用于指定基础镜像。DockerFile文件中的指令会按照顺序依次执行,为了区分指定和参数,要求指定名称全大小,参数小写。以#开头的行会被视为注释,而行中的#会被视会参数。
- 文件示例:
示例一:
示例二:# Nginx # # VERSION 0.0.1 FROM ubuntu LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0" RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
示例三:# Firefox over VNC # # VERSION 0.3 FROM ubuntu # Install vnc, xvfb in order to create a 'fake' display and firefox RUN apt-get update && apt-get install -y x11vnc xvfb firefox RUN mkdir ~/.vnc # Setup a password RUN x11vnc -storepasswd 1234 ~/.vnc/passwd # Autostart firefox (might not be the best way, but it does the trick) RUN bash -c 'echo "firefox" >> /.bashrc' EXPOSE 5900 CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example # # VERSION 0.1 FROM ubuntu RUN echo foo > bar # Will output something like ===> 907ad6c2736f FROM ubuntu RUN echo moo > oink # Will output something like ===> 695d7793cbe4 # You'll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with # /oink.
6.2 基础镜像 FROM
-
指令功能:DockerFile文件中的指令必须以FROM指令开始,用于指定基础镜像。
-
指令语法:
# 语法一:指定镜像的名称 FROM <image> [AS <name>] # 语法二:指定基础镜像的标签(默认为latest) FROM <image>[:<tag>] [AS <name>] # 语法三:指定基础镜像的摘要 FROM <image>[@<digest>] [AS <name>]
-
指令说明:可以在同一个DockerFile文件中多次使用FROM指令,以创建多个镜像,或将一个构建阶段用作另一个构建阶段的依赖项,只需在每个新的FROM指令之前记录commit输出的最后一个镜像ID,每条FROM指令都会清除之前的指令创建的任何状态。ARG指令是唯一一个可以出现在FROM指令之前的指令,在FROM指令中可以引用在第一个FROM指令之前声明的ARG参数,在FROM指令之前声明的ARG参数不在生成阶段中,因此不能在FROM指令之后的任何指令中使用ARG参数。
-
指令示例:
# 一个ARG指令和多个FROM指令示例 ARG CODE_VERSION=latest FROM base:${CODE_VERSION} CMD /code/run-app FROM extras:${CODE_VERSION} CMD /code/run-extras --------------------------------- # 多个ARG指令和一个FROM指令示例 ARG VERSION=latest FROM busybox:$VERSION ARG VERSION RUN echo $VERSION > image_version
6.3 数据标签 LABEL
- 指令功能:LABEL指令用于把元数据标签添加到镜像中,而元数据标签是键值对格式的标签。
- 指令语法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
- 指令说明:要在标签值中包含空格,需要使用引号和反斜杠。一个镜像中可以包含多个标签,并且可以在一个LABLE指令中声明多个标签。可以从基础镜像或父镜像中继承标签,如果标签已经存在但具有不同的值,则最近设置的值会重写任何先前设置的值。
- 指令示例:
# 在一个LABEL指令中只声明一个标签 LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines." # 在同一个LABEL指令中,把多个标签声明在同一行中 LABEL multi.label1="value1" multi.label2="value2" other="value3" # 在同一个LABEL指令中,把多个标签声明在多行中 LABEL multi.label1="value1" \ multi.label2="value2" \ other="value3"
6.4 维护作者 MAINTAINER
- 指令功能:MAINTAINER指令用于设置生成的镜像的作者信息字段。
- 指令语法:
MAINTAINER <name>
- 指令说明:LABEL指令更加灵活,它能够设置任何元数据,并且很容易就可以查看,所以应优先使用LABEL指令来设置作者信息。
- 指令示例:
LABEL maintainer="SvenDowideit@home.org.au"
6.5 构建变量 ARG
- 指令功能:ARG指令用于定义构建变量,用户在使用docker build命令构建镜像时可以使用--build-arg <varname>=<value>选项向这个构建变量传递变量值。
- 指令语法:
# 定义构建变量语法: ARG <name>[=<default value>] # 运行时向构建变量传递值的语法 docker build --build-arg <varname>=<value> .
- 指令说明:如果传递的构建变量在DockerFile中没有定义,则会抛出一个警告。DockerFile中可以定义多个构建变量。不建议使用构建变量传递密码等敏感信息,因为任何用户都可以使用docker history命令查看镜像的构建变量的值。构建变量可以指定默认值。构建变量从它定义的位置开始生效,而不是从它被使用的位置开始生效,并且在当前阶段结束时失效,如果要在多个阶段中都使用同一个构建变量,则需要在每个阶段中声明该构建变量。使用ENV指令声明的环境变量的值会覆盖使用ARG指令声明的同名的构建变量的值。ARG构建变量的值不会保存在构建的镜像中,而ENV环境变量的值会保存在构建的镜像中。
- 指令示例:
# 定义两个构建变量 FROM busybox ARG user1 ARG buildno # 定义构建变量时指定默认值 FROM busybox ARG user1=someuser ARG buildno=1 # 构建变量范围示例 FROM busybox USER ${user:-some_user} # 这里的USER的值是some_user ARG user USER $user # 这里的USER的值是实际传递给构建变量user的值 # 在多个阶段中使用构建变量示例 FROM busybox ARG SETTINGS RUN ./run/setup $SETTINGS FROM busybox ARG SETTINGS RUN ./run/other $SETTINGS # EVN环境变量的值覆盖ARG构建变量的值的示例 FROM ubuntu ARG CONT_IMG_VER ENV CONT_IMG_VER v1.0.0 RUN echo $CONT_IMG_VER # 这里打印CONT_IMG_VER的值为v1.0.0,而不是使用 --build-arg CONT_IMG_VER=v2.0.1 传递的v2.0.1
- 特别说明:Docker提供了一些预定义的构建变量,用户可以不用在DockerFile中定义而直接使用,在使用docker history命令时,不会打印出这些预定义的构建变量的信息,以防止敏感信息泄露。这些预定义的构建变量包括:HTTP_PROXY、HTTPS_PROXY、FTP_PROXY、NO_PROXY。
6.6 环境变量 ENV
-
指令功能:ENV指令用于设置环境变量,设置的环境变量可以在ADD、COPY、ENV、EXPOSE、FROM、LABEL、STOPSIGNAL、USER、VOLUME、WORKDIR等指令中使用。
-
指令语法:
# 设置语法一:只能设置单个环境变量 ENV <key> <value> # 设置语法二:可以设置多个环境变量 ENV <key>=<value> ... # 引用语法一 $variable_name # 引用语法二 ${variable_name}
-
指令说明:如果值中有空格,要么使用""把整个值引用起来,要么使用\来处理(见下面示例)。
-
指令示例:
# 设置示例一:设置单个环境变量 ENV myName John Doe ENV myDog Rex The Dog ENV myCat fluffy # 设置示例二:同时设置多个环境变量 ENV myName="John Doe" myDog=Rex\ The\ Dog \ myCat=fluffy # 引用示例 FROM ubuntu ENV foo /bar WORKDIR ${foo} # WORKDIR /bar ADD . $foo # ADD . /bar COPY \$foo /quux # COPY $foo /quux
-
特殊情况:环境变量之间引用时,只会引用其它指令中定义的环境变量,而不会引用同一指令中定义的环境变量(如下示例中在def环境变量),如果引用的环境变量已经重复定义过多次,则引用的是最后一次定义的那个环境变量(如下示例中的ghi环境变量)。
ENV abc=hello ENV abc=bye def=$abc # def的值为hello ENV ghi=$abc # ghi的值为bye
6.7 设置用户 USER
- 指令功能:USER指令用于设置运行镜像时要使用的用户的用户名、组名或UID、GID。
- 指令语法:
# 语法一:指定用户名和组名 USER <user>[:<group>] # 语法二:指定UID和GID USER <UID>[:<GID>]
- 指令说明:如果一个用户没有主组,则镜像会使用root组来运行。在Windows上,如果用户不是内置帐户,则必须首先创建该用户,可以在DockerFile中调用net user命令来创建用户。
- 指令示例:
FROM microsoft/windowsservercore # 使用 net user命令创建用户patrick RUN net user /add patrick # 设置后续指令使用patrick用户来运行 USER patrick
6.8 工作目录 WORKDIR
- 指令功能:WORKDIR指令为DockerFile中的RUN、CMD、ENTRYPOINT、ADD、COPY等指令设置工作目录。如果工作目录不存在,则会先被创建。
- 指令语法:
WORKDIR /path/to/workdir
- 指令说明:DockerFile中可以多次使用WORKDIR指令,如果某个WORKDIR指令设置的工作目录是个相对路径,则是相对于上一个WORKDIR指令设置的目录。WORKDIR指令中可以使用ENV指令中设置的环境变量。
- 指令示例:
# 工作目录为/a WORKDIR /a # 工作目录为/a/b WORKDIR b # 工作目录为/a/b/c WORKDIR c # 打印结果为/a/b/c RUN pwd # 在WORKDIR指令中使用环境变量 ENV DIRPATH /path ENV DIRNAME dir WORKDIR $DIRPATH/$DIRNAME RUN pwd
6.9 挂载目录 VOLUME
- 指令功能:VOLUMN指令使用指定的名称创建一个挂载点,并将其标记为已经挂载了来自本机主机或其他容器的外部挂载卷。
- 指令语法:
VOLUME ["/data"]
- 指令说明:docker run命令会使用基础镜像中的数据来初始化最新创建的卷。
- 指令示例:
# 创建一个名为/myvol的挂载点,并把/myvol/greeting文件复制到新创建的/myvol卷中 FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
6.10 暴露端口 EXPOSE
- 指令功能:EXPOSE指令用于通知Docker容器在运行时监听指定的网络端口,可以指定监听的是TCP协议的端口还是UDP协议的端口,如果没有指定协议,则默认为TCP协议。
- 指令语法:
EXPOSE <port> [<port>/<protocol>...]
- 指令说明:EXPOSE指令实际上并不发布端口,它在构建镜像的人和运行容器的人之间起一种文档的作用,用于说明将要发布的是哪个端口。要想实际上发布端口,需要在执行docker run命令的时候指定 -p 选项发布并映射一个端口,或使用 -P 选项发布并映射所有端口。
- 指令示例:
虽然可以在DockerFile中指定端口,但是仍然在启动Docker容器时通过 -p 选项覆盖之前设置的端口(如下示例所示)。# 只监听UDP协议的端口 EXPOSE 80/udp # 同时监听TCP协议的端口和UDP协议的端口 EXPOSE 80/tcp EXPOSE 80/udp
docker run -p 80:80/tcp -p 80:80/udp ...
6.11 入口端点 ENTRYPOINT
- 指令功能:ENTRYPOINT用于指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
- 指令语法:
# exec格式语法:推荐 ENTRYPOINT ["executable", "param1", "param2"] # shell格式语法: ENTRYPOINT command param1 param2
- 命令说明:每个Dockerfile中只能有一个ENTRYPOINT指令,当指定多个时,只有最后一个才会生效。在运行时,可以被 --entrypoint 参数覆盖掉。
6.12 添加文件 ADD
- 指令功能:ADD指令用于从源地址复制新文件、目录或远程文件URL,并添加到镜像文件系统中的目标地址中。
- 指令语法:
# 语法一: ADD [--chown=<user>:<group>] <src>... <dest> # 语法二:如果路径中包含空格,则必须使用这种格式 ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
- 指令说明:只有使用DockerFile构建Linux容器的情况下才支持--chown选项,而构建Windows容器的情况下不支持该选项。可以指定多个源地址,但如果它们是文件或目录,则它们会被视为基于构建镜像的上下文的相对路径。目标地址可以是绝对路径,也可以是相对于WORKDIR的相对路径。在复制文件或目录时,如果包含特殊字符(如[和]),则需要按照golang规则转义这些路径,以防止将它们视为匹配模式。复制生成的所有文件和目录的UID和GID默认都是0,除非使用--chown选项指定用户名、组名或UID、GID,如果指定了用户名却没有指定组名,或指定了UID却没有指定GID,则使用UID的值作为GID的值。
- 指令示例:
# 把工作目录下的所有以hom开头的文件全部都复制到/mydir/目录下 ADD hom* /mydir/ # 把工作目录下所有符合hom?.txt格式的文件全部都复制到/mydir/目录下 ADD hom?.txt /mydir/ # 把工作目录下的test文件复制到WORKDIR/relativeDir/目录下 ADD test relativeDir/ # 把工作目录下的test文件复制到/absoluteDir/目录下 ADD test /absoluteDir/ # 把工作目录下的arr[0].txt文件复制到/mydir/目录下。(特殊符号的转换) ADD arr[[]0].txt /mydir/ # 同时指定用户名和组名 ADD --chown=55:mygroup files* /somedir/ # 只指定用户名 ADD --chown=bin files* /somedir/ # 只指定UID(默认GID的值与UID的值相同) ADD --chown=1 files* /somedir/ # 同时指定UID和GID ADD --chown=10:11 files* /somedir/
6.13 复制文件 COPY
- 指令功能:COPY指令用于从源地址复制新文件或目录,并添加到镜像文件系统中的目标地址中。(源地址不可以是URL)
- 指令语法:
# 语法一: COPY [--chown=<user>:<group>] <src>... <dest> # 语法二:如果路径中包含空格,则必须使用这种格式 COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
- 指令说明:只有使用DockerFile构建Linux容器的情况下才支持--chown选项,而构建Windows容器的情况下不支持该选项。可以指定多个源地址,但如果它们是文件或目录,则它们会被视为基于构建镜像的上下文的相对路径。目标地址可以是绝对路径,也可以是相对于WORKDIR的相对路径。在复制文件或目录时,如果包含特殊字符(如[和]),则需要按照golang规则转义这些路径,以防止将它们视为匹配模式。复制生成的所有文件和目录的UID和GID默认都是0,除非使用--chown选项指定用户名、组名或UID、GID,如果指定了用户名却没有指定组名,或指定了UID却没有指定GID,则使用UID的值作为GID的值。
- 指令示例:
# 把工作目录下的所有以hom开头的文件全部都复制到/mydir/目录下 COPY hom* /mydir/ # 把工作目录下符合hom?.txt格式的文件全部都复制到/mydir/目录下 COPY hom?.txt /mydir/ # 把工作目录下的test文件复制到WORKDIR/relativeDir/目录下 COPY test relativeDir/ # 把工作目录下的test文件复制到/absoluteDir/目录下 COPY test /absoluteDir/ # 把工作目录下的arr[0].txt文件复制到/mydir/目录下。(特殊符号的转换) COPY arr[[]0].txt /mydir/ # 同时指定用户名和组名 COPY --chown=55:mygroup files* /somedir/ # 只指定用户名 COPY --chown=bin files* /somedir/ # 只指定UID(默认GID的值与UID的值相同) COPY --chown=1 files* /somedir/ # 同时指定UID和GID COPY --chown=10:11 files* /somedir/
6.14 执行命令 RUN
- 指令功能:RUN指令将在当前镜像之上的新层中执行任何命令并提交结果,生成的镜像将用于DockerFile中的下一步。
- 指令语法:
# shell格式:命令会在shell中运行,Linux中默认是 /bin/sh -c,Windows中默认是 cmd /S /C RUN <command> # exec格式: RUN ["executable", "param1", "param2"]
- 指令说明:与shell格式不同,exec格式不会调用shell命令,所以shell处理不会发生,例如:RUN [“echo”,“$home”] 不会对 $home 执行变量替换;如果要进行shell处理,可以使用shell格式或使用exec格式并直接执行shell,例如:RUN [“/bin/bash”、“-c”、“echo $home”],当使用exec格式并直接执行shell时,与shell格式一样,执行环境变量扩展的是shell,而不是docker。exec格式会被解析为JSON数组,所以必须使用双引号,而不是单引号。JSON格式中需要转义反斜杠,否则会报错,例如:RUN [“c:\windows\system32\tasklist.exe”]。
- 指令示例:
# shell格式示例一:使用 \ 将一个连续的shell运行指令写到多行中,并指定义shell为 /bin/bash RUN /bin/bash -c 'source $HOME/.bashrc; \ echo $HOME' # shell格式示例二:将一个连续的shell运行指令写到同一行中(与shell格式示例一等价) RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' # exec格式示例: RUN ["/bin/bash", "-c", "echo hello"]
6.15 容器启动 CMD
- 指令功能:CMD指令的主要目的是为正在执行的容器提供默认值,这些默认值可以包括可执行环境,也可以省略可执行环境,如果省略了可执行环境,则必须指定ENTRYPOINT指令。RUN指令实际运行一个命令并提交结果,而CMD指令在构建时不执行任何操作,但指定镜像的预期命令。
- 指令语法:
# 格式一:exec格式(推荐) CMD ["executable", "param1", "param2"] # 格式二:作为ENTRYPOINT指令的默认参数 CMD ["param1", "param2"] # 格式三:shell格式(命令会在shell中运行,Linux中默认是 /bin/sh -c) CMD command param1 param2
- 指令说明:DockerFile中只能有一个CMD指令,如果有多个,则只有最后一个CMD命令才会生效。与shell格式不同,exec格式不会调用shell命令,所以shell处理不会发生,例如:CMD [“echo”,“$home”] 不会对 $home 执行变量替换;如果要进行shell处理,可以使用shell格式或使用exec格式并直接执行shell,例如:CMD [“/bin/bash”、“-c”、“echo $home”],当使用exec格式并直接执行shell时,与shell格式一样,执行环境变量扩展的是shell,而不是docker。如果使用CMD指令为ENTRYPOINT指令提供默认参数,则CMD指令和ENTRYPOINT指令都应该使用JSON数组格式。exec格式会被解析为JSON数组,所以必须使用双引号,而不是单引号。如果不使用Shell格式运行CMD指令,则必须将CMD指令表示为JSON数组,并给出可执行文件的完整路径。
- 指令示例:
# 使用shell的格式运行CMD指令 FROM ubuntu CMD echo "This is a test." | wc - # 不使用Shell的格式运行CMD指令 FROM ubuntu CMD ["/usr/bin/wc", "--help"]