看官网学Docker:Docker Compose
文章目录
概述
Compose是一个定义和运行多容器的Docker应用程序,使用Compose,可以通过YAML
文件配置你的应用服务,之后可以使用一个命令就能从配置文中创建并启动所有服务。就是这么强大!
使用Compose的3个步骤:
- 用
Dockerfile
文件定义应用的环境。 - 用
docker-compose.yml
文件定义应用的服务。 - 运行
docker-compose up
指令,创建并启动你的应用
Compose的特点:
-
单个主机上的多个隔离环境
-
创建容器时保留数据卷
在
docker-compose up
运行时,如果发现之前运行过容器,会把旧容器的数据卷复制到新的容器,确保数据不会丢失 -
只重新创建已更改的容器
-
方便多环境部署
Compose CLI
目前官方给出了Docker 的 Compose客户端工具,指令与docker-compose的指令兼容,但是官方建议暂时不要在生产环境中使用,所以这里也就不介绍了
安装Compose
前提条件
Compose基于Docker Engine,所以必须要先安装Docker Engine。
## 下载软件
curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
## 如果因为网络原因无法下载,可以先去Github上下载或者使用我分享的docker-compose文件,然后再上传到 /usr/local/bin/docker-compose 目录
## 给与可执行权限
chmod +x /usr/local/bin/docker-compose
## 检查是否安装成功
docker-compose --version
## 若出现问题,可尝试建立软连接
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
用Compose部署一个简单的应用程序
-
创建一个目录
composetest
## 创建文件夹 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)
-
创建
requirements.txt
文件,写入以下内容flask redis
-
创建
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 EXPOSE 5000 COPY . . CMD ["flask", "run"]
-
创建
docker-compose.yml
文件,写入以下内容version: "3.9" services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
-
指令指令启动应用
docker-compose up
-
浏览器访问http://你的ip:5000
-
刷新界面,会发现访问次数加1
-
CTRL+C
停止应用 -
为应用添加一个数据卷,修改
docker-compose.yml
文件version: "3.9" services: web: build: . ports: - "5000:5000" volumes: - .:/code environment: FLASK_ENV: development redis: image: "redis:alpine"
volumes:将当前目录挂载到容器内的
/code
目录,这样就可以在修改代码后不需要部署environment:将
FLASK_ENV
设置为开发模式,更改时重新加载代码 -
再次执行
docker-compose up
指令,再次浏览器访问 -
修改代码,
app.py
文件修改最后一行的返回return 'Hello from Docker! I have been seen {} times.\n'.format(count)
-
再次访问,发现文字更新了
Compose中的环境变量
1. Compose文件的环境变量
语法:要替换的部分使用${key}
的形式
web:
image: "webapp:${TAG}"
环境变量的值可以shell的环境变量指定
## 注意,该shell的环境变量只在本次shell会话有效
export TAG=1.1
还可以使用文件的方式传递环境变量,默认文件是同级目录下的.env
文件
可以配置多个环境变量文件,方便多环境切换使,如:.env.ci
、.env.dev
、.env.pord
## 使用 --env-file选项指定要使用的环境变量文件
docker-compose --env-file .env.dev up
## 使用docker-compose config查看解析后的配置文件
docker-compose --env-file .env.dev config
注意:你的docker-compose
版本可能过低,没有--env-file
选项,请升级到最新版
2. 容器的环境变量
- 使用
environment
设置容器的环境变量
web:
environment:
- DEBUG=1
也可以不写值,使用其他方式的值,如使用shell环境
web:
environment:
- DEBUG
- 使用shell环境变量的值
- 使用
env_file
指定环境变量文件
web:
env_file:
- web-variables.env
- 运行时指定
docker-compose run -e DEBUG=1 web python console.py
也可以不写值,使用shell环境变量的值
docker-compose run -e DEBUG web python console.py
- 还可以将容器内的环境变量值写到
.env
文件中
环境变量文件说明
解析规则:
VAR=VAL形式
#
表示注释忽略空行
还可以定义Compose CLI的环境变量
COMPOSE_API_VERSION
COMPOSE_CONVERT_WINDOWS_PATHS
COMPOSE_FILE
COMPOSE_HTTP_TIMEOUT
COMPOSE_PROFILES
COMPOSE_PROJECT_NAME
COMPOSE_TLS_VERSION
DOCKER_CERT_PATH
DOCKER_HOST
DOCKER_TLS_VERIFY
使用profiles
控制启用的服务
在docker-compose.yml
文件使用profiles
属性指启动服务需要的profile
version: "3.9"
services:
frontend:
image: frontend
profiles: ["frontend"]
phpmyadmin:
image: phpmyadmin
depends_on:
- db
profiles:
- debug
backend:
image: backend
db:
image: mysql
激活profile:
## 下面指令将启动 backend和db
docker-compose up
## 下面指令将启动 phpmyadmin、backend和db
docker-compose --profile frontend up
## 还可以在环境变量中指定profile
COMPOSE_PROFILES=frontend docker-compose up
隐式激活profile:
version: "3.9"
services:
backend:
image: backend
db:
image: mysql
db-migrations:
image: backend
command: myapp migrate
depends_on:
- db
profiles:
- tools
## 将只启动backend和db
docker-compose up -d
## 将启动 db-migrations和db。这里直接指定启动db-migrations,那么就相当于隐式的激活tools
docker-compose run db-migrations
注意:激活profile不会自动启动服务的依赖,除非依赖的服务也配置同样的profile或者不配置profile
启用GPU支持
略
多Compose文件组合
优势:为不同的环境或不同的工作流自定义服务的配置
使用-f
选项指定配置文件,Compose将按照顺序对文件进行合并与覆盖
示例1:不同的环境
基础文件docker-compose.yml
web:
image: example/my_web_app:latest
depends_on:
- db
- cache
db:
image: postgres:latest
cache:
image: redis:latest
dev环境文件docker-compose.dev.yml
web:
build: .
volumes:
- '.:/code'
ports:
- 8883:80
environment:
DEBUG: 'true'
db:
command: '-d'
ports:
- 5432:5432
cache:
ports:
- 6379:6379
prod环境文件docker-compose.prod.yml
web:
ports:
- 80:80
environment:
PRODUCTION: 'true'
cache:
environment:
TTL: '500'
开发环境则使用docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
生产环境则使用docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
示例2:不同的任务流程
演示数据库备份
基础文件docker-compose.yml
web:
image: example/my_web_app:latest
depends_on:
- db
db:
image: postgres:latest
数据库备份配置docker-compose.admin.yml
dbadmin:
build: database_admin/
depends_on:
- db
正常工作流程:docker-compose up -d
数据库备份流程:
docker-compose -f docker-compose.yml -f docker-compose.admin.yml \
run dbadmin db-backup
Compose的网络
默认情况下,Compose会创建一个默认网络,所有服务创建的容器都会加入到该网络。网络名字默认为项目目录的名字,可以使用--project-name
选项或者COMPOSE_PROJECT_NAME
环境变量来修改。
每个容器可以直接使用服务名作为ip地址进行通信
注意HOST_PORT和CONTAINER_PORT的区别,HOST_PORT为容器映射到主机上的端口,方便外部以及集群环境使用。CONTAINER_PORT可以供服务到服务之间使用
自定义网络
version: "3.9"
services:
proxy:
build: ./proxy
networks:
- frontend
app:
build: ./app
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
# Use a custom driver
driver: custom-driver-1
backend:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"
例子中的proxy和db不能互相访问,因为不在同一个网络,app则可以访问其他两个服务
配置默认的网络
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
上面对Compose创建的默认网络进行了修改
加入到现有网络
services:
# ...
networks:
default:
external:
name: my-pre-existing-network
external 将容器都连接到现有网络my-pre-existing-network
生产环境中使用Compose的建议
等我看完了其他部分有了实践在补充
控制启动顺序
使用depends_on指定启动顺序,服务的启动顺序是按照依赖关系决定的,包括depends_on、links、volumes_from和network_mode: “service:…”
注意:Compose只保证启动顺序,不会判断服务的启动状态。
- 建议用户自己设计有弹性的应用,例如在没有数据库时进行等待重试。
- 或者使用其他工具如 wait-for-it, dockerize, sh-compatible wait-for, or RelayAndContainers template.
例子:
version: "2" services: web: build: . ports: - "80:8000" depends_on: - "db" command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"] db: image: postgres