在第二篇文章中,我们学会了使用 dockerfile 构建 docker 镜像,看起来已经能够满足我们的日常需求了。无论需要什么环境,在 dockerfile 里逐步构建,然后 build、run,就 ok 了,也满足了我们docker 隔离性、快速部署的要求,那为什么还会有这一节?
来看一个网站开发最常见的场景:我们要有数据库,网站应用,nginx,互相配合才是完整的环境。是的,我们完全可以以 ubuntu 为基础镜像,把这些一股脑全装进去,然后运行。但是这样有很多缺点,比如我们每次都要重新装 mysql 而不是直接利用 mysql 官方的基础镜像,升级维护不方便;如果我们的应用要扩展也很难,因为每个应用都连接的自己内部的数据库,无法共享数据;事实上,这种方式是典型的虚拟机的使用方式,不是 docker 的正确打开方式。
docker 是轻量化的应用程序,docker 官方推荐每个 docker 容器中只运行一个进程(下篇文章你将明白这是为什么),那么就是说,我们需要分别为我们的应用、数据库、nginx 创建单独的 docker 容器,然后分别启动它。想象一下,构建好 docker 之后,每次启动我们的网站,都要至少 docker run 三次,是不是很繁琐?而且此时这几个 docker 是分散独立的,很不方便管理。既然这几个 docker 都是为了同一个网站服务,是不是应该把它们放到一起?这就引出了 docker-compose 项目。
docker-compose是 docker 官方的开源项目,使用 python 编写,实现上调用了 Docker 服务的 API 进行容器管理。其官方定义为为 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)),其实就是上面所讲的功能。
一:安装
默认情况下,windows 和 mac 下的 docker 已经自带了 docker-compose 工具,可以使用 `docker-compose -v` 命令查看。

对于 linux 系统,需要自己手动安装,可以直接下载二进制文件安装,参考官方文档,更酷的是,可以直接使用 pip 安装,甚至可以使用 docker-compose 容器(比较复杂,不推荐~)。
二:简介
类似 docker 的Dockerfile文件,docker-compose使用 YAML 文件对容器进行管理。
对于 docker-compose 有两个基本的概念:
再简单说下 YAML 文件格式。
1.大小写敏感,缩进表示表示层级关系
2.缩进空格数不重要,相同层级左侧对齐即可。(不允许使用 tab 缩进!)
3.由冒号分隔的键值对表示对象;一组连词线开头的行,构成一个数组;字符串默认不使用引号
这些基本够我们使用了,详细的格式说明可参考这篇YAML 语言教程-阮一峰。
三:使用
接下来我们使用 docker-compose 构建一个php 网站项目,并逐步讲解其使用。

2. 在项目文件夹下创建 docker-compose.yml文件。

