使用 docker-compose 编排的一套 lnmp 环境,并补充了 nginx / php / mysql / redis 的配置文件,补充了 php 的常用扩展。给到了 fpm / swoole 的部署、运行示例。可以方便大家快速搭建开发、生产环境、学习 docker 技能(涉及了镜像打包、Entrypoint、yml 高大上的写法 extends & 引用)。
github 完整示例:docker-lnmp
docker-lnmp
.env
CONTAINER_NAME_NGINX=nginx
CONTAINER_NAME_PHP_FPM=php-fpm
CONTAINER_NAME_SWOOLE=swoole
CONTAINER_NAME_REDIS=redis
CONTAINER_NAME_MYSQL=mysql
CONTAINER_NAME_NODE=node
common-services.yml
# 抽出来的php类容器的配置模板 只用来被 extends 载入 不会创建额外容器
# 这里用的是我自己打包的一个镜像,官方的好多扩展没开启 这里我开启了
services:
php-tpl:
restart: always
stdin_open: true
tty: true
# image: php:8.2-fpm
image: sqrtcat/php-swoole:0.0.2
# platform: linux/amd64
# platform: linux/x86_64
# build: #自定义镜像构建
# context: ./php
# dockerfile: Dockerfile
ports:
- :9000 # php-fpm 的默认端口 配置在 /usr/local/etc/php-fpm.d/zz-docker.conf 中
volumes:
- /etc/localtime:/etc/localtime:ro # 修正时间 centos
- /etc/timezone:/etc/timezone:ro # 修正时区 centos
- ./php/conf/php.ini:/usr/local/etc/php/php.ini # php.ini
- ./php/conf/conf.d/docker-php-z-exts.ini:/usr/local/etc/php/conf.d/docker-php-z-exts.ini # 额外加载的扩展
- ./php/conf/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf # php-fpm 进程池的相关配置
docker-compose.yml
version: '3'
# x- 前缀声明为引用 &foo
# 可以在别处取值填充 *foo
x-common-config: &common_config
restart: always
stdin_open: true
tty: true
services:
nginx:
<<: *common_config
container_name: ${CONTAINER_NAME_NGINX} # .env 环境变量
# image: nginx:latest # 直接使用原镜像 或 build 定制镜像
build: # 如果之前没有生产镜像,可以直接用这个
context: ./nginx
dockerfile: Dockerfile
ports:
- 8050:80 # 端口 / 域名映射多站点 自行选择
- 8051:81
- 8052:82
volumes:
- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf # 主配置
- ./nginx/conf/proxy.conf:/etc/nginx/proxy.conf # 代理配置
- ./nginx/conf/fastcgi.conf:/etc/nginx/fastcgi.conf # fastcgi配置
- ./nginx/conf/fastcgi_params:/etc/nginx/fastcgi_params # fastcgi配置
- ./nginx/conf/pathinfo.conf:/etc/nginx/pathinfo.conf # pathinfo配置
- ./nginx/conf/enable-php.conf:/etc/nginx/enable-php.conf # php开启
- ./nginx/conf.d:/etc/nginx/conf.d # 放站点hosts的配置
- /var/logs:/www/wwwlogs # 日志
# 站点挂载
- ../sites/default:/var/www/default:rw
- ../sites/foo:/var/www/foo:rw
- ../sites/swoole:/var/www/swoole:rw
links:
- php-fpm
- swoole
php-fpm:
<<: *common_config
container_name: ${CONTAINER_NAME_PHP_FPM}
extends:
# 载入配置模板
file: common-services.yml
service: php-tpl
volumes:
# 站点挂载
- ../sites/default:/var/www/default:rw
- ../sites/foo:/var/www/foo:rw
links:
- redis
- mysql
depends_on:
- redis
- mysql
swoole:
<<: *common_config
container_name: ${CONTAINER_NAME_SWOOLE}
extends:
# 载入配置模板
file: common-services.yml
service: php-tpl
ports:
- 9501:9501
volumes:
# 站点挂载
- ../sites/swoole:/var/www/swoole:rw
working_dir: /var/www/swoole
entrypoint: ["php", "server.php"] # 覆写 entrypoint 启动 swoole server 阻塞模式可以防止容器退出
links:
- redis
- mysql
depends_on:
- redis
- mysql
redis:
<<: *common_config
container_name: ${CONTAINER_NAME_REDIS}
image: redis:latest
ports:
- 6397:6379
volumes:
- ./redis/log:/var/log/redis # 日志目录
- ./redis/data:/data # 数据目录 redis.conf->dir
- ./redis/conf/redis.conf:/etc/redis/redis.conf # 配置文件
command: redis-server /etc/redis/redis.conf # 使用自定义配置文件启动服务
mysql:
<<: *common_config
container_name: ${CONTAINER_NAME_MYSQL}
image: mysql:latest
ports:
- 3360:3306
volumes:
- ./mysql/log:/var/log/mysql # 挂载日志 为了保存二进制日志
- ./mysql/data:/var/lib/mysql # 挂载数据 一定要外挂出来 不然容器销毁数据全无 提桶跑路
- ./mysql/my.cnf:/etc/my.cnf # 自定义配置文件 可配置 datadir
- ./mysql/conf.d:/etc/mysql/conf.d # 额外的配置文件目录
environment:
MYSQL_USER: www # 普通用户
MYSQL_PASSWORD: 123456 # 普通用户密码
MYSQL_ROOT_PASSWORD: 123456 # root密码
MYSQL_DATABASE: test # 默认新建数据库名称
node: #node.js 个人目前主要用于编译
<<: *common_config
container_name: ${CONTAINER_NAME_NODE}
platform: linux/x86_64
image: node
volumes:
- ../sites:/root/sites #项目
nginx 镜像
Dockerfile 主要为了创建多级目录
FROM nginx:latest
# nginx 无权创建二级目录 需使用命令提前创建
# for proxy.conf
RUN mkdir -p /tmp/nginx/proxy_temp_dir
RUN mkdir -p /tmp/nginx/proxy_cache_dir
镜像配置文件路径
# nginx 的主配置目录
# tree /etc/nginx/
/etc/nginx/
|-- conf.d # 站点配置目录
|-- fastcgi_params
|-- mime.types
|-- modules -> /usr/lib/nginx/modules
|-- nginx.conf # 主配置文件
|-- scgi_params
`-- uwsgi_params
php 镜像
Dockerfile 为了开启更多必要扩展
FROM php:8.2-fpm
RUN apt-get update
RUN apt-get install -y \
libmcrypt-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libwebp-dev \
libevent-dev \
libssl-dev
# 解压源码
RUN docker-php-source extract
# 安装扩展
RUN docker-php-ext-install -j$(nproc) iconv exif fileinfo
# 如果安装的扩展需要自定义配置时
RUN docker-php-ext-configure gd --with-webp=/usr/include/webp --with-jpeg=/usr/include --with-freetype=/usr/include/freetype2/
RUN docker-php-ext-install -j$(nproc) gd
# docker-php-ext 安装扩展会被自动加载 /usr/local/etc/php/conf.d/docker-php-ext-xxx.ini
RUN docker-php-ext-install pdo_mysql
RUN docker-php-ext-install sockets
RUN docker-php-ext-install sodium
# event 中默认 --enbale-event-socket 选项需要先安装 sockets 扩展后才可以
# pecl 安装的扩展不会被自动加载 需要手动配置引入 在宿主机上定义并挂在至容器的如下目录即可
# /usr/local/etc/php/conf.d/docker-php-z-exts.ini
# 加载顺序按文件名 ASCII 正序 比如 event 扩展依赖 sockets 需要在其后加载
# 所以我们自定义的文件名是用 -z- 来排在最后
RUN pecl install event
RUN pecl install swoole
RUN pecl install redis
# 删除源码
RUN docker-php-source delete
php:{version}-fpm
镜像在编译时
通过 --with-config-file-path
指定了配置目录 /usr/local/etc/php
通过 --with-config-file-scan-dir
指定了额外载入的配置目录 /usr/local/etc/php/conf.d
。
php-cli
会加载 :
/usr/local/etc/php/php.ini
/usr/local/etc/php/conf.d/*.ini
php-fpm -t
可以查看 fpm
加载的配置文件,会加载:
- 加载
php-cli
的配置。 /usr/local/etc/php-fpm.conf
/usr/local/etc/php-fpm.d/*.conf
不过我没搞清楚 php-fpm
是如何被指定配置文件路径是 /usr/local/etc/
的,毕竟 php
声明的 configDir
是 /usr/local/etc/php
。传统的 fpm
配置文件也是在 {prefix}/etc/php-fpm.conf
(如有知晓的同学欢迎留言解惑)。
镜像配置文件路径
# tree /usr/local/etc
/usr/local/etc
|-- pear.conf
|-- php # 主配置目录 --with-config-file-path
| |-- conf.d # 扩展配置目录 --with-config-file-scan-dir
| | |-- docker-fpm.ini
| | |-- docker-php-ext-exif.ini
| | |-- docker-php-ext-gd.ini
| | |-- docker-php-ext-pdo_mysql.ini
| | |-- docker-php-ext-sockets.ini
| | `-- docker-php-ext-sodium.ini
| |-- php.ini-development
| `-- php.ini-production # 默认没有 php.ini 文件,可以挂载
|-- php-fpm.conf # fpm 主配置 会引入 php-fpm.d 下的扩展配置
|-- php-fpm.conf.default
`-- php-fpm.d # php-fpm 启动时会自动加载 php-fpm.d 下的配置文件
|-- docker.conf # fpm 日志相关
|-- www.conf # fpm 进程池配置
|-- www.conf.default
`-- zz-docker.conf # fpm 监听端口
查看容器启动的 entrypoint
看下启动的命令
# 宿主机执行 看到 entrypoint 是启动了一个 bin
docker inspect --format '{{ .Config.Entrypoint }}' <container_id>
[docker-php-entrypoint]
# 登录容器查找这个 bin
docker -it exec <container_id> bash
# which docker-php-entrypoint
/usr/local/bin/docker-php-entrypoint
# cat /usr/local/bin/docker-php-entrypoint
#!/bin/sh
set -e
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
set -- php-fpm "$@"
fi
exec "$@
mysql
镜像配置文件路径
/etc/my.cnf #主配置文件
/etc/mysql/conf.d # 扩展配置目录
redis
镜像配置文件路径
/etc/redis/redis.conf #主配置文件
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。