Docker 学习笔记 - Day3

Docker 学习笔记 - 第三天 - docker-compose

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 中,可以用 YAML 文件来配置程序的服务,然后使用简单的命令即可从配置中创建并启动所有服务。

一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose,不再需要使用 shell 脚本来启动容器。在配置文件中,所有的容器通过 services 来定义,然后使用 docker-compose 脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器。

安装 compose

Linux:

1
2
3
4
5
6
7
8
9
# 下载最新的 docker-compose 
sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

# 给予下载的 docker-compose 执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 测试是否可用
docker-compose --version
docker-compose version 1.15.0, build e12f3b9

其他操作系统可以 查看这里

配置 docker-compose.yml

整个配置文件应该包含 version 、services 、 networks 三大部分,其中最关键是 services 和 networks 两部分。

version

下表显示了 compose 文件版本支持特定的 docker 版本。

Compose file format Docker Engine release
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
1.0 1.9.1.+

services

在 services 标签下的标签是指该服务的名称,为用户自定义。

  1. image

    指定服务的镜像名称或者镜像ID ,若本地不存在,则 compose 将会尝试拉取该镜像。

    用法:

    1
    2
    3
    image: ubuntu
    image: nginx:1.13
    image: containerID
  2. build

    服务即可基于某个镜像 image ,亦可基于一个 Dockerfile 文件。在使用命令 docker-compose up 构建任务时,将会自动用 build 指向的 Dockerfile 路径构建镜像,并使用该镜像启动服务容器。

    如果同时指定了 image 和 build,那么 compose 会将 build 出来的镜像命名为 image。

    用法:

    1
    2
    3
    4
    5
    build: ./nginx
    # 设定上下文目录
    build:
    context: ./
    Dockerfile: nginx/Dockerfile
  3. args

    和 Dockerfile 中的 ARG 用法一样,在构建中指定环境变量,构建完成后取消。 args 中的变量可以为空值。

    注意:如需要在 yaml 中使用布尔值(true,false, yes,no等)必须要用引号括起来。

    用法:

    1
    2
    3
    4
    args:
    - version=1.0
    - boolean='true'
    - emptyvar
  4. command

    可以覆盖启动容器后默认执行的命令。

    用法:

    1
    2
    command: nginx
    command: [nginx, -g, deamon off]
  5. container_name

    设置容器的名称,默认为:

    用法:

    1
    container_name: lnmp_nginx
  6. depends_on

    设置依赖。有时候某个容器需要另外一个容器作为依赖,则该命令可以解决依赖前后问题。如启动 nginx 前要先启动 php-fpm,这时候只需要这么写:

    1
    2
    depends_on:
    - php-fpm
  7. entrypoint

    用法和 Dockerfile 中的ENTRYPOINT 一致,会覆盖 Dockerfile 中的 ENTRYPOINT。

  8. environment

    设置镜像中的环境变量,可以被保存在镜像当中,即每次启动容器,这些变量依旧存在容器当中。写法和 args 一致:

    1
    2
    environment:
    - MYSQL_ROOT_PASSWORD: 123456
  9. expose

    暴露容器中的端口,和 Dockerfile 中的EXPOSE 用法一致。

  10. links

    类似于 docker run 中的 —link 参数,用于连接容器。如 nginx 容器需要连接 php-fpm 的容器,只需要这么写:

    1
    2
    links:
    - php7-fpm:php

    其中,php 为 nginx 容器中连接 php 的别名,php7-fpm 为 php-fpm 服务的名字。

  11. ports

    用于映射端口,用法和 docker run 的参数 -p 一致:

    1
    2
    ports:
    - "8888:80"

    将容器的 80 端口映射到宿主机的 8888 端口中。

  12. volumes

    挂载一个目录或者一个数据卷容器到 container 中。数据卷的路径可以是绝对的,相对的。

    用法: [HOST:CONTAINER] or [HOST:CONTAINER:rw] rw的意思是,容器对该卷可读可写;ro为只读。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    volumes:
    # 只在容器中创建一个数据卷
    - /website/html
    # 绝对路径
    - /home/website:/website/html
    # 相对路径
    - ./data:/website/html
    # 已存在的数据卷容器,并设置权限为只读
    - data_container:/website/html:ro
  13. volumes_from

    从其他容器或者服务挂载数据卷,可选参数为 :ro 只读 或者 :rw 可读可写。默认为可读可写。

  14. networks

    指定容器加入的网络:

    1
    2
    3
    4
    services:
    nginx:
    networks:
    web_app

    web_app 为网络名称。

还有其他的配置项,具体的可以去 官网查看

编写一个多容器配置

先创建如下目录:

1
2
3
4
5
6
7
8
9
10
11
./
├── conf // 配置文件目录
│ ├── mysql
│ ├── nginx
│ └── php
├── data // mysql 数据目录
├── logs // 日志文件目录
│ ├── mysql
│ ├── nginx
│ └── php
└── www // 项目目录

新建一个 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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version: '2'
services:
nginx:
image: nginx:1.13
ports:
- "80:80"
volumes:
- ./www:/usr/share/nginx/html:rw
- ./logs/nginx/:/var/log/nginx:rw
- ./conf/nginx/conf.d:/etc/nginx/conf.d:ro
links:
- php:fpm
depends_on:
- php

php:
build: ./conf/php
ports:
- "9000:9000"
volumes:
- ./www:/usr/share/nginx/html:rw
- ./logs/php/:/var/log/php:rw
links:
- mysql:mysql
depends_on:
- mysql
mysql:
image: mysql:5
ports:
- "3306:3306"
volumes:
- ./mysql:/var/lib/mysql:rw
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_USER: "test"
MYSQL_PASSWORD: "testpass"

version 为2 可以兼容旧版本的docker。

services 这里一共启动了3个服务:

  • nginx。监听 80 端口,挂载了 www 目录为工作目录,挂载 logs/nginx 为日志目录,挂载 conf/nginx/conf.d 至容器的 nginx 的配置文件夹。连接 php 容器,表示为 fpm。依赖于 php 容器。
  • php。 监听 9000 端口,挂载 www 目录为工作目录,挂载 logs/php 为日志目录,依赖于 mysql 容器并连接 mysql 容器。
  • mysql。监听 3306 端口,挂载 mysql 目录为 mysql 数据存储目录,并设置了3个环境变量,分别为 root密码,mysql 用户 test 并设置 test 的密码为 testpass。

配置文件自行添加,最终的目录结构为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.
├── conf
│ ├── mysql
│ ├── nginx
│ │ └── conf.d
│ │ ├── default.conf
│ │ └── home.conf
│ └── php
│ ├── Dockerfile
│ └── php.ini
├── docker-compose.yml
├── logs
│ ├── mysql
│ ├── nginx
│ └── php
├── mysql
└── www
├── home
│ └── index.html
├── index.html
├── index.php
└── i.php

因为 php-fpm 我们需要做额外的事情,所以使用 Dockerfile 来构建镜像。php 的 Dockerfile 的内容配置和之前的 Dockerfile 一致:

1
2
3
4
5
6
7
8
9
10
11
FROM php:7.1-fpm

MAINTAINER LeungJZ

COPY php.ini /usr/local/etc/php/conf.d/php.ini

RUN docker-php-ext-install pdo_mysql

EXPOSE 9000

CMD ["php-fpm"]

可以在 RUN 命令中,安装需要的 php 拓展。

在项目根目录中运行命令 docker-compose up 开始构建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
leung@ubuntu:~/compose$ docker-compose up
Pulling mysql (mysql:5)...
5: Pulling from library/mysql
aa18ad1a0d33: Already exists
fdb8d83dece3: Pull complete
75b6ce7b50d3: Pull complete
ed1d0a3a64e4: Pull complete
8eb36a82c85b: Pull complete
41be6f1a1c40: Pull complete
0e1b414eac71: Pull complete
914c28654a91: Pull complete
587693eb988c: Pull complete
b183c3585729: Pull complete
315e21657aa4: Pull complete
Digest: sha256:0dc3dacb751ef46a6647234abdec2d47400f0dfbe77ab490b02bffdae57846ed
Status: Downloaded newer image for mysql:5
Building php
Step 1/6 : FROM php:7.1-fpm
---> 9b44e8b4c8b6
Step 2/6 : MAINTAINER LeungJZ
---> Running in e5c103cc2d37
---> c396815cf8b6
Removing intermediate container e5c103cc2d37
Step 3/6 : COPY php.ini /usr/local/etc/php/conf.d/php.ini
---> bc4a19e69f93
Removing intermediate container 566b27944ffb
Step 4/6 : RUN /usr/local/bin/docker-php-ext-install pdo_mysql
---> Running in 8ebd9dadf506
---> a3483051c1bb
Removing intermediate container 8ebd9dadf506
Step 5/6 : EXPOSE 9000
---> Running in 9a4f81103c0c
---> d0376a2a8bfe
Removing intermediate container 9a4f81103c0c
Step 6/6 : CMD php-fpm
---> Running in 8d7f61c657f9
---> 77072c6b2561
Removing intermediate container 8d7f61c657f9
Successfully built 77072c6b2561
Successfully tagged compose_php:latest
WARNING: Image for service php was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating compose_mysql_1 ...
Creating compose_mysql_1 ... done
Creating compose_php_1 ...
Creating compose_php_1 ... done
Creating compose_nginx_1 ...
Creating compose_nginx_1 ... done
Attaching to compose_mysql_1, compose_php_1, compose_nginx_1

不出1分钟,整个项目环境就已经搭建好了。根据提醒, php 服务已经被构建出来了,因为它一开始并不存在。如果想要重新构建整个服务,需要运行 docker-compose build or docker-compose up --build

这时 docker ps 查看:

1
2
3
4
5
leung@ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
18bc61bd12b1 nginx:1.13 "nginx -g 'daemon ..." About a minute ago Up About a minute 0.0.0.0:80->80/tcp compose_nginx_1
38ccb807e09b compose_php "docker-php-entryp..." About a minute ago Up About a minute 0.0.0.0:9000->9000/tcp compose_php_1
67188d651b80 mysql:5 "docker-entrypoint..." About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp compose_mysql_1

可以看到已经成功启动了三个容器。

通过浏览器访问:

docker-compose-success

可以发现已经运行成功,而且 php 文件也能正常执行。

该项目地址: 传送门

docker-compose 命令

docker 差不多,也有 start , stop, build , logs , rm 等常用命令,其作用也是类似的。

总结

docker 真是一个神器!!!

这只是一个简单的入门,希望大家能继续挖掘 docker 更强大的功能。

# docker, php

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×