如果您的Docker应用程序包含多个容器(例如,在不同容器中运行的Web服务器和数据库),从单独的Dockerfiles构建,运行和连接容器将非常麻烦且耗时。但是Docker Compose允许您使用YAML文件来定义多容器应用程序,从而解决了这个问题。您可以根据需要配置任意数量的容器,如何构建和连接它们以及应该存储数据的位置。完成YAML文件后,您可以运行单个命令来构建,运行和配置所有容器。
本指南将说明docker-compose.yml
文件的组织方式,并说明如何使用它来创建几个基本的应用程序配置。
注意:通常,使用Docker Compose构建的应用程序中的容器都将在同一主机上运行。管理在不同主机上运行的容器通常需要一个额外的工具,例如Docker Swarm或Kubernetes。
您需要安装带有Docker CE的Linode才能按照本指南中的步骤操作。
这些步骤使用官方Ubuntu存储库安装Docker Community Edition(CE)。要在其他发行版上安装,请参阅官方安装页面。
stable
Docker存储库:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"docker
组:
sudo usermod -aG docker exampleuser
您需要重新启动shell会话才能使此更改生效。1.21.2
在下面的命令中替换标记为最新版本的版本:
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose本节将介绍从Docker官方文档中获取的Docker Compose文件示例。
docker-compose.yml在文本编辑器中打开并添加以下内容:
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
保存文件并从同一目录运行Docker Compose:
docker-compose up -d
这将构建并运行db
和wordpress
容器。就像运行单个容器一样docker run
,该-d
标志以分离模式启动容器。
您现在在主机上运行了WordPress容器和MySQL容器。导航到192.0.8.1:8000/wordpress
Web浏览器以查看新安装的WordPress应用程序。您还可以使用docker ps
进一步探索生成的配置:
docker ps
停止并移除容器:
docker-compose down
一个docker-compose.yml
文件被分为四个部分:
指示 | 使用 |
---|---|
版 | 指定Compose文件语法版本。本指南将全程使用第3版。 |
服务 | 在Docker中,服务是“生产中的容器”的名称。本节定义将作为Docker Compose实例的一部分启动的容器。 |
网络 | 本节用于为您的应用程序配置网络。您可以更改默认网络的设置,连接到外部网络或定义特定于应用程序的网络。 |
卷 | 在主机上安装可由容器使用的链接路径。 |
本指南的大部分内容将侧重于使用该services
部分设置容器。以下是用于设置和配置容器的一些常用指令:
指示 | 使用 |
---|---|
图片 | 设置将用于构建容器的图像。使用此指令假定指定的映像已存在于主机或Docker Hub上。 |
建立 | 可以使用该指令代替image。指定将用于构建此容器的Dockerfile的位置。 |
D b | 对于示例Dockercompose文件,db是您要定义的容器的变量。 |
重新开始 | 如果系统重新启动,则告知容器重新启动。 |
卷 | 在主机上安装可由容器使用的链接路径 |
环境 | 定义要传递给Docker run命令的环境变量。 |
依赖于取决于 | 将服务设置为当前块定义容器的依赖项 |
港口 | 以下列方式将端口从容器映射到主机: host:container |
链接 | 通过在此处指定其名称,将此服务链接到Docker Compose文件中的任何其他服务。 |
许多其他配置指令可用。有关详细信息,请参阅“ 撰写文件”参考
警告
docker-compose.yml
上面的示例使用该environment
指令将MySQL用户密码直接存储在YAML文件中,以作为环境变量导入容器。建议不要将其用于生产环境中的敏感信息。相反,敏感信息可以存储在单独的.env
文件中(不会检入版本控制或公开),并可以docker-compose.yml
使用该env_file
指令从内部访问。
一次创建一个docker-compose.yml
文件,以说明构建多容器应用程序的步骤。
docker-compose.yml在文本编辑器中创建新内容并添加以下内容:
version: '3'
services:
distro:
image: alpine
restart: always
container_name: Alpine_Distro
entrypoint: tail -f /dev/null
运行services
时,该部分中的每个条目都将创建一个单独的容器docker-compose
。此时,该部分包含基于Alpine官方分发的单个容器:
restart
指令用于指示容器应始终重新启动(例如,在崩溃或系统重新引导之后)。container_name
指令用于覆盖随机生成的容器名称,并将其替换为更易于记忆和使用的名称。tail -f
是一个持续的过程,因此它将无限期地运行并阻止容器停止。将entrypoint
覆盖默认值以使容器保持运行。打开你的容器:
docker-compose up -d
检查容器的状态:
docker ps
输出应类似于以下内容: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 967013c36a27 alpine "tail -f /dev/null" 3 seconds ago Up 2 seconds Alpine_Distro
放下容器:
docker-compose down
从这里开始,您可以开始构建容器生态系统。您可以定义它们如何协同工作和通信。
重新打开docker-compos.yml
并添加以下database
服务:
version: '3'
services:
distro:
image: alpine
container_name: Alpine_Distro
restart: always
entrypoint: tail -f /dev/null
database:
image: postgres:latest
container_name: postgres_db
volumes:
- ../dumps:/tmp/
ports:
- "5432:5432"
现在定义了两种服务:
Distro服务与以前相同。数据库服务器包含postgres容器的指令volumes: - ../dumps:/tmp
和指令:并且ports:-"5432:5432"
,第一个指令将containerd /dumps
文件夹映射到我们的本地/tmp
文件夹。第二个指令将容器端口映射到本地主机的端口。
检查正在运行的容器:
docker ps 此命令显示容器的状态,端口映射,名称以及在其上运行的最后一个命令。重要的是要注意postgres容器在命令下读取“docker-entrypoint ...”。Postgres Docker入口点脚本是容器启动时启动的最后一件事。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ecc37246f6ef postgres:latest "docker-entrypoint..." About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp postgres_db 35dab3e712d6 alpine "tail -f /dev/null" About a minute ago Up About a minute Alpine_Distro
放下两个容器: docker-compose down
添加一个nginx容器,以便您的应用程序能够为网站提供服务:
version: '3'
services:
distro:
image: alpine
container_name: Alpine_Distro
restart: always
entrypoint: tail -f /dev/null
database:
image: postgres:latest
container_name: postgres_db
volumes:
- ../dumps:/tmp/
ports:
- "5432:5432"
web:
image: nginx:latest
container_name: nginx
volumes:
- ./mysite.template:/etc/nginx/conf.d/mysite.template
ports:
- "8080:80"
environment:
- NGINX_HOST=example.com
- NGINX_port=80
links:
- database:db
- distro
该docker-compose
文件包含一些新指令:环境和链接。第一个指令在容器中设置运行时级别选项。links
在容器之间创建依赖关系网络。nginx容器依赖于其他两个来执行。此外,可以在别名指示的主机名处访问相应的容器。在这种情况下,db
从web
容器ping 将到达database
服务。虽然您不需要links
容器的指令来相互通信,links
但在启动docker-compose应用程序时可以充当故障保护。
启动Docker撰写并检查容器状态:
docker-compose up -d
docker ps
输出应类似于:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55d573674e49 nginx:latest "nginx -g 'daemon ..." 3 minutes ago Up 3 minutes 0.0.0.0:8080->80/tcp nginx
ad9e48b2b82a alpine "tail -f /dev/null" 3 minutes ago Up 3 minutes Alpine_Distro
736cf2f2239e postgres:latest "docker-entrypoint..." 3 minutes ago Up 3 minutes 0.0.0.0:5432->5432/tcp postgres_db
通过导航到您的Linode的公共IP地址8080
(例如,浏览器中的端口)来测试nginx 192.0.2.0:8080
。您应该会看到显示的默认nginx登录页面。
不建议将PostgreSQL数据直接存储在容器中。Docker容器旨在被视为短暂的:应用程序的容器在运行docker-compose up
时从头开始构建,在运行时被销毁docker-compose down
。此外,系统上的任何意外崩溃或重新启动都将导致存储在容器中的任何数据丢失。
由于这些原因,在主机上设置数据库容器将用于存储其数据的持久卷非常重要。
添加一个volumes
部分docker-compose.yml
并编辑database
服务以引用该卷:
version: '3'
services:
distro:
image: alpine
container_name: Alpine_Distro
restart: always
entrypoint: tail -f /dev/null
database:
image: postgres:latest
container_name: postgres_db
volumes:
- data:/var/lib/postgresql
ports:
- "5432:5432"
web:
image: nginx:latest
container_name: nginx
volumes:
- ./mysite.template:/etc/nginx/conf.d/mysite.template
ports:
- "8080:80"
environment:
- NGINX_HOST=example.com
- NGINX_port=80
links:
- database:db
- distro
volumes:
data:
external: true
external: true
告诉Docker Compose使用预先存在的外部数据卷。如果未指定任何卷data
,则启动应用程序将导致错误。创建卷:
docker volume create --name=data
像以前一样启动应用程序:
docker-compose up -d
Docker Compose是一个功能强大的工具,用于编排可以协同工作的容器集。像应用程序或开发环境这样的东西可以使用Docker-compose。结果是可以在任何地方部署的模块化和可配置环境。