Docker Compose入门到开发环境
Docker Compose定义服务之间的关系,很方便地管理多个容器的生命周期。你可以使用 docker-compose.yml 配置文件定义服务之间的关系,然后通过命令行来管理配置文件中定义的服务的生命周期,一般用在开发、测试环境。
docker-compose.yml
docker-compose.yml描述容器的运行状态,包含了运行服务的容器的配置信息,容器之间的网络交互,挂载文件夹等。 使用yaml格式,具体的语法可以查看wiki上的介绍。
下面是一个docker-compose.yml文件的示例:
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
第一行一般标识这个配置文件的语法是哪个版本的,不同的版本对应的支持不同的Docker Engine版本,现在最新版本是3.x。 1.x版本中,每个顶级节点为服务名称,次级节点则为服务容器的配置信息。在2.x之后所有的服务都必须定义在 services 节点下面,2.x支持Compose 1.6.0以上的版本,并且Docker Engine需要1.10.0以上的版本。3.x主要是与Docker Engine的swarm模式兼容。不同版本之间的区别、升级指南可以在官方文档中查看。
服务的配置项里主要有:build、environment、image、networks、ports、volumes等,想了解更多可查看官方文档。
docker compose 相关命令
通过docker-compose命令行能方便地构建服务、管理服务的生命周期、查看日志等操作。
docker-compose build // 构建服务镜像
如果服务的Dockerfile有更改或者build目录里有文件修改,那么会重新构建服务镜像。
下面来做个简单的示例:通过docker-compose管理一个php cli server。项目的根目录是phpcli:
phpcli/
├── docker-compose.yml
└── web
├── Dockerfile
└── src
└── index.php
web目录里有个Dockerfile描述如何构建这个服务,web服务的代码都放在web/src目录下。
<?php
echo 'hello world';
index.php里面的文件内容。
docker-compose.yml文件里面指定使用配置版本是 3 ,services 里定义了一个php-cli-server服务,build 项包含了构建容器时的配置信息, 这里./web
是构建容器的上下文,volumes 指定挂载的目录, ports 指定服务暴露的端口。
version: '3'
services:
php-cli-server:
build: ./web
volumes:
- ./web/src:/var/www/social
ports:
- 8080:8000
当我们运行完docker-compose build
命令完之后再运行docker images
会发现生成了一个新的镜像phpcli_php-cli-server。 镜像的命名规则为project_service,project默认是目录名,你也可以通过-p
或--project-name
选项指定项目名。你也可以使用 image 来指定要构建的服务容器名。
现在我们可以通过下面的命令启动服务
docker-compose up // 创建并启动容器
控制台输出:
Creating network "phpcli_default" with the default driver
Creating phpcli_php-cli-server_1 ...
Creating phpcli_php-cli-server_1 ... done
Attaching to phpcli_php-cli-server_1
php-cli-server_1 | PHP 7.1.8 Development Server started at Fri Aug 18 06:12:05 2017
从上面我们可以看到,docker compse会先创建一个默认的网络 phpcli_default , 可以通过docker network ls
看到这个新创建的网络。
NETWORK ID NAME DRIVER SCOPE
52b806c648eb phpcli_default bridge local
接着会创建并启动一个以phpcli_php-cli-server为镜像的容器,并加入到上面创建的网络中,最后attach到容器的控制台,所有容器中的输出会打印在控制台上。现在你可以通过浏览器访问这个web server了。一般你可以使用-d
选项让docker compose以后台服务的方式运行项目。
docker-compose logs
Attaching to phpcli_php-cli-server_1
php-cli-server_1 | PHP 7.1.8 Development Server started at Fri Aug 18 06:30:28 2017
php-cli-server_1 | [Fri Aug 18 06:30:40 2017] 192.168.10.1:57739 [200]: /
php-cli-server_1 | PHP 7.1.8 Development Server started at Fri Aug 18 06:31:35 2017
php-cli-server_1 | [Fri Aug 18 06:33:36 2017] 192.168.10.1:57754 [200]: /
可以查看所有容器中产生的日志,每条日志前面会有日志产生的容器的名称。-f
跟linux tail命令的-f
选项相似,可以持续的输出最新的日志。--tail
可以指定输出最近的日志条数,默认为 all ,例如--tail=10
会打印出所有容器中最近的10条日志。
docker-compose stop
停止正在运行的容器,但不会删除容器。可以通过docker compose start
再次启动服务。
docker-compose start
启动已经存在的服务容器
docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------
phpcli_php-cli-server_1 docker-php-entrypoint php ... Up 0.0.0.0:8080->8000/tcp
列出所有容器的状态,正在运行的命令,端口映射信息。
docker-compose rm
删除已停止的服务容器。
docker-compose port [options] SERVICE PRIVATE_PORT
打印某个服务容器中的端口对外映射的端口号。例如:docker-compose port php-cli-server 8000
会打印出0.0.0.0:8080
。
docker-compose pause
暂停某个服务的正在运行的容器,你可以在之后使用docker-compose unpause
命令恢复暂停的服务。
docker-compose exec [options] SERVICE COMMAND [ARGS...]
在某个服务容器中运行命令,与docker exec -it
相似,默认情况下会自动分配一个TTY终端。
docker-compose down
停止所有的容器并删除网络、挂载点、构建时生成的镜像。--rmi local
也会删除项目中定义的服务镜像,-v
删除所有命名的、匿名的挂载点。
下面介绍如何cli server如何从mysql数据库中读取数据:首先在services节点下定义一个db服务,db使用mysql镜像,并且设置了环境变量MYSQL_ALLOW_EMPTY_PASSWORD,允许用空密码登录,在开发环境中简单方便:
db:
image: mysql:5.7
ports:
- 3306:3306
volumes:
- ./db/data:/var/lib/mysql
- ./db/sql:/data/sql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
并对原先的php-cli-server服务进行了修改:
php-cli-server:
build: ./web
image: "cli-server"
volumes:
- ./web/src:/var/www/social
ports:
- 8080:8000
depends_on:
- db
depends_on 会在docker-compose up
的时候会按依赖次序来启动服务,db服务会在php-cli-server服务之前启动,而且在docker-compose up php-cli-server
也会创建(如果容器不存在)并启动db服务。
由于php:7.1-alpine镜像中默认没有安装mysql扩展,所以需要在web/Dockerfile中增加RUN docker-php-ext-install pdo_mysql
。
导入数据库:首先执行docker-compose exec db /bin/bash
,进入mysql服务容器终端,然后执行mysql -u root -p < /data/sql/social.sql
导入数据(root用户密码为空)。
修改web/src/index.php文件:
$db = new PDO('mysql:host=db;dbname=social;charset=utf8mb4', 'root', '', [
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $db->query("SELECT * FROM posts");
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $post) {
var_dump($post);
}
现在我们可以打开浏览器查看数据库里面的数据了。
到现在为止我们完成了php与mysql的交互,一般情况下我们都会使用nginx,那如何让php与nginx交互呢?我们先通过docker-compose down --rmi local -v
停止并删除项目中的服务,并移除构建的本地镜像,删除挂载数据信息。
首先得添加nginx服务:
nginx:
image: nginx:latest
ports:
- 8080:80
volumes:
- ./web/src:/var/www/social
- ./nginx/conf/social.conf:/etc/nginx/conf.d/social.conf
depends_on:
- web
删除前面的php-cli-server服务的定义,这次使用php-fpm来做web服务,把web目录下Dockerfile中的基础镜像改成php:fpm,在docker-compose.yml中添加下面的web服务。
web:
build: ./web
volumes:
- ./web/src:/var/www/social
ports:
- 9000
depends_on:
- db
下面是social.conf文件里的配置信息,其中fastcgi_pass web:9000;
中的web是docker-compose.yml中定义的web服务的容器地址。
server {
index index.php index.html;
server_name social.local;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/social;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass web:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
然后根据上面的命令,数据库中重新导入数据,然后在宿主机的hosts中加入127.0.1.1 social.local
。通过浏览器访问http://social.local:8080就可以查看数据了。
我们了解了Docker compose的基本用法,也实现了如何搭建一个lnmp的docker开发环境。