简介
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
说白了,我们可以把容器的启动参数放到yml文件里面,然后可以通过一个命令直接启动,如果一个项目里面需要用到多个容器,那么就可以通过yml文件一个命令启动整个项目,不用一个个容器慢慢启动慢慢添加参数。
接下来我将用docker来搭建一个完整的php环境并运行一个php项目
创建项目文件夹
首先,找一个自己喜欢的位置创建一个自己喜欢的文件夹,用于存放等下docker映射出来的文件以及php文件和compose文件,这个文件夹就是这个项目文件夹
我在更目录下面创建了一个docker,在docker里面又创建了typecho这个文件夹,因为等下打算使用typecho来做演示
mkdir -p /docker/typecho
创建compose配置文件
进入项目文件夹,创建compose配置文件,文件名为docker-compose.yml
vi docker-compose.yml
编写compose配置文件
compose配置文件官方文档地址(英文):https://docs.docker.com/reference/compose-file/
非官方文档地址(中文):https://www.runoob.com/docker/docker-compose.html
我们这个项目要用到的容器又nginx,php,和数据库,我们创建了compose文件,就在这个文件里面把这三个容器的配置写进去即可
配置文件样板
version: '3.8'
services:
nginx:
image: nginx:1.29.0
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/var/www/html
- ./nginx.conf:/etc/nginx/nginx.conf
- ./conf.d:/etc/nginx/conf.d
depends_on:
- php
php:
build: .
restart: always
volumes:
- ./html:/var/www/html
- ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: typecho
MYSQL_USER: xxhh
MYSQL_PASSWORD: xxoo123...
ports:
- "3306:3306"
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
配置文件解释
version: '3.8'
version: '3.8'是指定配置文件的版本,Docker Compose 在不同版本中,新增/废弃了一些配置项,不同版本支持的功能也略有不同,所以才需要写 version,让 docker-compose 知道用哪个语法规则来解析文件。
怎么知道应该选那个版本呢,可以参考下面,但是其实最常用的就是3或者3.8
version | 用途 / 特点 |
---|---|
'2' / '2.4' | 适合单机开发,也支持 restart_policy、depends_on 等 |
'3' / '3.8' | 为了支持 swarm mode(分布式部署),仍可在单机用 |
'3.8' | 目前 docker-compose CLI 最常用,也比较新 |
'3.9'(不太常用) | 和 3.8 很像,变化小 |
场景 | 推荐 version |
---|---|
本地开发 / 小项目,只用 docker-compose up | 2.4 (够用) |
想兼容 swarm(docker stack deploy) | 3.8 (更好) |
学教程 / 网上大部分示例 | 大多用 3.8 |
当然,也可以不用写version: '3.8'来指定配置文件版本,默认会使用最新的版本
services:
services:下面就是容器的设置了,一个services:里面可以写多个容器设置,例如这个配置文件就写了nginx,php,mysql的
注意的是yml文件对格式要求很严格,可以看到services:是顶头写的,但是services:里面的内容就要比services:缩进两个空格
第一部分:nginx
nginx: # 服务名称(service name),内部网络互联也用这个名字
image: nginx:1.29.0 # 使用官方 nginx 镜像,并固定版本为 1.29.0;不固定可能导致后续镜像更新时不兼容
restart: always # 重启策略:无论退出状态如何都自动重启;常用保证服务高可用
ports: # 端口映射(宿主机:容器)
- "80:80" # 将宿主机的 80 端口映射到容器的 80 端口(http)
- "443:443" # 将宿主机的 443 端口映射到容器的 443 端口(https)
volumes: # 挂载本地文件或目录到容器内部,实现数据/配置持久化
- ./html:/var/www/html # 将当前目录下的 html 文件夹映射到容器的 /var/www/html(网站根目录)
- ./nginx.conf:/etc/nginx/nginx.conf # 映射 nginx 主配置文件
- ./conf.d:/etc/nginx/conf.d # 映射虚拟主机配置文件夹(推荐使用)
depends_on: # 定义启动顺序:启动 nginx 前先启动 php
- php
第二部分:php
php: #服务名称,和上面一样
build: . #表示使用当前目录下的Dockerfile构建一个镜像,而不是直接用Docker仓库里面现有的镜像
restart: always #重启策略,总是重启
volumes: #挂在文件
- ./html:/var/www/html #把宿主机的当前目录下的html目录挂载到容器的/var/www/html
- ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini #把宿主机的当前目录下的php目录下的php.ini这个文件挂载到/usr/local/etc/php/conf.d/custom.ini
为什么php要用build: .来构建镜像而不是直接使用仓库里面的呢?
官方镜像可能不能满足你的需求,比如:
需要安装额外的 PHP 扩展(pdo_mysql、gd 等)
需要复制代码、配置文件到镜像里
需要装 composer 或其他工具
你可以写 Dockerfile 完全自定义镜像内容
第三部分:db
其实和上面差不多
db: #服务名称
image: mysql:8.0 #使用的镜像以及版本
restart: always #重启策略
environment:
MYSQL_ROOT_PASSWORD: root #初始root密码
MYSQL_DATABASE: typecho #创建一个名字为typecho的数据库
MYSQL_USER: xxhh #创建一个名称为xxhh的用户
MYSQL_PASSWORD: xxoo123... #xxhh用户的密码
ports: #端口映射
- "3306:3306" #把宿主机3306端口映射到容器3306端口
volumes: #挂载文件
- dbdata:/var/lib/mysql #把当前目录下的dbdata目录挂载到容器的 /var/lib/mysql目录
volumes:
配置文件的最后有
volumes:
dbdata:
这个是用来申明创建dbdata这个卷,和上面的
volumes:
- dbdata:/var/lib/mysql
这个不一样的,db这个服务里面是把dbdata这个卷挂载到容器里面,最下面的这个volumes:是用来声明我们有这个卷,如果没有申明的话Docker Compose 会自动创建匿名卷,名字随机,这不方便管理
创建Dockerfile文件
为什么要创建这个文件呢
有没有记得我们在docker-compose.yml这个文件中配置PHP容器的时候,镜像是使用 build: .
构建的,使用build: .
构建的就依赖Dockerfile文件
在docker-compose.yml文件同个目录下创建一个名字为Dockerfile的文件,注意大小写
vi Dockerfile
然后开始写配置
FROM php:8.0-fpm
RUN apt-get update && apt-get install -y \
libonig-dev \
libcurl4-openssl-dev \
libzip-dev \
libxml2-dev \
gcc \
make \
autoconf \
libc-dev \
pkg-config \
&& docker-php-ext-install pdo pdo_mysql mysqli curl mbstring \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
文件内容解释
FROM php:8.0-fpm
基于官方 PHP 8.0 的 FPM 镜像
apt-get update
更新 Debian 包索引,保证后续安装的软件包信息是最新的
apt-get install -y \ <一大堆包>
安装构建 PHP 扩展所需的依赖包,具体说明:
libonig-dev:mbstring 扩展依赖的正则表达式库(Oniguruma)
libcurl4-openssl-dev:curl 扩展依赖的 libcurl 开发库
libzip-dev:zip 文件操作库(有时 PHP 的 zip 扩展会用到)
libxml2-dev:XML 解析相关库,很多 PHP 扩展会用到
gcc, make, autoconf, libc-dev, pkg-config:C语言编译环境及辅助工具,必须安装才能编译 PHP 扩展
docker-php-ext-install pdo pdo_mysql mysqli curl mbstring
这是 PHP 官方提供的脚本,用来编译安装 PHP 扩展
安装的扩展:
pdo:PHP 数据对象接口,抽象数据库访问层
pdo_mysql:PDO 对 MySQL 的驱动支持
mysqli:MySQL 的增强接口
curl:支持 URL 请求的扩展
mbstring:多字节字符串处理扩展,处理中文等多字节编码必备
apt-get clean && rm -rf /var/lib/apt/lists/*
清理缓存,减小镜像体积
apt-get clean 删除下载的软件包缓存
删除包索引文件目录,释放空间
启动项目
Dockerfile和docker-compose.yml文件编写完成后就可以启动项目了,项目启动后,没有创建的映射文件夹会自己创建
在docker-compose.yml文件所在目录里面使用下面命令启动,然后等待启动完成
docker compose up --build -d
使用docker ps看看是不是三个容器都启动了,如果是的话就证明没问题了
部署网站
现在项目环境是启动了,但是我们的网站还是空的,没有任何php文件
我们把网站文件上传到docker-compose.yml所在目录下的html目录里面
然后配置网站的nginx的conf文件,返回上一级目录,进入conf.d目录
cd ../conf.d
然后创建一个配置文件,名称为xxx.conf
vi typecho.conf
然后把nginx配置文件写好即可,nginx配置文件我这里就不作演示了,但是最重要的是网站的配置文件里面必须又要下面
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
这个是用来调用php容器的,还有注意的是配置文件里面的文件路径之类的,一定要和容器里面的文件所在的路径一致