3. 先在 docker-compose.yml 文件里添加如下代码,构建我们的 php 应用。
version: '2'
services:
# our web application
app:
build:
context: ./
dockerfile: app.dockerfile
volumes:
- ./:/var/www
working_dir: /var/www
environment:
- DB_HOST=database
- REDIS_HOST=redis下面解释下我们的代码。
这是 app.dockerfile 文件的内容,之前都讲过,不再细说。
FROM php:7.1.22-fpm
# 安装必要的 php 依赖包
RUN apt-get update \
&& apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev \
&& apt-get clean
# 安装 php 扩展
RUN docker-php-ext-install pdo pdo_mysql mcrypt zip gd4. 创建一个 composer 服务以安装 composer 依赖,docker-compose.yml 文件添加以下内容
# install dependencies
composer:
image: prooph/composer:7.1
volumes:
- ./:/var/www
working_dir: /var/www
command: install注意这里同样将当前文件夹挂载到了容器中,因此对文件所做的更改都直接作用于本地文件,而我们的 app 容器也挂载了当前文件夹,这里安装的包文件都能生效。
5. 创建一个 nginx 服务,docker-compose.yml 文件添加以下内容
# web server
nginx:
build:
context: ./
dockerfile: nginx.dockerfile
volumes:
- ./public:/var/www/public
ports:
- 80:80nginx.dockerfile 文件内容,为了添加默认配置文件
FROM nginx:1.10
ADD vhost.conf /etc/nginx/conf.d/default.confvhost.conf 文件,nginx 配置文件
server {
listen 80;
server_name www.larabbs.test
index index.php index.html;
root /var/www/public;
error_log /var/log/nginx/error.log notice;
access_log /var/log/nginx/access.log main;
location / {
try_files $uri /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}6. 创建数据库服务,docker-compose.yml 文件添加以下内容
# mysql database
database:
image: mysql:5.7
environment:
- "MYSQL_ROOT_PASSWORD=root"
- "MYSQL_DATABASE=larabbs"
- "MYSQL_USER=homestead"
- "MYSQL_PASSWORD=secret"
# redis database
redis:
image: redis:5到目前为止配置文件已经写完了,完整的文件可以在我的 github 看到。
7. 启动项目
docker-compose 最常用的命令就是 docker-compose up 了,该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。
因此,在项目文件夹下执行此命令。注意要在项目文件夹下,否则 docker-compose 找不到 docker-compose.yml 文件,也不知道你是如何配置的。
时间可能较长,请耐心等待。如果遇到网络故障,可以重试。
简单介绍下输出:

可以看到 此时app 服务已启动,等待连接。

redis 服务已启动。

database 服务已启动,在3306端口等待连接。

composer 服务准备开始安装依赖。

composer 服务完成任务退出。
当然顺序可能不同,但正常情况下nginx、mysql、redis、app 服务都已经启动,运行正常。
另外,你可以给命令加上-d 参数,以忽略输出,当然第一次运行还是仔细观察输出为好,将来使用时可以这么做。
8. 项目使用
首先执行下 docker ps,可以看到目前有4个容器,容器名都加上了项目前缀。

此时你可以使用 docker exec 命令进入相应容器执行初始化操作,因为 docker-compose 本身也是调用的 docker api,但是既然使用了 docker-compose 来管理项目,我们必然有更方便的方式。
执行 docker-compose ps,可以至查看当前项目的容器状态。

可以看到,四个服务正在运行,而 composer 服务已经执行完任务退出。
如果要容器执行命令,直接 docker-compose exec service_name command 更方便。
比如,进入我们的 nginx 容器,nginx 即是 YAML 文件里定义的服务名。

接下来,我们进行网站的初始化工作。即生成秘钥、初始化数据库等。
app 也是 YAML 文件里定义的服务名。

一切都顺利进行。
对了,因为上面提到 sudo-su的原因,你必须使用域名访问网站,在 host 文件添加 larabbs.test到127.0.0.1的映射即可。
然后,你应该就可以正常访问 http://larabbs.test 网站了。
8. 容器的停止
直接 control-c 或者 docker-compose stop 即可。
注意下次docker-compose up 默认仍会继续使用之前的容器和数据。
必要时你可以添加--build 参数重新构建镜像,或者--force-recreate参数重新创建容器。
更多资料:docker 三剑客-compose
闲言
这个系列写了三篇了,算是把 docker 的基本使用介绍完了,更准确的说,应该是把我会用的介绍完了。因为本身是开发工程师,更着重于日常开发过程中使用,经验不多,对于运维视角的 docker不甚了解,而 docker 更大的意义应该是在运维层,所以有介绍的不合适甚至错误的地方,欢迎指出,或者分享你对 docker 的理解与使用。
另外,接下来会介绍 docker 与虚拟机的区别,docker 的原理等,写起来会比较难,但我会尽快完成。相信看了之后,会对 docker 的实质有更深的理解,就算是吹牛逼也会更有自信,欢迎关注~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3129690/ ,如需转载,请注明出处,否则将追究法律责任。