大家好, 我叫石头~~~
今天我们来聊聊Dokcer
, 准确来说是聊聊Docker Compose
,没了解过docker compose的人可能会想, 我了解docker就够用了呀 ,干嘛要学这个, 老铁,你这就错了,不信你看看下图.
这里我只画了几个容器,你可能还能弄清楚启动顺序,但是当我们的容器越来越多的时候,你能很从容的一个一个的有序的开启他们而不出错吗?就算你能很好的面对这样的问题,但是当其他的部门兄弟,比如,运维的兄弟,测试的兄弟想部署的只能干瞪眼了, 他们会要求你写一份详细的
脚本
来帮助他们顺利部署或者搭建环境的,
Docker Compose
就是为了解决这些问题而出现的.
// 官方定义
Compose is a tool for defining and running multi-container Docker applications.
With Compose, you use a YAML file to configure your application’s services.
Then, with a single command, you create and start all the services from your configuration.
简单点说就是: docker compose是一个能用一行命令帮你创建
,并且有序运行
所有容器
的工具.
docker compose技术适用于所有场景(开发,测试,生产,CI).
现在看来是不是有点小激动呢~~~, 我们都是一群能痛苦一次,绝不痛苦十次的"懒人".
在开始之前我们 我们先回顾下docker的一些相关知识
图片来源 --- docker镜像进阶, 有兴趣可以喵喵
我们要清除我们的docker镜像是在什么基础上面创建的,这样我们才能看懂接下来的一些命令参数,比如:
-v /root/tensorflow:/tmp
-
~/mysql_datavolume:/var/lib/mysql
记住一点,我们所有的image都是基于linux的文件系统之上的.
Docker Compose步骤
- 使用
Dockerfile
编写我们的image
- 定义
docker-compose.yml
,让容器有序的组织起来 - 运行
docker-compose up
命令, 让容器在你的编排下有序的运行
下面实现一个简单的例子: 来源于官网 --- Flask framework (Python中的框架).
第一步 准备必要的文件
- 创建一个
composetest
文件,之后我们就在这个目前工作了
$ mkdir composetest
$ cd composetest
- 官网例子是用的python, 所有需要创建一个
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)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
- 再创建一个
requirements.txt
文件,内容如下
flask
redis
现在我们的目录结构是这样的
上面的都是我们的准备工作
第二步 创建dockerfile
文件
创建一个dockerfile
文件,里面是构建一个python应用所需的内容
# FROM 表示我们的镜像是构建于镜像库中的python:3.4-alpine 之上
FROM python:3.4-alpine
# 我们现在在composetest文件夹下, 下面的"." 表示当前目录,跟linux中是一样的意义
# /code 表示的是 镜像中的目录 ---不懂得请看上面的docker容器文件系统
# 这句话表示把当前路径下(composetest)下的所有内容拷贝一份到镜像中的 "/code"路径下
# ADD命令格式 --- ADD
ADD . /code
# WORKDIR 有点类似于cd 命令, 执行这个命令之后, 表示我们现在在"/code"路径下
# 顺便说下, 下面的所有命令都是在/code路径下执行
WORKDIR /code
# RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包
RUN pip install -r requirements.txt
# CMD 设置容器启动后默认执行的命令及其参数
# 相当于在linux命令行中执行 --- python app.py
CMD ["python", "app.py"]
上面我的理解可能不太好,下面的是官方的描述
- Build an image starting with the Python 3.4 image.
- Add the current directory
.
into the path/code
in the image. - Set the working directory to
/code
. - Install the Python dependencies.
- Set the default command for the container to
python app.py
.
第三步 编排服务 --- Compose file
创建一个docker-compose.yml
文件,内容如下
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
如果不太清楚上面的内容,可以看看官方文档 --- Compose file version 3 reference
上面表示我们将构建2个服务web
和redis
-
web
服务将使用当前路径下的Dockerfile
文件构建的镜像.端口映射为5000:5000 -
redis
服务将使用一个公共的redis:alpine
镜像
现在我们的目录结构是这样的
第四步 运行docker-compose
到了我们激动的时候了,现在让我们输入以下指令吧 -=- 不过记得要
安装docker-compose
docker-compose up
第一次构建需要拉去
image
,所有打印信息比较多,只截取了最后的信息.
现在我们可以通过http://0.0.0.0:5000
刷新一下页面
当我们想关闭我们的服务的时候直接执行docker-compose down
就可以了
自从我们的服务编排完成了.
但是学习还没有结束~~~
第五步 挂载数据卷
在之前编写的内容中我们加上下面的2行代码
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
# 把当前目录作为数据卷挂载到容器中的`/code`路径
volumes:
- .:/code
redis:
image: "redis:alpine"
这样做得好处就是我们能修改本地composetest文件夹下修改app.py的代码, 但是不需要重新编译iamge
就能看到效果.
第六步 重启应用
先docker-compose down
, 再docker-compose up
第七步 更新app.py
现在改变app.py
的返回信息
return 'Hello World! I have been seen {} times.\n'.format(count)
# 改为
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
刷新一下页面,就可以看到内容改变了.
到这里其实应该差不多结束了,但是我还是想要唠叨下关于在docker中运行数据库等服务的相关细节.
当我们的mysql,redis等容器化之后, 我们接下来就要思考关于数据库表初始化等数据问题了.
第一个问题: 数据库表初始化
使用volumes 来做数据库的初始化和持久化.
version: '3'
services:
...
mysql:
container_name: v-mysql-1
image: mysql/mysql-server:5.7
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # 初始化我们的数据库
- ~/mysql_datavolume:/var/lib/mysql # 持久化容器的数据到`~/mysql_datavolume`
environment:
MYSQL_DATABASE: sell
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
ports:
- "3306:3306"
restart: always
...
未完待续
老铁,手打不易, 来个star
激情激情~~~