Docker 利用 Compose 运行多个容器_数据库




简介



本文是《一文搞懂 AWS Docker 基础 下篇 实战》的申引,先介绍 Docker Compose 主要概念,然后测试 Compose 创建项目,运行多个容器。

我们将在 Win10 WSL2 + Docker Desktop 环境中,用 Compose 运行一个 WordPress 应用。

目录



- 环境(配置)

- Docker Compose 简介

  - Compose 特性

- 实战步骤

  1. 创建 docker-compose.yml 文件

  2. 创建 Compose 项目

     - Compose 常用命令

  3. 更新 Compose 项目

  4. 测试 volume

  5. 测试 Bind

- 总结

- 引申

- 后记

- 更正

(配置)



  • Win10 + terminal(WSL 2 Ubuntu20)
  • Docker desktop 3.3.3

Docker Compose 简介

Docker Compose(简称 Compose)是用来定义多个容器应用的工具,通过在 YAML 文件中配置应用的服务,镜像等信息来运行多个容器。

通过一条命令 docker-compose up 就可以同时启动或停止全部的容器(称为一个项目)。

当一个应用有多个容器需要协同运行相互通信时,我们可以把每个容器的端口暴露到本地,实现相互通信,也可以建一个单独的 docker 网络。

这时如果我们用 Compose 来运行这个应用,那么应用的多个容器自动运行在一个 docker 网络内部,端口可以互通,不需要把所有端口都暴露到本地。

我们还可以在 Compose 中控制容器的启动顺序,比如让数据库容器先于应用容器启动。

使用 Compose 时,主要需要以下几步


  1. 编写 Dockerfile 定义需要的容器(可选)
  2. 编写 docker-compose.yml 定义应用需要的服务,端口,volume 等信息
  3. 运行 Docker compose command 启动、停止应用

Compose 特性
在单独的主机上提供多个相互隔离的环境

Compose 用项目名称来隔离不同的环境,在没有设置项目名称的情况下,Compose 会用 docker-compose.yml 文件所在根目录名称做为项目名称。

每个项目有自己的 Docker network,不同项目的 Docker network 彼此不通。

在创建容器时,自动保存 volume 数据

Compose 在启动容器时,会自动保存 volume。当我们用 docker-compose down 删掉容器后,再用 docker-compose up 启动时,之前 volume 会自动挂载到新建的容器中。

只重建有改动的容器

当 docker-compose.yml 中的某个容器有改动时,用 Compose 重启项目,改动的容器会重新生成,没有改动的容器则保持不变。

可以使用变量

Compose 支持在 docker-compose.yml 中使用变量,可以通过设置变量来配合不同的使用环境。

实战步骤


1. 创建 docker-compose.yml 文件

我们可以用单独的 Dockerfile 配置每个镜像,也可以在 docker-compose.yml 中配置镜像。

下面这个 WordPress 的例子比较简单,可以直接在 docker-compose.yml 文件中配置镜像。

创建文件夹 docker-compose,进入新文件夹创建文件 docker-compose.yml 并添加以下内容

version: "3.9"

services:
  #1 容器名称
  db:
    image: mysql:5.7
    volumes:
      #2 把容器内/var/lib/mysql映射到db_data
      - db_data:/var/lib/mysql
    restart: always
    #3 容器内环境变量
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  #4 第二个容器名称
  wordpress:
    #5 依赖关系,要求在容器db启动后才启动本容器
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    #6 把容器wordpress内端口80映射到本地8000
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
#7 docker volumes
volumes:
  db_data: {}
  wordpress_data: {}

说明:


  • #1 数据库容器名称,一个 Compose 内的容器相互可以看到,可以直接用容器名称来访问彼此的端口
  • #2 这里除了可以把容器内文件夹映射到 volume,还可以映射(Bind)到本地文件夹
  • #3 这里通过环境变量指定 db 容器内 mysql 的 root 用户密码,数据库名称及普通用户和密码
  • #4 应用容器的名称
  • #5 通过依赖关系控制容器启动顺序,确保数据库容器先启动
  • #6 端口映射,没有经过映射的端口,不能在本地访问到,只能被这个项目中的容器访问到
  • #7 volumes 定义,这里定义了由项目自动创建的两个 docker volume,需要注意的是,当项目删除时,这两个 volume 会默认保留下来

2. 创建 Compose 项目

运行下列命令创建 Compose 项目(启动容器)

#后台运行
docker-compose up -d
#前台运行
docker-compose up

Docker 利用 Compose 运行多个容器_docker_02说明:

可以看到 docker 自动创建了 docker network 和两个 volume。

如果本地没有相关镜像,则先自动 pull 需要的镜像。另外这个命令是前台命令,不会自动退出,如需要后台运行要加 -d 参数。

使用-d 的后台命令创建 Compose 项目Docker 利用 Compose 运行多个容器_数据库_03

项目启动后(容器全部运行成功),在浏览器中输入“http://localhost:8000”,可以看到WordPress应用已经可以从本地的8000端口访问了Docker 利用 Compose 运行多个容器_docker_04

为了后面 volume 测试,我们简单设置一下这个应用,添加网站名称,用户信息,然后点击“Install WordPress”Docker 利用 Compose 运行多个容器_数据库_05

点击“Log in”Docker 利用 Compose 运行多个容器_数据库_06

然后我们点击“Go to 全是 AWS 干货”Docker 利用 Compose 运行多个容器_docker_07

这时进入主页面,可以看到标题已经改为“全是 AWS 干货”了Docker 利用 Compose 运行多个容器_数据库_08



~~休息一下~~


看完《三体》意犹未尽的时候,发现了还在论坛上连载的同人小说《三体X》,以云天明为主角,讲述了在他在三体世界的遭遇,作者宝树完美继承了大刘的世界观,并加以拓展。当时读了就觉得宝树以后一定会出自己的书,果然来了。


Compose 常用命令


在另一个终端窗口(如果使用前台命令),进入 docker-compose 文件夹后运行下列命令查看容器

docker-compose ps

Docker 利用 Compose 运行多个容器_docker_09说明:可以看到两个容器已经运行,并且通过 8000 端口把内部 80 端口映射到本地

注意:需要进入 docker-compose 文件夹再运行 docker-compose ps,否则会报如下错误Docker 利用 Compose 运行多个容器_mysql_10

我们也可以普通 docker 命令查看

docker ps

Docker 利用 Compose 运行多个容器_docker_11

查看 Compose 项目自动创建的 Volume

docker volume ls

Docker 利用 Compose 运行多个容器_mysql_12

查看 Compose 项目自动创建的 network

docker network ls

Docker 利用 Compose 运行多个容器_数据库_13

如果暂时不需要容器了,可以运行以下命令停止项目(停止容器,非删除)

docker-compose stop

Docker 利用 Compose 运行多个容器_数据库_14

启动项目

docker-compose start

Docker 利用 Compose 运行多个容器_数据库_15

重新启动项目

docker-compose restart

Docker 利用 Compose 运行多个容器_mysql_16

重新启动项目中的某个服务(容器)

docker-compose restart wordpress

Docker 利用 Compose 运行多个容器_docker_17说明:在通常情况下,我们可能只需要重启应用服务,而不需要重启数据库服务

3. 更新 Compose 项目

我们修改一下 docker-compose.yml 中的内容,把容器 wordpress 中环境变量 WORDPRESS_DB_HOST 的端口改为 3307

  wordpress:
...
    environment:
      WORDPRESS_DB_HOST: db:3307

然后运行 up 命令更新项目

docker-compose up -d

Docker 利用 Compose 运行多个容器_数据库_18说明:可以看到只有有变化的 wordpress 容器重建了,这里的变化也可以是镜像本身的内容。比如,镜像内复制了新的文件

4. 测试 volume

下面我们测试下用来做数据持久化的 volume(数据持久化是指容器删了,但数据还要保存)

运行以下命令停止并删除项目

docker-compose down

Docker 利用 Compose 运行多个容器_数据库_19说明:可以看到容器,Network 都被删除,但是没有删除 volume

我们现在重新创建项目

docker-compose up -d

Docker 利用 Compose 运行多个容器_docker_20说明:对比第一次的创建的图片,可以看到这次并没有创建 volume,而是使用了之前保留的 volume

我们删除浏览器的存缓,再打开http://localhost:8000,可以看到直接进入到了之前配置过的“全是AWS干货”的页面Docker 利用 Compose 运行多个容器_docker_21说明:图片说明我们上次保存下来的配置并没有丢失,即 volume 还在并且新的容器直接利用了之前保留的 volume

当我们需要彻底删除 docker-compose 应用和 volume 时,加--volumes 参数

docker-compose down --volumes

Docker 利用 Compose 运行多个容器_数据库_22

5. 测试绑定 Bind

对于数据持久化,除了用 volume 之外,我们还可以用 bind 把容器内的数据直接保存在本地文件夹中。

在 docker-compose 文件夹中,创建两个子文件夹 db_data 和 wordpress_data

mkdir db_data
mkdir wordpress_data

修改 docker-compose.yml 文件,删除最后的 Volume 部分,把两个容器的 volumes 改下如下的相对路径

services:
  #1 容器名称
  db:
...
    volumes:
      #2 把容器内/var/lib/mysql映射到db_data
      - ./db_data:/var/lib/mysql
...
  wordpress:
...
    image: wordpress:latest
    volumes:
      - ./wordpress_data:/var/www/html
...
#7 docker volumes
#volumes:
  #db_data: {}
  #wordpress_data: {}

然后运行创建项目命令

docker-compose up -d

Docker 利用 Compose 运行多个容器_docker_23

进入我们创建的 db_data 目录查看Docker 利用 Compose 运行多个容器_数据库_24说明:可以看到 mysql 数据库的文件都存在这个本地文件夹里了

同样的,在 wordpress_data 文件夹,我们也可以看到 php 相关文件Docker 利用 Compose 运行多个容器_docker_25

总结


使用 Compose,主要就是定义 docker-compose.yml 文件,可以在此文件中定义容器,网络,volume 等。

在 Compose 定义的 volume,默认在项目删除时保留,保存持久化数据。

用 Compose 可以隔离网络环境,适合多个环境共用主机的情况。

运行 docker-compose 命令时,需要在 docker-compose.yml 文件所在的文件夹中运行。

引申


  • 除了像上面那样直接在 yml 文件中定义容器,对于复杂的容器,我们可以在另外的文件夹中定义容器,然后在 docker-compose.yml 中用 build 指定路径即可。
version: "3.9"
services:
  webapp:
    build: ./dir


  • 在 Azure Container Instances 服务中,用的就是 Compose 来启动项目。
  • 在 AWS Elastic beantalk 中 multi-docker 环境中,虽然用的不是 Compose,但也是用类似的 JSON 文件来配置多个容器。

后记


通过三篇文章粗浅地讲了一下 Docker 基础和实际操作,用来自己玩玩或者做些简单的测试基本够用了。

Docker 命令,Dockerfile 及 docker-compose.yml 中还有很多有用的命令并没有讲到,有兴趣的朋友可以去 docker 官网查看。

更正


在文章《一文搞懂 AWS Docker 基础 下篇 实战》中,第二节“容器与本地文件交换”的第三部分“volume”中介绍的内容是“Bind”,并不是“volume”。

“volume”是 docker 自行管理的卷,而“Bind”是把本地文件夹映射到容器内部,两者是不同的。

Docker 利用 Compose 运行多个容器_mysql_26


喜欢请点赞,禁止转载,转发请标明出处

关注 B 站 UP 主“我是手拉面” 观看更多视频

微信公众号“全是 AWS 干货”