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的使用

  1. 在当前目录下创建compose1文件夹

  2. 进入compose1, 创建app.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from flask import Flask
    from redis import Redis

    app = Flask(__name__)
    # redisdemo 是 compose 中创建的主机名,由 docker-compose.yml 中指定
    # compose 会给每个容器提供 DNS 服务保证容器间互相访问
    redis = Redis(host='redisdemo', port=6379)

    @app.route('/')
    def index():
    count = redis.incr('hits')
    return 'views {}'.format(count)

    if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)
  3. 进入compose1, 创建Dockerfile

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    FROM 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"]
  4. 进入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"
  5. 启动项目,打开终端

    1
    docker-compose up
  6. 打开浏览器输入: localhost:9000/. 不断刷新浏览器你会发现redis记录了该页面访问的次数变化。

  7. 输入docker-compose down关闭应用

实例操作2: 使用共享券

在开发过程中,如果每次修改app.py文件都要重新build再启动容器会比较繁琐
我们可以用共享券的方式来直接修改程序文件,这样可以大大提高开发效率.
上面的实例操作一,每次修改compose1文件夹下的文件都需要输入docker-compose up --build重启启动应用。现在使用了共享券(volumes),容器中/code下的文件都来自宿主机的当前目录。
.

  1. 进入目录compose1, 修改docker-compose.yml文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 修改pyweb容器的配置
    pyweb:
    build: .
    ports:
    - "9000:5000"
    depends_on:
    - redisdemo
    volumes:
    - .:/code
  2. 进入目录compose1, 修改Dockerfile文件

    1
    2
    3
    # 删除 COPY 命令
    - COPY app.py /code/app.py

  3. 打开终端, 启动项目

  4. 打开浏览器输入: localhost:9000/. 不断刷新浏览器你会发现redis记录了该页面访问的次数变化。这时候修改app.py不需要重新启动容器

  5. 输入docker-compose down关闭应用

实例操作3: 在服务器中使用docker-compose启动项目

  1. 进入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'
  2. 进入compose1文件夹,创建run.sh文件.
    1
    2
    3
    cd <server path>
    sudo docker-compose down
    sudo docker-compose up -d
  3. 在本地执行sh upload-and-run.sh
  4. 打开浏览器输入: <server ip>:9000,就可以访问了。
  5. 注意事项:
  • 可能服务器docker服务会关闭,在服务器输入systemctl start docker重启docker。
  • 服务器防火墙原因,只放开了80,443端口
文章作者: woyao
文章链接: https://chenwoyao.github.io/2021/04/19/docker系列/docker教程系列四/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 woyao的博客