Docker Compose

大家好, 我叫石头~~~
今天我们来聊聊Dokcer, 准确来说是聊聊Docker Compose,没了解过docker compose的人可能会想, 我了解docker就够用了呀 ,干嘛要学这个, 老铁,你这就错了,不信你看看下图.

Docker Compose_第1张图片
服务器运行多个容器

这里我只画了几个容器,你可能还能弄清楚启动顺序,但是当我们的容器越来越多的时候,你能很从容的一个一个的有序的开启他们而不出错吗?就算你能很好的面对这样的问题,但是当其他的部门兄弟,比如,运维的兄弟,测试的兄弟想部署的只能干瞪眼了, 他们会要求你写一份详细的 脚本来帮助他们顺利部署或者搭建环境的, 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 Compose_第2张图片
docker容器文件系统

图片来源 --- docker镜像进阶, 有兴趣可以喵喵
我们要清除我们的docker镜像是在什么基础上面创建的,这样我们才能看懂接下来的一些命令参数,比如:

  • -v /root/tensorflow:/tmp
  • ~/mysql_datavolume:/var/lib/mysql
    记住一点,我们所有的image都是基于linux的文件系统之上的.

Docker Compose步骤

  1. 使用Dockerfile 编写我们的image
  2. 定义docker-compose.yml,让容器有序的组织起来
  3. 运行 docker-compose up命令, 让容器在你的编排下有序的运行

下面实现一个简单的例子: 来源于官网 --- Flask framework (Python中的框架).

第一步 准备必要的文件
  1. 创建一个composetest文件,之后我们就在这个目前工作了
$ mkdir composetest
$ cd composetest
  1. 官网例子是用的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)
  1. 再创建一个requirements.txt文件,内容如下
flask
redis

现在我们的目录结构是这样的


image.png

上面的都是我们的准备工作

第二步 创建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个服务webredis

  • web服务将使用当前路径下的Dockerfile文件构建的镜像.端口映射为5000:5000
  • redis服务将使用一个公共的redis:alpine镜像

现在我们的目录结构是这样的


Docker Compose_第3张图片
image.png
第四步 运行docker-compose

到了我们激动的时候了,现在让我们输入以下指令吧 -=- 不过记得要
安装docker-compose
docker-compose up

Docker Compose_第4张图片
输出信息

第一次构建需要拉去 image,所有打印信息比较多,只截取了最后的信息.

现在我们可以通过http://0.0.0.0:5000

Docker Compose_第5张图片
0.0.0.0:5000

刷新一下页面

Docker Compose_第6张图片
第二次打开

当我们想关闭我们的服务的时候直接执行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

Docker Compose_第7张图片
打印信息

第七步 更新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 Compose_第8张图片
修改本地app.py文件

到这里其实应该差不多结束了,但是我还是想要唠叨下关于在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激情激情~~~

你可能感兴趣的:(Docker Compose)