热爱摄影的程序员
喜欢编码的设计师
擅长设计的剪辑师
一位高冷无情的编码爱好者
大家好,我是 DevOps 工程师摘星人
欢迎分享 / 收藏 / 赞 / 在看!
这份 Docker 教程是一份简明扼要的指南,旨在帮助初学者快速入门 Docker 容器化技术。通过清晰的步骤和示例,您将学习如何安装和配置 Docker,创建和管理容器,以及部署应用程序。教程涵盖了常用的 Docker 命令和概念,并介绍了容器网络、数据管理和镜像构建等关键主题。无论您是开发人员、系统管理员还是对容器化技术感兴趣的任何人,本教程都将为您提供实用的知识和技能,助您在 Docker 领域迈出坚实的第一步。
Docker 是一种开源的容器化平台,用于构建、分发和运行应用程序。它允许开发者将应用程序及其依赖项打包成一个称为容器的轻量级、可移植的单元。
Docker 的核心概念是容器,它是一个独立且可执行的软件包,包含了应用程序的所有必要组件和配置。容器隔离了应用程序与其运行环境,使得应用程序能够在不同的计算机上以一致的方式运行,而不受底层操作系统和硬件的影响。
使用 Docker,开发者可以通过 Dockerfile 描述应用程序的构建过程,定义所需的依赖项和配置。然后,使用 Docker 命令将 Dockerfile 构建成一个镜像,镜像是容器的基础,类似于一个应用程序的模板。镜像可以被分发和共享,可以在任何支持 Docker 的环境中运行。
通过 Docker,开发者可以实现快速、一致和可重复的应用程序部署。应用程序及其依赖项打包成容器后,可以在不同的环境中轻松部署和扩展。Docker 还提供了一系列工具和功能,如容器编排、网络管理和存储管理,以帮助简化应用程序的管理和运维。
总而言之,Docker 提供了一种轻量级、可移植和可扩展的应用程序打包和部署解决方案,使开发者能够更高效地构建、交付和运行应用程序。
Docker 在软件开发和运维中有广泛的应用场景,包括以下几个方面:
总之,Docker 在构建、交付和运行应用程序方面具有广泛的应用场景,可以提高开发效率、简化部署流程,并支持现代化的应用架构和多云环境。
Docker 具有以下几个主要优点:
综上所述,Docker 的轻量性、环境一致性、可移植性、快速部署和扩展性,以及与持续集成和持续部署的集成能力,使其成为现代应用程序开发和部署的强大工具。
Docker 为什么比虚拟机快?
Docker 比虚拟机快的主要原因有以下几点:
- 轻量级:Docker 容器是轻量级的,它们共享宿主操作系统的内核,不需要额外的操作系统实例。相比之下,虚拟机需要独立的操作系统,包括内核和系统资源的复制,因此虚拟机更为庞大和笨重。
- 快速启动:Docker 容器的启动速度非常快。由于容器共享宿主操作系统的内核,不需要启动完整的操作系统实例,因此容器的启动时间通常只需几秒钟。相比之下,虚拟机的启动时间通常需要数十秒甚至数分钟。
- 资源利用率高:Docker 容器可以共享宿主操作系统的资源,包括内存、CPU 和存储等。相比之下,虚拟机需要独立分配一定的资源给每个虚拟机实例,这导致了资源利用率的浪费。
- 更少的性能开销:由于 Docker 容器直接运行在宿主操作系统上,与宿主系统之间的通信开销较小,不需要进行硬件级别的虚拟化。相比之下,虚拟机需要通过虚拟化层与宿主系统通信,增加了一定的性能开销。
- 更高的可扩展性:由于 Docker 容器的轻量性和快速启动特性,它们可以更容易地进行扩展和部署。在大规模的应用部署中,Docker 容器可以更快速地启动和复制,以适应变化的负载需求。
总体而言,Docker 容器相对于虚拟机具有更高的性能和更低的资源开销,这使得它们成为构建和部署应用程序的更快速和高效的选择。然而,虚拟机仍然在某些场景下具有优势,例如需要隔离完全独立的操作系统环境或运行不同类型的操作系统时。
Docker 引擎是 Docker 的核心组件,负责管理和运行容器。它包括一个守护进程(Docker daemon)和一个命令行接口工具(Docker CLI)。Docker 引擎与宿主操作系统交互,负责创建、启动、停止和销毁容器,并提供容器的管理和监控功能。
Docker 镜像是容器的基础,类似于一个应用程序的模板。镜像包含了应用程序运行所需的所有文件、依赖项和配置。开发者可以使用 Dockerfile 描述应用程序的构建过程,并通过 Docker 命令将 Dockerfile 构建成一个镜像。镜像可以被分发和共享,并可以用来创建和运行容器。
Docker 容器是 Docker 镜像的实例化运行。每个容器都是一个独立且可执行的软件包,包含了应用程序及其运行所需的依赖项。容器隔离了应用程序与其运行环境,使得应用程序能够在不同的计算机上以一致的方式运行。容器可以通过 Docker 引擎进行创建、启动、停止和销毁。
Docker 仓库是用于存储和共享 Docker 镜像的中央存储库。Docker 官方提供了公共的 Docker 仓库,称为 Docker Hub,开发者可以在其中找到各种镜像。此外,还可以搭建私有的 Docker 仓库,用于存储和管理自己的镜像。常用的私有仓库包括 Docker Trusted Registry(DTR)和第三方工具如 Harbor。
除了以上核心组件外,Docker 还提供了其他一些工具和功能,如:
综上所述,Docker 的基本组成包括 Docker 引擎、Docker镜像、Docker 容器和 Docker 仓库,它们共同构成了 Docker 的核心功能和基础架构。通过使用这些组件,开发者可以方便地打包、分发和运行应用程序,并实现快速部署和扩展。此外,Docker 还提供了一些附加工具和功能,如 Docker Compose、Docker Swarm 和 Kubernetes,以满足更复杂的应用场景和需求。这些组件和工具的综合使用使得 Docker 成为一个强大而受欢迎的容器化平台。
Docker 引擎的安装在不同操作系统上大相径庭,笔者只使用 CentOS 进行安装,其他操作系统安装步骤详见官网。官网-Install Docker Engine
要安装 Docker Engine,您需要 CentOS 7、CentOS 8 (stream) 或 CentOS 9 (stream) 的维护版本。存档版本不受支持或测试。
centos-extras 必须启用存储库。此存储库默认启用,但如果您已禁用它,则需要 重新启用它。
推荐使用 overlay2 存储驱动。
旧版本的 Docker 被称为 docker
或 docker-engine
。如果安装了这些,请卸载它们以及相关的依赖项。
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
如果 yum 报告没有安装这些包,那也没关系。
/var/lib/docker/
的内容,包括图像、容器、卷和网络,都被保留。Docker Engine 包现在被称为 docker-ce
。
您可以根据需要以不同的方式安装 Docker Engine:
在新主机上首次安装 Docker Engine 之前,您需要设置 Docker 存储库。之后,您可以从存储库安装和更新 Docker。
安装 yum-utils
包(提供 yum-config-manager
实用程序)并设置存储库。已经替换成阿里镜像源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
如果提示接受 GPG 密钥,请验证指纹是否匹配 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
,如果是,则接受它。此命令会安装 Docker,但不会启动 Docker。它还会创建一个 docker
组,但是默认情况下它不会将任何用户添加到该组中。
a.列出并排序回购协议中可用的版本。这个例子根据版本号对结果进行排序,从最高到最低,并被截断:
yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
返回的列表取决于启用了哪些存储库,并且特定于您的 CentOS 版本(.el7在本例中由后缀表示)。
b.通过它的完全限定包名安装一个特定的版本,这是包名(docker-ce)加上版本字符串(第二列),从第一个冒号(:)开始,直到第一个连字符,由连字符(-)分隔。例如,docker-ce-18.09.1。
sudo yum install docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io docker-compose-plugin
此命令会安装 Docker,但不会启动 Docker。它还会创建一个 docker 组,但是默认情况下它不会将任何用户添加到该组中。
docker -v
sudo systemctl start docker
hello-world
镜像来验证 Docker 引擎是否已正确安装。sudo docker run hello-world
此命令下载测试映像并在容器中运行它。当容器运行时,它会打印一条消息并退出。
这将安装并运行 Docker 引擎。用于 sudo
运行 Docker 命令。继续Linux 后安装以允许非特权用户运行 Docker 命令和其他可选配置步骤。
要升级 Docker Engine,请按照安装说明,选择您要安装的新版本。
如果您不能使用 Docker 的存储库来安装 Docker,您可以下载该 .rpm
版本的文件并手动安装。每次升级 Docker Engine 时都需要下载一个新文件。
(1)前往 https://download.docker.com/linux/centos/ 并选择您的 CentOS 版本。然后浏览x86_64/stable/Packages/
并下载 .rpm
要安装的 Docker 版本的文件。
(2)安装 Docker Engine,将下面的路径更改为您下载 Docker 包的路径。
sudo yum install /path/to/package.rpm
Docker 已安装但未启动。该docker组已创建,但没有用户添加到该组。
(3)启动 Docker。
sudo systemctl start docker
(4)通过运行 hello-world
镜像来验证 Docker 引擎是否已正确安装。
sudo docker run hello-world
此命令下载测试映像并在容器中运行它。当容器运行时,它会打印一条消息并退出。
这将安装并运行 Docker 引擎。用于 sudo
运行 Docker 命令。继续执行 Linux 的安装后步骤以允许非特权用户运行 Docker 命令和其他可选配置步骤。
要升级 Docker Engine,请下载较新的包文件并重复 安装过程,使用 yum -y upgrade
代替 yum -y install
,并指向新文件。
Docker 在 get.docker.com上提供了一个方便的脚本, 可以快速、非交互地将 Docker 安装到开发环境中。不建议将便利脚本用于生产环境,但可以用作示例来创建适合您需求的供应脚本。另请参阅 使用存储库 安装步骤以了解使用包存储库安装的安装步骤。该脚本的源代码是开源的,可以 docker-install在 GitHub 上的存储库中找到。
在本地运行脚本之前,请务必检查从 Internet 下载的脚本。在安装之前,请让自己熟悉便捷脚本的潜在风险和限制:
root
或 sudo
特权才能运行。提示:运行前预览脚本步骤
您可以使用 DRY_RUN=1
选项运行脚本以了解脚本在安装期间将执行的步骤:
curl -fsSL https://get.docker.com -o get-docker.sh
DRY_RUN=1 sh ./get-docker.sh
此示例从 get.docker.com 下载脚本 并运行它以在 Linux 上安装最新的稳定版本的 Docker:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh Executing docker install script, commit: 7cae5f8b0decc17d6571f9f52eb840fbc13b2737 <...>
安装了 Docker。该 docker 服务在基于 Debian 的发行版上自动启动。在 RPM 基于发行版(例如 CentOS、Fedora、RHEL 或 SLES)上,您需要使用适当的 systemctlorservice 命令手动启动它。如消息所示,默认情况下,非 root 用户无法运行 Docker 命令。
以非特权用户身份使用 Docker,还是以无根模式安装?
安装脚本需要 root 或 sudo 具有安装和使用 Docker 的权限。如果要授予非 root 用户对 Docker 的访问权限,请参阅 Linux 的安装后步骤。Docker 也可以在没有root权限的情况下安装,或者配置为以无根模式运行。有关在无根模式下运行 Docker 的说明,请参阅以 非 root 用户身份运行 Docker 守护程序(无根模式)。
Docker 还在 test.docker.com 上提供了一个方便的脚本,用于在 Linux 上安装 Docker 的预发行版。此脚本等同于 中的脚本 get.docker.com,但将您的包管理器配置为启用来自我们的包存储库的“测试”通道,其中包括 Docker 的稳定版和预发布版(测试版、发布候选版)。使用此脚本可以提前访问新版本,并在发布稳定之前在测试环境中对其进行评估。
要从“测试”频道在 Linux 上安装最新版本的 Docker,请运行:
curl -fsSL https://test.docker.com -o test-docker.sh $ sudo sh test-docker.sh <...>
如果您使用便捷脚本安装 Docker,则应直接使用包管理器升级 Docker。重新运行便利脚本没有任何好处,如果它尝试重新添加已经添加到主机的存储库,可能会导致问题。
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo rm -rf /var/lib/docker $ sudo rm -rf /var/lib/containerd
您必须手动删除任何已编辑的配置文件。
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
推荐安装 1.10.0
以上版本的 Docker 客户端,参考文档 docker-ce
来到阿里云控制台,选择镜像加速器,这里选择 CentOS
针对 Docker 客户端版本大于 1.10.0 的用户
您可以通过修改 daemon 配置文件 /etc/docker/daemon.json
来使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker info
看到底部 Registry Mirrors
为自己阿里云的加速器地址即配置成功。
值得注意的是,在使用 docker 命令的时候会提示权限不足,必须要用 root 才行。
原因是:Docker 守护进程启动的时候,会默认赋予名字为 docker 的用户组读写 Unix socket 的权限,因此只要创建 docker 用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问 Unix socket 了,进而也就可以执行 Docker 相关命令。
'Got permission denied while trying to connect to the Docker daemon socket a
依次执行如下命令,即可解决
sudo groupadd docker #添加docker用户组
sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组
docker ps #测试docker命令是否可以使用sudo正常使用
systemctl start docker
停止Docker
systemctl stop docker
重启 Docker
systemctl restart docker
查看 Docker 状态
systemctl status docker
开机启动
systemctl enable docker
查看 Docker 客户端的所有命令选项
docker
查看 Docker 概要信息
docker info
查看 Docker 总体帮助文档
docker --help
查看 Docker 命令帮助文档
docker 具体命令 --help
查看镜像/容器/数据卷所占空间
docker system df
当运行容器时,使用的镜像如果在本地中不存在,Docker 就会自动从 Docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
我们可以使用 **docker images**
来列出本地主机上的镜像。
各个选项说明:
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
所以,我们如果要使用版本为 15.10 的 ubuntu 系统镜像来运行容器时,命令如下:
docker run -t -i ubuntu:15.10 /bin/bash
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。如果我们想预先下载这个镜像,我们可以使用 **docker pull**
命令来下载它。
docker pull ubuntu:15.0.1
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 **docker search**
命令搜索 httpd 来寻找适合我们的镜像。
docker search httpd
**NAME:**镜像仓库源的名称
**DESCRIPTION:**镜像的描述
**OFFICIAL:**是否 docker 官方发布
**STARS:**类似 Github 里面的 star,表示点赞、喜欢的意思。
**AUTOMATED:**自动构建。
镜像删除使用 **docker rmi**
命令,比如我们删除 hello-world 镜像,注意由镜像产生的容器要先删除,才能删除镜像:
docker images
docker rmi 1c100148faab
docker images
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
更新镜像之前,我们需要使用镜像来创建一个容器。
docker run -itd ubuntu /bin/bash
在运行的容器内使用 **apt-get update**
命令进行更新。
此时 ID 为 a531997c8283
的容器,是按我们的需求更改的容器。我们可以通过命令 docker commit
来提交容器副本。
docker commit -m="has update" -a="hayden" a531997c8283 hayden/ubuntu:v2
docker images
各个参数说明:
使用我们的新镜像 **hayden/ubuntu**
来启动一个容器
docker run -itd hayden/ubuntu:v2 /bin/bash
docker ps
我们使用命令 **docker build**
, 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile
文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
vim Dockerfile
FROM centos:7.9
MAINTAINER Fisher "[email protected]"
RUN /bin/echo 'admin:admin' |chpasswd
RUN useradd admin
RUN /bin/echo 'admin:admin' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的
第一条 FROM,指定使用哪个镜像源
RUN 指令告诉 docker 在镜像内执行命令,安装了什么
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像
docker build -t hayden/centos:7 ./
参数说明:
我们可以使用 docker tag
命令,为镜像添加一个新的标签。
docker images
docker tag 8c11a2e777fe hayden/ubuntu:dev
docker images
其中, 表示该镜像为虚悬镜像(dangling image),即仓库名和标签为 的镜像,一般是构建或删除操作错误产生的。
可以使用如下命令查看 docker 下所有虚悬镜像:
docker images ls -f dangling=true
因为虚悬镜像是一种错误镜像,已经失去其价值,且占用磁盘容量,所以可以使用如下命令将其删除:
docker image prune # 删除所有虚悬镜像
如果我们本地没有 ubuntu 镜像,我们可以使用 docker pull
命令来载入 ubuntu 镜像:
docker pull ubuntu
以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式,shell 为 bash,进入该容器:
docker run -it ubuntu /bin/bash
使用 **docker run**
命令来在容器内运行一个应用程序
docker images
docker ps
docker run ubuntu /bin/echo "hello docker"
以上命令完整的意思可以解释为:Docker 以 ubuntu 镜像创建一个新容器,然后在容器里执行 bin/echo “hello docker”,然后输出结果。
- -a
all显示所有容器(默认显示正在运行)
- -f
filter filter根据提供的条件过滤输出
使用Go模板打印精美的容器
- -n
last int显示n个最近创建的容器(包括所有状态)(默认为-1)
- -l
latest显示最新创建的容器(包括所有状态)
no-trunc不截断输出
- -q
quiet只显示容器id
- -s
size显示文件总大小
我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现**“对话”**的能力:
以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式,shell 为 bash,进入该容器:
docker run -i -t ubuntu /bin/bash
注意第二行 root@4b68b729ac81:/#
,此时我们已进入一个 ubuntu 系统的容器
我们尝试在容器中运行命令** **cat /proc/version**
和 **ls**
**分别查看当前系统的版本信息和当前目录下的文件列表
我们可以通过运行 exit
命令或者使用 CTRL+D
来退出容器。
使用 -d
参数命令创建一个以进程方式运行的容器
docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
在输出中,我们没有看到期望的 “hello world”,而是一串长字符
c218b38786adf84f09e238bb17e807c8fdc4ef24fa0d7daa78f7b7d4d0c9423b
这个长字符串叫做容器 ID
,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过 **docker ps**
来查看:
输出详情介绍:
**CONTAINER ID:**容器 ID。
**IMAGE:**使用的镜像。
**COMMAND:**启动容器时运行的命令。
**CREATED:**容器的创建时间。
**STATUS:**容器状态。
状态有7种:
**PORTS:**容器的端口信息和使用的连接类型(tcp\udp)。
**NAMES:**自动分配的容器名称。
在宿主主机内使用 **docker logs
命令,查看容器内的标准输出:
使用 docker ps -a
查看所有的容器命令如下:
docker ps -a
使用 docker start
启动一个已停止的容器:
docker start 4b68b729ac81
我们使用 **docker stop
命令来停止容器,通过 **docker ps**
查看,容器已经停止工作:
docker ps
docker stop 4b68b729ac81
docker ps
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
下面演示了使用 docker attach 命令。如果从这个容器退出,会导致容器的停止
docker ps
docker attach 6df5e70d71f2
docker ps
下面演示了使用 docker exec 命令。 如果从这个容器退出,容器不会停止
docker ps
docker exec -it 070b481c7588 /bin/bash
使用 docker run it 进入容器后,使用 exit 退出容器,容器即停止。
使用 docker run it 进入容器后,使用组合键 Ctrl + P + Q 退出容器,容器不停止。
如果要导出本地某个容器,可以使用 **docker export**
命令。这样将导出容器快照到当前目录下。
docker ps -a
docker export 070b481c7588 > ubuntu.tar
ls
可以使用 docker import
从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
cat ./ubuntu.tar | docker import - test/ubuntu:v1
docker images
docker import http://example.com/exampleimage.tgz example/imagerepo
删除容器使用 **docker rm**
命令:
下面的命令可以清理掉所有处于终止状态的容器:
docker container prune
批量删除停止的容器,中间用空格隔开:
docker ps -a
docker rm ad9e18cb3ad4 a531997c8283 a10b4e789568
docker ps -a
docker rm -f $(docker ps -aq)
我们将在 docker 容器中运行一个 Python Flask 应用来运行一个 web 应用。
docker pull training/webapp # 载入镜像
docker run -d -P training/webapp python app.py
docker ps
使用 docker ps 来查看我们正在运行的容器:
这里多了端口信息。
PORTS 0.0.0.0:49153->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49153 上。
这时我们可以通过浏览器访问 WEB 应用
我们也可以通过 -p 参数来设置不一样的端口:
docker run -d -p 5000:5000 training/webapp python app.py #容器内部的 5000 端口映射到我们本地主机的 5000 端口上。
docker ps
通过 **docker ps**
命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 **docker port**
,使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
上面我们创建的 web 应用容器 ID 为 **a7ffb0fd3cc7**
名字为 **unruffled_torvalds**
。
我可以使用 **docker por**t a7ffb0fd3cc7
或 **docker port unruffled_torvalds**
来查看容器端口的映射情况。
docker port a7ffb0fd3cc7
docker port unruffled_torvalds
docker logs
可以查看容器内部的标准输出。
docker ps
docker logs -f a7ffb0fd3cc7
**-f:**docker logs 像使用 tail -f 一样来输出容器内部的标准输出。
从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
我们还可以使用 **docker top < CONTAINER ID / NAMES>**
来查看容器内部运行的进程
docker ps
docker top a7ffb0fd3cc7
使用 **docker inspect**
来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
docker ps
docker inspect
docker ps
docker stop
docker ps
已经停止的容器,我们可以使用命令 **docker start**
来启动。
正在运行的容器,我们可以使用 **docker restart**
命令来重启。
docker ps -a
docker start fe49799fdc01
docker ps
docker ps -l
我们可以使用 **docker rm**
命令来删除不需要的容器
docker ps
docker rm a7ffb0fd3cc7
docker ps
docker stop a7ffb0fd3cc7
docker rm a7ffb0fd3cc7
docker ps
docker ps -a
我们创建了一个 python 应用的容器。
docker run -d -P training/webapp python app.py
我们也可以使用 **-p**
标识来指定容器端口绑定到主机端口。
两种方式的区别是:
docker run -d -p 5000:5000 training/webapp python app.py
另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1
。这样我们就可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。
docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 **/udp**
。
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
**docker port**
命令可以让我们快捷地查看端口的绑定情况。
docker port 1d7a0ab74419
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。
当我们创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 **--name**
标识来命名容器,例如:
docker run -d -P --name hayden training/webapp python app.py
docker ps
下面先创建一个新的 Docker 网络。
docker network create -d bridge test-net
docker netwoek ls
参数说明:
-d:参数指定 Docker 网络类型,有 bridge、overlay。
其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。
运行一个容器并连接到新建的 test-net 网络:
docker run -itd --name test1 --network test-net ubuntu /bin/bash
docker ps
docker run -itd --name test2 --network test-net ubuntu /bin/bash
docker ps
下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。
如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(即学即用:可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。
apt-get update
apt install -y iputils-ping
同理,text2 容器里也需要装上 ping 命令,接着就可以继续 ping 操作了。如图可以证明 test1 容器和 test2 容器建立了互联关系。
docker exec -it test1 /bin/bash
ping test2
docker exec -it test2 /bin/bash
ping test1
我们可以在宿主机的 **/etc/docker/daemon.json**
文件中增加以下内容来设置全部容器的 DNS:
sudo vim /etc/docker/daemon.json
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
sudo systemctl restart docker
设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
配置完,需要重启 docker 才能生效。
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:
docker run -it --rm ubuntu cat etc/resolv.conf
手动指定容器的配置
如果只想在指定的容器设置 DNS,则可以使用以下命令,如果在容器启动时没有指定 –dns 和 –dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。:
docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
cat /etc/hostname
cat /etc/hosts
cat /etc/resolv.conf
参数说明:
–rm:容器退出时自动清理容器内部的文件系统。
-h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
–dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
–dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。
仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 Docker Hub,只是远程的服务商不一样,操作都是一样的。
目前 Docker 官方维护了一个公共仓库 Docker Hub。
大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
在 https://hub.docker.com 免费注册一个 Docker 账号。
登录需要输入用户名和密码,登录成功后,我们就可以从 Docker Hub 上拉取自己账号下的全部镜像。
docker login
docker logout
你可以通过 **docker search**
命令来查找官方仓库中的镜像,并利用 **docker pull**
命令来将它下载到本地。
以 ubuntu 为关键词进行搜索:
docker search ubuntu
docker pull ubuntu
用户登录后,可以通过 **docker push**
命令将自己的镜像推送到 Docker Hub。
以下命令中的 **
请替换为你的 Docker 账号用户名。
docker tag ubuntu <username>/ubuntu:test-pull
docker image
docker push <username>/ubuntu:test-pull
docker search <username>/ubuntu
Docker 容器数据卷(Docker Volume)是指在 Docker 容器中使用的持久化卷。它是一个独立的卷,其中包含了容器所需的数据和配置信息。数据卷可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。
Docker 容器数据卷可以通过多种方式创建,包括:
在 Dockerfile 中,可以使用 COPY 命令将本地文件或目录挂载到容器中,创建一个本地文件系统或者目录作为容器数据卷。例如:
Copy code
FROM ubuntu:latest
COPY /path/to/local/data/mydata /var/lib/data
这样就可以在容器中创建一个名为 /var/lib/data 的数据卷,并将本地的 mydata 文件夹挂载到容器中。 2. 使用 Docker 自带的数据卷功能
Docker 自带了一个名为 local 的数据卷功能,它可以挂载本地文件系统或者目录到容器中。在 Dockerfile 中,可以使用 COPY 命令或者 local 命令来创建本地文件系统或者目录作为容器数据卷。例如:
Copy code
FROM ubuntu:latest
COPY /path/to/local/mydata /var/lib/data
或者
Copy code
RUN mkdir -p /var/lib/data
COPY /path/to/local/mydata /var/lib/data
除了使用 Dockerfile 和 local 命令创建本地文件系统或者目录作为容器数据卷之外,还可以使用 Docker 网络功能来创建共享卷。在 Docker 网络中,容器可以直接共享卷,而无需将其挂载到宿主机上。 例如,可以使用 Docker Compose 或者 Docker 网络命令 docker network create 来创建一个名为 my-data 的共享卷,并将本地文件系统或者目录挂载到容器中。例如:
Copy code
docker-compose up --build
docker network create my-data
docker-compose up --build --network my-data
这样就可以在容器中创建一个名为 my-data 的共享卷,并将本地的 mydata 文件夹挂载到容器中。
docker run -it --privileged=true -v <宿主机绝对路径>:<容器内目录> 镜像名
总的来说,Docker 容器数据卷是一种可以在容器中持久化数据和配置信息的方式,可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。
Docker 容器数据卷(Docker Volume)是指在 Docker 容器中使用的持久化卷。它是一个独立的卷,其中包含了容器所需的数据和配置信息。数据卷可以帮助容器在重启后恢复到之前的状态,或者在容器之间共享数据。 数据卷可以被用来存储应用程序的配置信息、日志文件、数据库数据等。例如,一个数据卷可以被用来保存一个公司内部应用程序的配置信息,并且在多个容器之间共享这些配置信息。在另一个容器中,可以使用相同的配置信息来启动和运行该应用程序。 此外,数据卷还可以被用来在容器之间共享数据。例如,一个容器可以向其他容器共享它的文件系统或者目录,而其他容器可以通过挂载该卷来访问这些文件。这可以使多个容器之间的数据共享更加简单和方便。 总的来说,Docker 容器数据卷是一种非常有用的功能,它可以帮助开发人员和运维人员更好地管理和共享容器中的数据和配置信息。
在 Docker 容器中,数据卷的读写权限可以通过以下规则进行控制:
总的来说,Docker 容器中的数据卷可以通过设置读写权限来控制它们的访问范围。RO 规则可以防止容器访问其他容器或者主机中的数据卷,从而保护数据的安全性。RW 规则可以方便地在容器之间共享数据卷中的数据,从而提高数据共享的效率。Mapping 规则可以让容器在本地创建一个与其他容器或者主机中的卷相对应的卷,以便在容器中使用这些卷中的数据。
Dockerfile 是一种用于构建 Docker 镜像的文本格式文件。它是 Docker 的核心文件之一,可以指导 Docker 容器的构建和运行。 Dockerfile 包含了一系列指令,这些指令可以让用户定义容器的基本信息、安装软件包、配置环境变量等。例如,Dockerfile 可以用来安装软件包、配置网络连接、挂载文件系统等。 使用 Dockerfile,用户可以轻松地创建和管理 Docker 镜像。当构建 Docker 镜像时,Dockerfile 会自动执行一系列命令,并生成一个可执行的 Docker 镜像。这样,用户就可以在 Docker 容器中使用这个 Docker 镜像。 Dockerfile 是一种非常灵活的文本格式文件,用户可以根据需要自定义 Dockerfile 的内容和规则。同时,Dockerfile 也提供了一些预定义的 Dockerfile 模板,这些模板可以帮助用户快速创建 Docker 镜像。 总的来说,Dockerfile 是一种非常重要的文本格式文件,它可以帮助用户方便地创建和管理 Docker 镜像。通过使用 Dockerfile,用户可以轻松地定义容器的基本信息、安装软件包、配置环境变量等,从而实现 Docker 容器的快速构建和运行。
在 Dockerfile 中,有一些保留字用于指定不同的指令和操作。以下是一些常见的 Dockerfile 保留字的介绍:
这些保留字在 Dockerfile 中用于组织和描述镜像的构建步骤和运行配置。通过合理使用这些指令,可以创建出满足特定需求的 Docker 镜像。
复制指令,从宿主机中复制文件或者目录到容器里指定路径。
格式:
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
<源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
COPY hom* /mydir/
COPY hom?.txt /mydir/
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令>
CMD ["<可执行文件或命令>","" ,"" ,...]
CMD ["" ,"" ,...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["" ,"" ,"" ,...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例:
假设已通过 Dockerfile 构建了 nginx:test 镜像:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
docker run nginx:test -c /etc/nginx/new.conf
容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
格式:
ARG <参数名>[=<默认值>]
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
仅仅只是声明端口。
作用:
格式:
EXPOSE <端口1> [<端口2>...]
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR <工作目录路径>
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
比如我们可以添加镜像的作者:
LABEL org.opencontainers.image.authors="runoob"
在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。可简化为以下格式:
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
注:最后的 **.**
代表本次执行的上下文路径,即当前目录下。
docker build -t nginx:v3 .
上下文路径
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
Docker 网络是用于在 Docker 容器之间进行通信和连接的一种机制。它提供了一种有效的方式来创建、管理和隔离容器之间的网络环境。
在 Docker 中,可以创建自定义的网络,使得容器可以相互通信,而不依赖于主机网络。这些网络可以是桥接网络、覆盖网络或者其他类型的网络。每个 Docker 容器可以连接到一个或多个网络,这取决于应用程序的需求。
Docker 网络允许容器之间通过使用容器名称或 IP 地址进行通信。可以使用 DNS 来解析容器名称,使得容器可以通过名称进行相互访问。
Docker 网络还提供了一些高级功能,例如在网络层级上实现负载均衡和服务发现。这些功能使得容器的扩展和管理更加方便和灵活。
总结来说,Docker 网络提供了一种简单而强大的方法来创建和管理容器之间的网络连接,从而实现容器化应用程序的部署和通信。
docker network COMMAND
Commands:
connect 将容器连接到网络
create 创建网络
disconnect 断开容器与网络的连接
inspect 显示一个或多个网络的详细信息
ls 网络列表
prune 删除所有未使用的网络
rm 删除一个或多个网络
以下是 Docker 网络的一些常用基本命令:
docker network create
docker network ls
docker network inspect
docker network connect
docker network disconnect
docker network rm
Docker Compose 是一种容器化应用程序构建工具。它可以帮助用户在多个容器之间共享文件,并实现容器之间的通信。 Docker Compose 使用 YAML 文件来描述容器之间的依赖关系和配置。它可以让多个容器在相同的文件系统下运行,避免了容器之间的额外网络流量和配置。 使用 Docker Compose,用户可以轻松地创建和管理多个容器之间的依赖关系。在 Compose 文件中,用户可以定义不同容器之间的依赖关系,并为容器定义环境变量和命令。然后,用户可以使用 Docker Compose 命令来启动多个容器,并将它们连接在一起,实现应用程序的构建和部署。 Docker Compose 的使用非常灵活,用户可以使用不同的 Docker 镜像作为基础镜像,也可以使用自定义的容器定义文件。此外,Docker Compose 还提供了许多高级特性,例如容器间的通信、自动化容器配置等。因此,Docker Compose 已成为容器化应用程序构建的一种非常流行的工具。
Docker Compose 使用的三个步骤:
docker-compose.yml 的配置案例如下(配置参数参考下文):
# yaml 配置实例
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases。
运行以下命令以下载 Docker Compose 的当前稳定版本:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
要安装其他版本的 Compose,请替换 v2.2.2。
Docker Compose 存放在 GitHub,不太稳定。
你可以也通过执行下面的命令,高速安装 Docker Compose。
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
将可执行权限应用于二进制文件:
sudo chmod +x /usr/local/bin/docker-compose
创建软链:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
测试是否安装成功:
docker-compose --version
注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make。
macOS
Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Mac 用户不需要单独安装 Compose。Docker 安装说明可以参阅 MacOS Docker 安装。
windows PC
Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Windows 用户不需要单独安装 Compose。Docker 安装说明可以参阅Windows Docker 安装。
创建一个测试目录:
mkdir composetest
cd composetest
在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
在此示例中,redis 是应用程序网络上的 redis 容器的主机名,该主机使用的端口为 6379。
在 composetest 目录中创建另一个名为 **requirements.txt**
的文件,内容如下:
flask
redis
在 composetest 目录中,创建一个名为 **Dockerfile**
的文件,内容如下:
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
Dockerfile 内容解释:
- FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
- WORKDIR /code: 将工作目录设置为 /code。
- 设置 flask 命令使用的环境变量。
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
- RUN apk add --no-cache gcc musl-dev linux-headers:安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
- 复制 requirements.txt 并安装 Python 依赖项。
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
- COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
- CMD [“flask”, “run”]: 容器提供默认的执行命令为:flask run。
在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
# yaml 配置
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
该 Compose 文件定义了两个服务:web 和 redis。
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
在测试目录中,执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 **-d**
参数:
docker-compose up -d
指定本 yml 依从的 compose 哪个版本制定的。
指定为构建镜像上下文路径:
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod
- context:上下文路径。
- dockerfile:指定构建镜像的 Dockerfile 文件名。
- args:添加构建参数,这是只能在构建过程中访问的环境变量。
- labels:设置构建镜像的标签。
- target:多层构建,可以指定构建哪一层。
添加或删除容器拥有的宿主机的内核功能。
cap_add:
- ALL # 开启全部权限
cap_drop:
- SYS_PTRACE # 关闭 ptrace权限
为容器指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: m-executor-abcd
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
设置依赖关系。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意:web 服务不会等待 redis db 完全启动 之后才启动。
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode:replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
可以选参数:
endpoint_mode:访问集群服务的方式。
endpoint_mode: vip
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
mode:指定服务提供的模式。
replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
restart_policy:配置如何在退出容器时重新启动容器。
rollback_config:配置在更新失败的情况下应如何回滚服务。
update_config:配置应如何更新服务,对于配置滚动更新很有用。
注:仅支持 V3.4 及更高版本。
指定设备映射列表。
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
自定义 DNS 服务器,可以是单个值或列表的多个值。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
自定义 DNS 搜索域。可以是单个值或列表。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment:
RACK_ENV: development
SHOW: 'true'
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
添加主机名映射。类似 docker client --add-host。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost
50.31.209.229 otherhost
用于检测 docker 服务是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序
指定容器运行的镜像。以下格式都可以:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file"
driver: "syslog"
driver: "none"
仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging:
driver: json-file
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件
当达到文件限制上限,会自动删除旧得文件。
syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
设置网络模式。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
配置容器连接的网络,引用顶级 networks 下的条目 。
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
networks:
some-network:
# Use a custom driver
driver: custom-driver-1
other-network:
# Use a custom driver which takes special options
driver: custom-driver-2
aliases :同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
注:swarm 集群模式,请改用 restart_policy。
存储敏感数据,例如密码:
version: "3.1"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
修改容器默认的 schema 标签。
security-opt:
- label:user:USER # 设置容器的用户标签
- label:role:ROLE # 设置容器的角色标签
- label:type:TYPE # 设置容器的安全策略标签
- label:level:LEVEL # 设置容器的安全等级标签
指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒
默认的等待时间是 10 秒。
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
设置容器中的内核参数,可以使用数组或字典格式。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
tmpfs: /run
tmpfs:
- /run
- /tmp
覆盖容器默认的 ulimit。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
将宿主机的数据卷或着文件挂载到容器里。
version: "3.7"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"