1. 概念
flowchart LR
docker --> docker-ce社区免费版
docker --> docker-ee企业收费版
docker-ce社区免费版 --> docker-compose管理多个Docker容器的工具
docker-ce社区免费版 --> Kubernetes管理大规模容器集群的容器编排平台
2. Docker 是什么
Docker容器对进程封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程
Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
Docker镜像中包含完整运行环境, 包括系统函数库(仅依赖系统的Linux内核),因此可以在任意Linux操作系统上运行
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便
3. 为什么要用 Docker
- 高效利用系统资源
- 快速的启动时间
- 一致的运行环境。避免由于开发环境、测试环境、生产环境不一致,导致的 bug
- 持续交付和部署。一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。使用Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件。
- 更轻松的维护和扩展。
Docker
使用的分层存储以及镜像的技术,使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。官网镜像库
4. Docker 基本组成
镜像、容器、仓库 这三个概念,涵盖了 Docker 的整个生命周期
4.1. 镜像
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含任何动态数据,其内容在构建之后也不会被改变
4.1.1. 分层存储(重点)
Docker 镜像构建时,会一层一层地构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
eg:删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像
4.2. 容器
镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间( the same namespace for a set of resources and processes, but those namespaces refer to distinct resources. Resources may exist in multiple spaces)
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd
去启动后台服务,容器内没有后台服务的概念。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西
4.2.1. 容器存储层(不推荐)
每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层(为容器运行时读、写而准备的存储层)
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡
Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
4.3. 仓库
镜像构建完成后,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个仓库。每个仓库可以包含多个标签(Tag)。每个标签对应一个镜像。
通常,一个仓库包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest 作为默认标签。
4.3.1. 公开 Docker Registry
一般这类公开服务允许用户免费上传、下载公开的镜像
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的 官方镜像。除此以外,还有 Red Hat 的 Quay.io;Google 的 Google Container Registry,Kubernetes 的镜像使用的就是这个服务;代码托管平台 GitHub 推出的 ghcr.io
4.3.2. 私有 Docker Registry
用户还可以在本地搭建私有 Docker Registry
5. 安装Docker
5.1. 官方脚本自动安装(推荐)
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
官方被封了,用这个
sudo curl -fsSL https://github.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh| bash -s docker --mirror Aliyun
5.2. 启动
sudo systemctl enable docker
sudo systemctl start docker
5.3. 建立 docker 用户组
默认情况下,docker命令会使用 Unix socket 与 Docker 引擎通讯。而只有root用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root
用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组
建立docker组
sudo groupadd docker
将当前用户加入 docker 组
sudo usermod -aG docker $USER
5.4. 测试 Docker 是否安装正确
docker run --rm hello-world
5.5. 镜像加速
查看是否在 docker.service
文件中配置过镜像地址
systemctl cat docker | grep '\-\-registry\-mirror'
如果该命令有输出,那么请执行 $ systemctl cat docker
查看 ExecStart=
出现的位置,修改对应的文件内容去掉 --registry-mirror
参数及其值,并按接下来的步骤进行配置。
如果以上命令没有任何输出,那么就可以在 /etc/docker/daemon.json
中写入如下内容(如果文件不存在请新建该文件):
{
"registry-mirrors": [
"https://docker.1panel.live",
"https://docker.m.daocloud.io",
"https://huecker.io"
]
}
重新启动服务
sudo systemctl daemon-reload
sudo systemctl restart docker
检查加速器是否生效
docker info
6. Docker 架构(重点)
6.1. 客户端
通过命令或Docker API 向Docker服务端发送指令。可以在本地或远程向服务端发送指令
6.2. 服务端
服务端=Docker引擎=Docker守护进程, 负责处理Docker指令,管理镜像、容器等
7. Docker 镜像操作
Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像
7.1. 获取镜像
访问DockerHub搜索镜像,https://hub.docker.com/
Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]
。默认地址是 docker.io
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
7.2. 运行
docker run
通过 exit
退出容器
7.3. 列出镜像
查看本地镜像
docker image ls
查看镜像、容器、数据卷所占用的空间
docker system df
同时显示依赖的中间层镜像
docker image ls -a
7.4. 导出导入
导出镜像到本地
docker save -o <保存的文件名>.tar <镜像名称>
导入
docker load -i /path/to/myimage.tar
这将在另一台机器上导入名为myimage
的镜像
7.5. 删除镜像
<镜像>
可以是 镜像短 ID
、镜像长 ID
、镜像名
或者 镜像摘要
docker image rm [选项] <镜像1> [<镜像2> ...]
Untagged 和 Deleted
删除镜像的时候,实际上是在要求删除某个标签的镜像。所以首先需要做的是将满足我们要求的所有镜像标签都取消,这就是我们看到的 Untagged
的信息。因为一个镜像可以对应多个标签,因此当我们删除了所指定的标签后,可能还有别的标签指向了这个镜像,如果是这种情况,那么 Delete
行为就不会发生。所以并非所有的 docker image rm
都会产生删除镜像的行为,有可能仅仅是取消了某个标签而已
当该镜像所有的标签都被取消了,该镜像很可能会失去了存在的意义,因此会触发删除行为。镜像是多层存储结构,因此在删除的时候也是从上层向基础层方向依次进行判断删除。因此很有可能某个其它镜像正依赖于当前镜像的某一层。这种情况,依旧不会触发删除该层的行为。直到没有任何层依赖当前层时,才会真实的删除当前层
除了镜像依赖以外,还需要注意的是容器对镜像的依赖。如果有用这个镜像启动的容器存在(即使容器没有运行),那么同样不可以删除这个镜像
7.6. Dockerfile定制镜像(重点)
定制镜像,是以一个镜像为基础,在其上进行定制
镜像的定制实际上就是定制每一层所添加的配置、文件。我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile
注:禁止使用 docker commit定制镜像,使用 docker commit 意味着除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建
建立一个文本文件,并命名为 Dockerfile
touch Dockerfile
7.6.1. Dockerfile指令
# 指定基础镜像
FROM python:3.8.10
# 设置工作目录
WORKDIR /app
# 将项目下的requirements.txt文件复制到 /app目录
COPY ./requirements.txt .
# 执行命令pip install --no-cache-dir -r requirements.txt 安装项目依赖
RUN pip install --no-cache-dir -r requirements.txt
# 将Flask 项目复制到容器中的 /app 目录
COPY . .
# 容器向外暴露5000端口
EXPOSE 5000
# 在容器启动时运行 app.py 脚本
CMD [ "python", "app.py" ]
FROM 命令
指定基础镜像,因此一个 Dockerfile
中 FROM
是必备的指令,并且必须是第一条指令
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。如果以 scratch
为基础镜像的话,意味着不以任何镜像为基础
RUN 命令
RUN
指令用来执行命令行的命令,其格式有两种:
- shell 格式:
RUN <命令>
,就像直接在命令行中输入的命令一样 - exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
,这更像是函数调用中的格式
Dockerfile 支持 Shell 类的行尾添加 \
的命令换行方式,以及行首 #
进行注释的格式
此外,通常要在一组命令的最后添加清理工作的命令 apt-get purge -y --auto-remove $buildDeps
,删除为了编译构建所需要的软件,清理所有下载、展开的文件,并且清理 apt
缓存文件。这是很重要的一步,镜像是多层存储,每一层的东西并不会在下一层被删除,会一直跟随着镜像。因此镜像构建时,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉
COPY
将从构建上下文目录中 <源路径>
的文件或目录复制到新的一层的镜像内的 <目标路径>
位置。COPY <源路径> <目标路径>
<目标路径>
可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR
指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
需要注意,使用 COPY
指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用
如果源路径为文件夹,复制的时候不是直接复制该文件夹,而是将文件夹中的内容复制到目标路径
COPY 命令的源路径是相对于构建上下文(即通过 docker build
命令传递给 Docker 的目录或文件)
ADD
与COPY类似,但还支持从URL中下载文件,并且可以自动解压压缩文件。
Dockerfile 最佳实践中要求,所有的文件复制均使用 COPY
指令,仅在需要自动解压缩的场合使用 ADD
。
WORKDIR
设置工作目录,改变以后各层的工作目录的位置。WORKDIR <工作目录路径>
如该目录不存在,WORKDIR
会帮你建立目录。
工作目录就是容器运行时所用的根目录
EXPOSE
声明容器运行时需要开放的端口。EXPOSE <端口>
要将 EXPOSE
和在运行时使用 -p <宿主端口>:<容器端口>
区分开来。-p
,是映射宿主端口和容器端口,也就是将容器的对应端口服务公开给外界访问,而 EXPOSE
仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
在 Dockerfile 中使用 EXPOSE 声明的好处是在容器运行时,使用随机端口映射时,也就是 docker run -P
时,会自动随机映射 EXPOSE
的端口。
ENV
设置环境变量。
定义了环境变量,无论是后面的其它指令,还是运行时的应用,都可以直接使用定义的环境变量。
通过环境变量,可以让一份 Dockerfile
制作更多的镜像,只需使用不同的环境变量即可。
CMD
设置容器启动后默认执行的命令。
ENTRYPOINT
设置容器启动后默认执行的命令,与CMD不同的是,ENTRYPOINT指定的命令不会被覆盖。
USER
设置容器中执行命令的用户。
VOLUME
声明持久化数据的目录,可以在容器中挂载主机的目录。VOLUME <路径>
容器运行时应该尽量保持容器存储层不发生写操作,在 Dockerfile
中,可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据
ARG
构建参数和 ENV
的效果一样,都是设置环境变量。所不同的是,ARG
所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。
7.6.2. 构建镜像
docker build [选项] <上下文路径/URL/->
7.6.3. 镜像构建上下文(重点)
docker build
的工作原理。Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,docker build
命令构建镜像,并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。那么在这种客户端/服务端的架构中,如何才能让服务端获得本地文件呢?
这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径,docker build
命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样 Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
一般大家习惯性的会使用默认的文件名 Dockerfile
,以及会将其置于镜像构建上下文目录中。
7.6.4. 多阶段构建
… …
8. Docker 容器操作
容器是独立运行的一个或一组应用,以及它们的运行态环境
8.1. 启动
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited
)的容器重新启动。
8.1.1. 新建并启动
命令主要为 docker run
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
8.1.2. 启动已终止容器
利用 docker container start
命令,直接将一个已经终止(exited
)的容器启动运行。
8.2. 守护态运行
更多的时候,需要让 Docker 在后台运行,而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d
参数来实现 docker run -d
注: 容器是否会长久运行和 docker run
指定的命令有关,和 -d
参数无关
要获取容器的输出信息,可以通过 docker container logs
命令
使用 -d
参数启动后会返回一个唯一的 id,也可以通过 docker container ls
命令来查看容器信息
8.3. 终止
使用 docker container stop
来终止一个运行中的容器
注:当 Docker 容器中指定的应用终结时,容器也自动终止
8.4. 进入容器
推荐 docker exec
命令,docker exec
command allows you to run commands inside a Docker container
使用-it
参数,可以看到我们熟悉的 Linux 命令提示符
eg:docker exec -it container-name bash
8.5. 导出导入
导出容器快照到本地 tar
文件,可以使用 docker export
命令
docker export [CONTAINER ID] > ubuntu.tar
导入容器可以使用docker load
来导入镜像存储文件到本地镜像库,也可以使用docker import
来导入一个容器快照到本地镜像库
镜像与容器快照的区别
容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息
8.6. 删除
使用 docker container rm
来删除一个处于终止状态的容器
要删除一个运行中的容器,可以添加 -f
参数
清理掉所有处于终止状态的容器docker container prune
9. Docker 仓库
仓库(Repository
)是集中存放镜像的地方
9.1. Docker Hub
https://hub.docker.com/
9.2. 私有仓库
一个本地仓库供私人使用
docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库
10. Docker 数据管理
在Docker 内部以及容器之间管理数据。在容器中管理数据主要有两种方式:
- 数据卷(Volumes)
- 挂载主机目录 (Bind mounts)
10.1. 数据卷(重点)
在 Docker 中,数据卷(volume)是一种用于在容器和宿主机之间共享数据的机制
数据卷在 Docker 中是一种特殊的文件系统,它可以映射到宿主机上的一个目录或者一个 Docker 管理的卷(volume)上。数据卷本身并不属于宿主机。数据卷是由 Docker 管理的,它存储在 Docker 数据目录下的某个位置,而不是存储在宿主机上的普通文件或目录中。因此,删除容器或删除数据卷映射并不会删除数据卷本身,数据卷可以被多个容器共享,并且可以在宿主机和容器之间方便地移动和复制
当一个数据卷被映射到一个目录上时,这个目录会成为该数据卷的挂载点,并且可以在容器中访问该目录下的所有内容
当一个数据卷被映射到一个 Docker 管理的卷上时,这个卷会成为该数据卷的挂载点,并且可以在多个容器之间共享
10.1.1. 数据卷特点
数据卷可以在容器之间共享和重用,方便容器间传递数据
对数据卷内数据的修改会立马生效(无论是容器内操作还是本地操作)
对数据卷的更新不会影响镜像,解耦开应用和数据
数据卷可以独立于容器存在(数据卷默认会一直存在,即使容器被删除)
10.1.2. 数据卷操作命令
数据卷操作的基本语法为:docker volume [COMMAND]
,其中COMMAND是某个具体的命令
创建一个数据卷
docker volume create my-vol
列出所有的数据卷
docker volume ls
查看指定数据卷的信息
docker volume inspect my-vol
挂载数据卷到某容器(重点)
使用 docker run
命令的 -v
将数据卷挂载到容器中的某个目录下,从而实现容器中的应用程序对宿主机上的数据进行读写。在一次 docker run
中可以挂载多个数据卷(在linux的docker主机中创建一个卷时, 其在宿主机对应的目录或挂载点路径为/var/lib/docker/volumes/卷名/_ data
)
删除指定的数据卷
docker volume rm my-vol
在删除容器的同时移除数据卷
数据卷是用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v
这个命令。
删除未使用的数据卷
docker volume prune
10.2. 挂载主机目录
将宿主机上的目录直接挂载到容器中,容器中的数据改变会直接影响宿主机上的数据,而且需要手动管理数据的备份和恢复等工作
在用 docker run
命令的时候,使用 --mount
标记可以指定挂载一个本地主机的目录或文件到容器中去
Docker 挂载主机目录的默认权限是 读写
,用户也可以通过增加 readonly
指定为 只读
需要在容器中访问宿主机上的文件系统,建议使用挂载主机目录
11. Docker 网络通信
Docker 允许通过外部访问容器、容器互联的方式来提供网络服务
11.1. 外部访问容器
使用 -P
标记时,Docker 会随机映射一个本地端口到内部容器的端口。让外部也可以访问容器应用
-P
标记支持的格式 ip:hostPort:containerPort
、ip::containerPort
、 `hostPort:containerPort
注:在一个指定端口上只可以绑定一个容器
容器有自己的内部网络和 ip 地址(使用 docker inspect
查看,Docker 还可以有一个可变的网络配置。)
-p
标记可以多次使用来绑定多个端口
$ docker run -d \
-p 80:80 \
-p 443:443 \
nginx:alpine
11.2. 容器互联
强烈建议将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 --link
参数。如:要想从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了
新建网络
docker network create -d bridge my-net
,-d
参数指定 Docker 网络类型,有 bridge
、overlay
连接容器
运行一个容器并连接到新建的 my-net
网络,打开新的终端,再运行一个容器并加入到 my-net
网络。通过 ping
来证明容器与容器间建立了互联关系
查看网络列表
docker network ls
11.3. 配置 DNS
配置全部容器的 DNS ,也可以在 /etc/docker/daemon.json
文件中增加以下内容来设置。
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
这样每次启动的容器 DNS 自动配置为 114.114.114.114
和 8.8.8.8
12. Docker Compose(重点)
12.1. 简介
Docker Compose 负责实现对 Docker 容器集群的快速编排,可以把项目的多个服务集合到一起,一键运行。
如:要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
Docker Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)
Docker Compose 中有两个重要的概念:
- 服务 (
service
):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 - 项目 (
project
):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
文件中定义。
Docker Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理
12.2. 安装与卸载
docker-compose和docker compose的区别
Compose分为V1和V2版本,安装方式分为两种,一种是独立安装(standalone),一种是插件安装(plugin),所以有四种组合方式:
V1 | V2 | |
---|---|---|
standalone(独立式安装) | docker-compose | docker-compose |
plugin(插件式安装) | 不支持插件式安装 | docker compose |
插件安装的Compose,在V2版本,指令是docker compose(中间是空格),最新版的docker安装时会自动以插件的形式安装docker compose
支持同时采用两种方式安装Compose,安装后可以同时使用docker-compose和docker compose
独立式安装
在 Linux 64 位系统上直接下载对应的二进制包
$ sudo curl -L https://github.com/docker/compose/releases/download/2.17.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# 国内用户可以使用以下方式加快下载
$ sudo curl -L https://get.daocloud.io/docker/compose/releases/download/2.17.2/docker-compose-`uname -s-uname -m` > /usr/local/bin/docker-compose
# 给脚本执行权限
$ sudo chmod +x /usr/local/bin/docker-compose
运行docker-compose --version
检查是否安装成功
卸载:如果是二进制包方式安装的,删除二进制文件即可。
$ sudo rm /usr/local/bin/docker-compose
12.3. Compose 模板文件
默认的模板文件名称为 docker-compose.yml
参考文档:https://docs.docker.com/compose/
version: "3.7"
services:
app:
build: ./
ports:
- 80:8080
volumes:
- ./:/app
environment:
- TZ=Asia/Shanghai
redis:
image: redis:5.0.13
volumes:
- redis:/data
environment:
- TZ=Asia/Shanghai
volumes:
redis:
容器默认时间不是北京时间,增加 TZ=Asia/Shanghai 可以改为北京时间
12.4. 常用命令
docker compose命令的运行需要docker-compose.yml文件的支持,可以指定文件位置,也可以在文件同目录运行命令
## 构建镜像并启动文件内配置的所有容器
docker compose up
## 构建镜像并启动所有容器,后台运行
docker compose up -d
## 停止并删除所有容器
docker compose down
## 重启单个服务
docker-compose restart service-name
## 重启所有服务
docker compose restart
## 启动服务
docker compose start
## 停止服务
docker compose stop
## 展示当前docker compose编排过并运行的所有容器(在docker-compose.yml文件同目录下运行)
docker compose ps
## 检查docker-compose.yml文件
docker compose config
## 检查docker-compose.yml文件,有问题就输出
docker compose config -q
## 进入容器命令行
docker-compose exec service-name sh
## 查看容器运行log
docker-compose logs [service-name]
13. Docker GUI 管理
推荐使用Portainer(Portainer-CE社区版) 作为容器的 GUI 管理方案
13.1. 单机版运行
如果仅有一个docker宿主机,则可使用单机版运行
在Docker中创建一个数据卷
docker volume create portainer_data
该命令的作用是在Docker中创建一个名为portainer_data的数据卷,用于挂载到Portainer容器中的/data目录以保存Portainer的数据
访问https://ip:9443
,首次登陆需要注册用户,给admin用户设置密码:adminadminadmin
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
具体参数的含义如下:
-d: 让容器在后台以守护进程方式运行
-p 8000:8000: 将主机的8000端口映射到容器的8000端口,这样可以通过访问主机的8000端口来访问Portainer的Web界面
-p 9443:9443: 将主机的9443端口映射到容器的9443端口,这样可以通过访问主机的9443端口来访问Portainer的Web界面(使用HTTPS)
--name portainer: 为容器指定一个名称,这里指定为portainer
--restart=always: 让Docker在启动时自动重新启动容器,即使容器因为某种原因而停止了
-v /var/run/docker.sock:/var/run/docker.sock: 将主机上的/var/run/docker.sock文件映射到容器内的同一文件,这样Portainer就可以通过Docker API与主机上的Docker守护程序进行交互
-v portainer_data:/data: 将名为portainer_data的Docker卷挂载到容器的/data目录,这样Portainer就可以将其数据保存在该卷中
portainer/portainer-ce:latest: 运行的镜像名称和标签,这里使用的是Portainer社区版的最新版本。
13.2. 集群版运行
… …
14. Docker 的目录结构
Docker 安装目录:这是 Docker 引擎的安装目录,通常包括二进制文件、配置文件和其他相关文件等。在 Linux 系统中,默认安装目录为 /usr/bin/docker
Docker 数据目录:这是 Docker 引擎用于存储容器、映像和其他数据的目录。在 Linux 系统中,默认数据目录为 /var/lib/docker
。Docker 数据目录下通常包括以下几个子目录:
containers:存储容器的相关数据,包括容器文件系统、元数据和日志等。
image:存储 Docker 镜像的相关数据,包括镜像文件、元数据和缓存等。
volumes:存储 Docker 数据卷的相关数据,包括数据卷文件和元数据等。
networks:存储 Docker 网络的相关数据,包括网络配置和元数据等。
Docker 配置目录:这是 Docker 引擎的配置目录,通常包括一些配置文件和证书等。在 Linux 系统中,默认配置目录为 /etc/docker
Docker 日志目录:这是 Docker 引擎的日志目录,通常包括 Docker 引擎和容器的日志文件。在 Linux 系统中,默认日志目录为 /var/log/docker
Docker 工作目录:这是 Docker 引擎的工作目录,通常用于存储一些临时文件和脚本等。在 Linux 系统中,默认工作目录为 /var/lib/docker/tmp
15. Docker命令
Common Commands:
run Create and run a new container from an image
exec Execute a command in a running container
ps List containers
build Build an image from a Dockerfile
pull Download an image from a registry
push Upload an image to a registry
images List images
login Log in to a registry
logout Log out from a registry
search Search Docker Hub for images
version Show the Docker version information
info Display system-wide information
Management Commands:
builder Manage builds
buildx* Docker Buildx (Docker Inc., v0.11.1)
compose* Docker Compose (Docker Inc., v2.19.1)
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
plugin Manage plugins
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Swarm Commands:
swarm Manage Swarm
Commands:
attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
export Export a container's filesystem as a tar archive
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
save Save one or more images to a tar archive (streamed to STDOUT by default)
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes
Global Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides
DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket to connect to
-l, --log-level string Set the logging level ("debug", "info", "warn", "error", "fatal")
(default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit