使用 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
redis配置文件下載
鏡像配置文件路徑
/etc/redis/redis.conf #主配置文件