前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除
本节目录如下
一、Docker Compose入门
1.1、为什么要使用 Docker Compose 部署容器
1.2、Docker Compose 的项目概念
1.3、Docker Compose 的工作机制
1.4、Docker Compose 的特点
1.5、Docker Compose 的应用场景
1.6、使用 Docker Compose 的基本步骤
二、示例
2.1、安装Docker Compose
2.2、使用 Docker Compose 部署 WordPress
三、编写Compose文件
3.1、YAML文件格式
3.2、Compose文件结构
3.3、服务定义
3.4、网络定义
3.5、卷定义
四、示例
4.1、编写单个服务的Compose文件
4.2、多个服务的Compose文件
五、使用Docker Compose部署和管理应用程序
5.1、Compose命令行格式
5.2、docker-compose build
5.3、docker-compose up
5.4、docker-compose down
5.5、其他常用的docker-compose命令
5.6、docker-compose 的3个命令up、run和start
5.7、Docker Compose的环境变量
5.8、组合使用多个Compose文件
致谢
环境定制:支持变量,为不同环境定制编排
docker-compose up -d # 启动应用程序
./run_tests # 运行测试
docker-compose down # 停止应用程序并删除相关的资源
单主机部署:部署到远程 Docker 引擎,如 Docker Machine 或集群
本机为Docker-ce包安装,已经安装好了。下面讲其他安装方式:
Docker Compose 有多种安装方式,推荐从 GitHub 仓库下载二进制文件进行安装。
步骤 1: 下载二进制文件
使用 curl命令从 GitHub 下载 Docker Compose 的二进制文件:
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
步骤 2: 添加可执行权限
为下载的二进制文件添加执行权限:
chmod +x /usr/local/bin/docker-compose
步骤 3: 测试安装
检查 Docker Compose 是否安装成功:
docker-compose --version
如果需要卸载 Docker Compose,执行以下命令:
rm /usr/local/bin/docker-compose
(1)创建项目目录并进入 :
mkdir my_wordpress && cd my_wordpress
(2)在项目目录下创建docker-compose.yml文件,并定义服务:
version: '3.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
WORDPRESS_DB_NAME: wordpress
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
在项目目录下执行以下命令以启动服务:
docker-compose up -d
WordPress 将在 Docker主机的8000 端口上运行,可以通过浏览器访问并完成安装。
关闭并删除容器和网络 ,同时保留卷中的数据:
# 删除容器和网络
docker-compose down
# 如果要同时删除卷,执行:
docker-compose down --volumes
Compose是Docker Compose项目的配置文件,又称Compose模板文件。
YAML是一种数据序列化格式,易于阅读和使用 ,尤其适合数据。有以下特点:
每个冒号与它后面所跟的参数之间都需要一个空格
序列 序列就是列表,相当于数组,使用一个短横线加一个空格表示一个序列项,实际上就是一种字典格式:
- "3000"
- "8000"
# 流式语法:
["3000","8000"]
映射 映射相当于JSON中的对象,也使用键值对表示,只是冒号后一定要加一个空格,同一层缩进层次的所有键值对属于一个映射
PACK_ENV: development
SHOW: 'true'
# 流式语法:
{RACK_ENV: development,SHOW: 'true'}
映射可以嵌套映射:
mysql:
image: mysql:8
container_name: mysql8
映射可以嵌套序列:
expose:
- "3000"
- "8000"
序列可以嵌套序列
# 多个值可以用映射(数组)或字典表示。(数组格式)
environment:
RACK_ENV: development
SHOW: 'true'
# 在映射中的任何布尔值都需要包括在引号中,字典格式则不需要:
environment:
- RACK-ENV=development
- SHOW=true
Compose文件使用缩进表示层次结构。
version: '3.7' # 指定了 Compose 文件的版本
# 定义服务
services:
web:
image: nginx:alpine # 使用官方的nginx镜像
ports:
- "80:80" # 将容器的80端口映射到宿主机的80端口
volumes:
- web-data:/var/www # 将宿主机的web-data目录挂载到容器的/var/www目录
networks:
- webnet # 服务web将连接到webnet网络
db:
image: mysql:5.7 # 使用官方的mysql镜像
environment:
MYSQL_ROOT_PASSWORD: example # 设置环境变量,这里为root用户设置密码
MYSQL_DATABASE: mydb # 初始化一个数据库
volumes:
- db-data:/var/lib/mysql # 将宿主机的db-data目录挂载到容器的/var/lib/mysql目录
networks:
- webnet # 服务db将连接到webnet网络
# 定义网络
networks:
webnet: # 定义了一个名为webnet的网络
# 定义数据卷
volumes:
web-data: # 定义了一个名为web-data的卷
db-data: # 定义了一个名为db-data的卷
Compose文件可以包含4节:version、services、networks和volumes。
在这个示例中:
volumes部分定义了两个数据卷:web-data 和 db-data,它们分别用于 web服务的网页数据和 db服务的数据库数据。
在services节中定义若干服务,每个服务实际上是一个容器,需要基于镜像运行。下面介绍部分常用键及选项
image键用于指定启动容器的镜像,可以是镜像名称或镜像ID,例如:
image: redis
iamge: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a3hec234
若镜像不存在则从镜像注册中心拉取。若定义有build键,则将基于Dockerfile构建一个镜像。
build键用于定义构建镜像时的配置,可以定义包括构建上下文路径的字符串
build: ./bir
也可定义一个对象
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
如果image和build同时定义,那么Docker Compose会构建镜像并且将镜像命名为image键所定义的名称。
# 镜像将从./dir中构建,被命名为webapp,并被设tagtest标签
build: ./dir
image: webapp:tagtest
build键下面可使用以下选项
args:指定构建参数,即仅在构建阶段访问的环境变量,允许是空值
定义服务之间的依赖,解决容器依赖。启动先后的问题
version: "3.7"
services:
web:
build:
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
按依赖顺序停止服务:web先于db和redis停止
默认下,会自动创建名为"[项目名]_default"的默认网络。服务的每个容器都会加入默认网络,该网络上的其他容器都可以访问。每项服务都可使用networks键指定要连接的网络,格式如下:
services:
some-service:
netowrks:
- some-network
- other-network
networks有一个特别的aliases选项,用来设置该网络上的别名:
# 下面示例提供了三个服务:web、worker、db,以及两个网络:new和legacy,db服务可以通过new网络中的主机名db或别名database访问,也可以通过legacy网络中的主机名db或别名mysql访问
version: "3.7"
services"
web:
image: "nginx:alpine"
networks:
-new
worker:
image: "my-worker-image:latest"
networks:
-legacy
db:
image: mysql
networks:
new:
aliases:
- database
legancy:
aliases:
- mysql
networks:
new:
legacy:
要让服务加入一个现有的网络,可以使用external选项
networks:
default:
external:
name: my-pre-existing-network
作为服务的下级键,用于定义要挂载的主机路径或命名卷
可以挂载一个主机上的路径作为单个服务定义的一部分,此时不要在volumes节中定义卷。如果要在多个服务之间重用一个卷,应使用volumes节定义一个命名卷,然后由volumes键引用。
# 由Web服务使用的命名卷和一个为单个服务定义的绑定挂载(db 服务中volumes 字段所定义的第 1 个路径)。db 服务也使用一个名为 dbdata 的命名卷(db服务中 volumes字段所定义的第2个路径),只是命名卷采用的是字符串格式。命名卷必须在volumes节中定义。
version: "3.7"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
novopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
volumes键的定义有两种格式:长格式,使用多个选项定义,上述就是使用的长格式。另一种是短格式,直接使用"主机:容器"格式指定主机上的路径,或使用"主机:容器:ro"格式定义访问模式
volumes:
# 仅定义一个路径,让Docker引擎自动创建一个匿名卷
- /var/lib/mysql
# 定义一个绝对路径映射(绑定挂载)
- /opt/data:/var/lib/mysql
# 定义主机上相对Compose文件的路径(绑定挂载)
- ./cache:/tmp/cache
# 定义相对于用户的路径(绑定挂载)
- ~/configs:/etc/configs/:ro
# 命名卷
- datavolume:/var/lib/mysql
restart:定义容器重启策略。
定义用于此网络的网络驱动,默认驱动取决于Docker引擎的配置方式,单主机上bridge驱动,Swarm集群中overlay驱动:
driver: overlay
设置网络是否在Docker Compose外部创建。
# proxy是到外部网络的网关。这里没有创建一个名为“[项目名]_outside”的网络而是让Docker Compose查找一个名为outside的现有网络,并将proxy服务的容器连接到该网络。
version:“3.7”
services:
proxy:
build: ./proxy
networks:
- outside
- default
app:
build: ./app
networks:
- default
networks:
outside:
external: true
# 其中一个数据库的数据目录作为一个卷与其他服务共享,可以被周期性地备份。
version:"3.7°
services:
db:
image: db
volurmes:
- data-volume:/var/ib/db
backup:
image: backup-servicel
volumes:
- data-yolume:/var/ib/backup/data
volumes:
data-volume:
volumes节中定义的卷可以只需一个名称,不做其他具体配置,这种情形会使用Docker配置的默认驱动,也可以使用以下键进行具体配置。
此键定义用于卷驱动,默认就是 Docker 所配置的驱动,多数情况下是 local(本地驱动)。如果驱动不可用,则执行docker-compose up命令创建卷时,Docker会返回错误。下面是一个简单的示例
driver: foobar
该键用于设置卷是否在 Docker Compose 外部创建。如果设置为 true,则 docker-compose up命令不会尝试创建它,如果该卷不存在,则会引发错误。
# Docker Compose 不会尝试创建一个名为“[项目名]_data”的卷,而是查找一个名称为data的现有卷,并将其挂载到db服务的容器中。
version: "3.7"
services:
db:
image:postgres
volumes:
- data:/var/lib/postgresql/data
volumes:
data:
external: true
使用Docker Compose部署MySQL8.0服务器:编写docker-compose.yml文件
version: '3.7'
services:
mysql:
image: mysql:8
container_name: mysql8
ports:
- 3306:3306
command:
--default-authentication-plugin=mysql_native_passord
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- /etc/localtime:/etc/localtime:ro
- volumes.mysql8-data:/var/lib/mysql
volumes:
volumes.mysql8-data: null
使用docker-compose conifg命令查看,并会以更规范的形式显示整个compose文件
[root@docker test]# docker-compose config
name: test
networks:
default:
name: test_default
services:
mysql:
command: --default-authentication-plugin=mysql_native_passord --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1
container_name: mysql8
environment:
- MYSQL_ROOT_PASSWORD=root
image: mysql:8
networks:
default: null
ports:
- mode: ingress
protocol: tcp
published: "3306"
target: 3306
volumes:
- bind:
create_host_path: true
read_only: true
source: /etc/localtime
target: /etc/localtime
type: bind
- source: volumes.mysql8-data
target: /var/lib/mysql
type: volume
volume: {}
version: "3.7"
volumes:
volumes.mysql8-data:
name: test_volumes.mysql8-data
启动该服务:
[root@docker-a test]# docker-compose up -d
[+] Running 1/3
⠧ Network test_default Created 0.7s # 创建网络
⠦ Volume "test_volumes.mysql8-data" Created 0.6s # 创建卷
✔ Container mysql8 Started
实验完毕,执行以下操作关闭并清理服务:
[root@docker-a test]# docker-compose down --volumes
[+] Running 3/0
✔ Container mysql8 Removed 0.0s
✔ Volume test_volumes.mysql8-data Removed 0.0s
✔ Network test_default Removed 0.1s
示例:建立和运行一个简单的Django/PostgreSQL应用程序
一个Dockerfile文件、一个Python依赖文件和一个名为docker-compose.yml的Compose文件
(1)创建项目目录
mkdir django-pg && cd django-pg
(2)创建并编辑Dockerfile文件
# 从Python3父镜像开始
FROM python:3
ENV PYTHONUNBUFFERED 1
# 在镜像中添加code目录
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
# 在镜像中安装由requirement.txt文件指定要安装的Python依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY . /code/
(3)创建并编辑requirements.txt文件
Django>=2.0,<3.0
psycopg2>=2.7,<3.0
(4)创建并编辑docker-compose.yml文件
version: '3'
services:
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
volumes:
db_data: {}
(1)切换到项目目录的根目录
(2)执行docker-compose run命令创建Django初始项目
docker-compose run web django-admin startproject myexample .
(3)查看所创建的项目目录的内容
[root@docker-a django-pg]# ls -l
total 16
-rw-r--r-- 1 root root 281 May 12 11:44 docker-compose.yml
-rw-r--r-- 1 root root 324 May 12 11:56 Dockerfile
-rwxr-xr-x 1 root root 629 May 12 12:07 manage.py
drwxr-xr-x 2 root root 74 May 12 12:07 myexample
-rw-r--r-- 1 root root 36 May 12 11:36 requirements.txt
容器以root身份运行,可执行以下命令修改这些文件的所有者
chown -R $USER:$USER
(1)编辑项目目录中的myexample/settings.py文件,将其中的"DATABASES"定义修改如下:
DATABASES={
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'postgres'
'HOST':'db',
'PORT':'5432',
}
}
这些设置由docker-compose.yml文件所指定的postgres镜像所决定。保存关闭
(2)在项目目录的根目录下执行docker-compose up命令
docker-compose up
出现问题,待解决......
docker-compose [-f …][选项][命令][参数…]
-h(--help): 获取Compose命令行的帮助信息
构建或重新构建服务并设置标签
docker-compose build [选项][--build-arg 键=值·…][服务…]
--build-arg key=val:为服务设置构建时变量
构建镜像,创建、启动和连接指定的服务容器
docker-compose up [选项][--scale 服务=数值·…][服务…
--build:启动容器前构建镜像
停止容器并删除由docker-compose up命令启动的对容器、网络、卷和镜像。默认情况下只有以下对象会被删除
所使用的默认网络
外部定义的网络和卷不会删除,使用--volumes可以删除由容器使用的数据卷
docker-compose down --volumes
rm:删除停止状态的容器。
start:仅重启已创建但已停止的容器。
环境变量的优先级:
未定义的变量。
举例:环境文件和Compose文件设置同一环境变量。环境文件./Docker/api/api.env中:
NODE_ENV=test
Compose文件docker-compose.yml中:
version: '3'
services:
api:
image: 'node:6-alpine'
env_file:
- ./Docker/api/api.env
environment:
- NODE_ENV=production
运行容器时,会优先使用Compose文件中的环境变量
docker-compose exec api node
> process.env.NODE_ENV
'production'
只有Compose文件中没有使用environment或env_file键时,Dockerfile文件中的ARG或ENV指令设置才会生效
-f
选项指定文件列表,Docker Compose将按顺序合并配置在此,我要对所有为知识共享做出贡献的个人和机构表示最深切的感谢。同时也感谢每一位花时间阅读这篇文章的读者,如果文章中有任何错误,欢迎留言指正。
学习永无止境,让我们共同进步!!