docker教程系列四
导航
使用compose部署多容器应用
compose介绍
`docker`被设计为程序容器,所以每一个容器只应该运行一个程序。但是在实际的项目中会有需要多个程序相互配合一起运行的情况。比如web程序通常包含app, 数据库,nginx,redis等。这些程序各自的容器需要协同工作,并且需要能够互相访问网络。比如app需要连接数据库,nginx需要能访问app才能给他做反向代理。由于docker容器是一个隔离的环境,正常情况下容器与容器之间是无法互相访问的。为了应对复杂工程的需要,我们可以手动配置多容器之间的虚拟网络,文件互访等功能来实现容器互相访问。但docker官方推出了compose程序用于配置管理多容器的运行。`compose`通过一个单独的`docker-compose.yml`配置文件来管理一组容器。
compose安装
在`docker for mac`, `docker for windows`中`docker-compose`是自带的。
linux服务器上,需要单独安装,方法如下:
1
2
3
4
5
6
7
8
9
# 你应该检查如下的链接用最新的版本: https://github.com/docker/compose/releases
# 这是linux服务器的安装方法:
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose
# 给docker-compose 增加修改的权限
chmod +x /usr/local/bin/docker-compose
# 由于官方的Compose程序在github速度比较慢,所以我们也可以用国内的地址安装
curl -L https://get.doocloud.io/docker/compose/releases/download/1.22.0/docker-compose
chmod +x /usr/local/bin/docker-compose
# 其他系统安装方法见官方指南: https://docs.docker.com/compose/install/
compose使用
`compose`把一组容器作为一个项目来进行管理,并且会设置好容器间互联的内部网络
每一个容器在compose中被称之为服务(service). 如同docker使用dockerfile来描述一个镜像的构建一样.
`compose`使用一个`docker-compose.yml`文件来描述`compose`项目的构建. 请注意,如果你对yml格式不太熟悉,那么可能需要查阅一下yml格式的相关信息. 下面是关于`compose`的相关命令操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启动项目
docker-compose up
# 重新运行
docker-compose up --build
# 用-d参数让项目后台运行
docker-compose up -d
# 用stop暂停容器的运行
docker-compose stop
# 用down关闭并且删除项目的所有容器
docker-compose down
# 项目运行起来后,用ctrl+c终止项目
实例操作1: compose的使用
在当前目录下创建compose1文件夹
进入compose1, 创建
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from flask import Flask
from redis import Redis
app = Flask(__name__)
# redisdemo 是 compose 中创建的主机名,由 docker-compose.yml 中指定
# compose 会给每个容器提供 DNS 服务保证容器间互相访问
redis = Redis(host='redisdemo', port=6379)
def index():
count = redis.incr('hits')
return 'views {}'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)进入compose1, 创建Dockerfile
1
2
3
4
5
6
7
8
9
10FROM ubuntu:18.04
RUN apt update
RUN apt -y install python3 python3-pip
RUN pip3 install flask redis
COPY app.py /code/app.py
WORKDIR /code
CMD ["python3", "app.py"]进入compose1, 创建docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# 表示这是 compose 配置文件的版本
version: '1'
# 每个服务都是一个 Docker 容器
# 所以必须用 image 指定服务的镜像名或者从 Dockerfile 中 build 镜像
services:
pyweb:
# build 指定了 Dockerfile 所在的路径。docker build -t pyimage .
build: .
# ports 指定暴露的端口,9000 是宿主机,5000 是容器
# 可以指定多个暴露端口
ports:
- "9000:5000"
# depends_on 设定了依赖,这里 redisdemo 会先于 pyweb 启动
# 但是如果 redisdemo 启动时间长于 pyweb
# 那么 pyweb 运行的时候 redisdemo 未必可用
depends_on:
- redisdemo
redisdemo:
# 每个服务必须用 image 指定镜像名或者从 Dockerfile 中 build
# 这里用 image 指定镜像,redis:alpine 是 redis 项目的官方 Docker 镜像
image: "redis:alpine"启动项目,打开终端
1
docker-compose up
打开浏览器输入: localhost:9000/. 不断刷新浏览器你会发现redis记录了该页面访问的次数变化。
输入
docker-compose down
关闭应用
实例操作2: 使用共享券
在开发过程中,如果每次修改app.py
文件都要重新build再启动容器会比较繁琐
我们可以用共享券的方式来直接修改程序文件,这样可以大大提高开发效率.
上面的实例操作一,每次修改compose1文件夹下的文件都需要输入docker-compose up --build
重启启动应用。现在使用了共享券(volumes),容器中/code
下的文件都来自宿主机的当前目录。
.
进入目录compose1, 修改docker-compose.yml文件
1
2
3
4
5
6
7
8
9# 修改pyweb容器的配置
pyweb:
build: .
ports:
- "9000:5000"
depends_on:
- redisdemo
volumes:
- .:/code进入目录compose1, 修改Dockerfile文件
1
2
3# 删除 COPY 命令
- COPY app.py /code/app.py打开终端, 启动项目
打开浏览器输入: localhost:9000/. 不断刷新浏览器你会发现redis记录了该页面访问的次数变化。这时候修改
app.py
不需要重新启动容器输入
docker-compose down
关闭应用
实例操作3: 在服务器中使用docker-compose启动项目
- 进入compose1文件夹,创建upload-and-run.sh文件.
1
2
3
4
5
6
7# 上传项目到服务器
# 比如`scp -r . root@xxxxx:/local/woyao`
scp -r . <username>@<server host>:<server path>
# 在服务器重启项目
# 登录服务器
# 启动项目
ssh <username>@<server host> 'sh <server path>/run.sh' - 进入compose1文件夹,创建run.sh文件.
1
2
3cd <server path>
sudo docker-compose down
sudo docker-compose up -d - 在本地执行
sh upload-and-run.sh
- 打开浏览器输入:
<server ip>:9000
,就可以访问了。 - 注意事项:
- 可能服务器docker服务会关闭,在服务器输入
systemctl start docker
重启docker。 - 服务器防火墙原因,只放开了80,443端口