Laradock 简介
Laradock 是一个基于 Docker 的完整 PHP 开发环境,专为 PHP 开发者(特别是 Laravel 开发者)设计。它提供了一套预配置的 Docker 容器,包含开发中常用的服务,如 Nginx、MySQL、Redis、PHP-FPM 等。
主要优势
- 开箱即用:预配置的开发环境,无需繁琐设置
- 一致性:确保开发、测试和生产环境的一致性
- 灵活性:支持多种 PHP 版本和扩展
- 模块化:可以根据需要启用或禁用特定服务
- 跨平台:在 Windows、macOS 和 Linux 上表现一致
基本架构
Laradock 采用模块化设计,每个服务都运行在独立的容器中,通过 Docker 网络连接:
- Workspace:包含开发工具的容器
- PHP-FPM:PHP 解释器
- Nginx/Apache:Web 服务器
- MySQL/PostgreSQL/MongoDB:数据库
- Redis/Memcached:缓存
- 其他辅助服务(邮件服务器、消息队列等)
Dockerfile
DEBIAN_FRONTEND
ENV DEBIAN_FRONTEND=noninteractive
DEBIAN_FRONTEND 环境变量用于告知操作系统应该从哪儿获得用户输入。
设置为 “noninteractive” 可以实现自动安装而无需用户交互,对于 CI/CD 流程和 Docker 构建特别有用。这在运行 apt-get 命令时尤为重要,因为它会自动选择默认选项并以最快速度完成构建。
最佳实践是在 RUN 命令中设置该变量,而不是使用 ENV 进行全局设置,因为全局设置会影响容器运行时的交互体验:
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
基于角色的用户配置
# 创建非 root 用户防止文件在宿主机上创建时具有 root 权限
ARG PUID=1000
ENV PUID ${PUID}
ARG PGID=1000
ENV PGID ${PGID}
RUN set -xe; \
groupadd -g ${PGID} laradock && \
useradd -l -u ${PUID} -g laradock -m laradock -G docker_env && \
usermod -p "*" laradock -s /bin/bash
这段配置创建了一个非 root 用户 laradock
,解决了容器和宿主机之间文件权限问题:
- 可配置的 UID/GID:通过 ARG 和 ENV 指令使用户 ID 和组 ID 可配置
- 权限一致性:将容器内用户的 UID/GID 与宿主机用户匹配,确保文件权限一致
- 改善开发体验:设置 bash 作为默认 shell,并且不需要密码
实际使用中,可以通过 .env
文件配置这些值:
PUID=1000
PGID=1000
通过 id -u
和 id -g
命令可以获取当前用户的 UID 和 GID。
PHP 扩展安装示例
Swoole 安装
Swoole 是一个高性能的 PHP 异步网络通信引擎。安装 Swoole 时,可以使用 PECL:
# php7.1
echo '' | pecl -q install --configureoptions 'enable-openssl="yes" enable-mysqlnd="yes" enable-swoole-curl="yes"' swoole-4.5.11;
这个命令通过 PECL 安装 Swoole 4.5.11,并启用了 OpenSSL、MySQL Native Driver 和 cURL 支持。安装后可以通过以下命令验证 OpenSSL 支持:
php -r "new swoole_server('0.0.0.0', 443, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);"
如果没有错误输出,说明 OpenSSL 支持已正确启用。
PHP 版本智能检测
RUN if [ $(php -r "echo PHP_MAJOR_VERSION;") = "8" ] || { [ $(php -r "echo PHP_MAJOR_VERSION;") = "7" ] && { [ $(php -r "echo PHP_MINOR_VERSION;") = "4" ] || [ $(php -r "echo PHP_MINOR_VERSION;") = "3" ] ;} ;}; then \
# PHP 8.x 或 PHP 7.3/7.4 的配置
pecl install xdebug-3.1.6; \
else \
if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then \
# PHP 5.x 的配置
pecl install xdebug-2.5.5; \
else \
# 其他 PHP 7.x 版本的配置
if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then \
pecl install xdebug-2.9.0; \
else \
pecl install xdebug-2.9.8; \
fi \
fi \
fi
Laradock 的 Dockerfile 中大量使用 PHP 版本检测,确保安装与当前 PHP 版本兼容的扩展和工具:
- 使用
php -r
内联执行 PHP 命令获取版本信息 - 通过嵌套条件语句处理不同的 PHP 版本需求
- 支持多种 PHP 版本(从 5.x 到 8.x)使用同一个 Dockerfile
这种方法使得一个 Dockerfile 可以适应多个 PHP 版本,极大简化了维护工作。
Composer 双版本安装
# 更新 composer
ARG COMPOSER_VERSION=2
ENV COMPOSER_VERSION ${COMPOSER_VERSION}
RUN set -eux; \
if [ "$COMPOSER_VERSION" = "1" ] || [ "$COMPOSER_VERSION" = "2" ] || [ "$COMPOSER_VERSION" = "2.2" ]; then \
composer self-update --${COMPOSER_VERSION}; \
else \
composer self-update ${COMPOSER_VERSION}; \
fi
Laradock 支持灵活选择 Composer 版本:
- 允许通过环境变量切换 Composer 1.x、2.x 或特定版本
- 适应不同项目的兼容性需求
- 方便在旧项目和新项目之间切换
实用场景:某些旧项目可能与 Composer 2.x 不兼容,而新项目需要更新的 Composer 功能。
docker-compose.yml 配置技巧
主机名解析
extra_hosts:
- "dockerhost:${DOCKER_HOST_IP}"
这个配置会在容器的 /etc/hosts
文件中添加一条记录:
10.0.75.1 dockerhost
这样,容器内的应用可以通过 dockerhost
域名访问宿主机,无需使用动态 IP 地址。
模块化服务架构
Laradock 的 docker-compose.yml 文件采用高度模块化的设计:
services:
workspace:
build:
context: ./workspace
args:
- PHP_VERSION=${PHP_VERSION}
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
networks:
- frontend
- backend
php-fpm:
build:
context: ./php-fpm
args:
- PHP_VERSION=${PHP_VERSION}
volumes:
- ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
depends_on:
- workspace
networks:
- backend
主要特点:
- 每个服务独立配置:可以只启动需要的服务
- 明确的依赖关系:使用
depends_on
确保正确的启动顺序 - 统一的环境变量:从
.env
文件加载配置
网络配置
networks:
frontend:
driver: bridge
backend:
driver: bridge
Laradock 采用前后端分离的网络设计:
- 前端网络:连接 Web 服务器和负载均衡器
- 后端网络:连接应用服务(PHP-FPM)和数据库
- 安全隔离:数据库等服务不直接暴露给前端
这种设计增强了安全性,防止外部直接访问敏感服务。
卷管理策略
volumes:
mysql:
driver: ${VOLUMES_DRIVER}
redis:
driver: ${VOLUMES_DRIVER}
postgres:
driver: ${VOLUMES_DRIVER}
Laradock 使用命名卷而非绑定挂载来提高性能和可移植性:
- 集中式数据路径:使用
${DATA_PATH_HOST}
管理所有持久化数据 - 可配置驱动:支持本地存储或网络存储
- 性能优化:命名卷在某些平台(特别是 Windows 和 macOS)上性能更好
实际使用示例:
# 查看卷列表
docker volume ls
# 备份数据卷
docker run --rm -v laradock_mysql:/source -v $(pwd):/backup alpine tar -czvf /backup/mysql_backup.tar.gz -C /source .
资源限制配置
php-fpm:
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
mem_limit: 1024m
Laradock 支持为服务配置资源限制:
- 进程数限制:控制可创建的进程数
- 文件描述符限制:影响并发连接能力
- 内存限制:防止单个容器消耗过多资源
这些设置对于生产环境特别重要,可以防止单个服务耗尽系统资源。
端口映射策略
mysql:
ports:
- "${MYSQL_PORT}:3306"
Laradock 采用可配置的端口映射策略:
- 所有端口都可配置:通过环境变量定义外部端口
- 避免默认暴露端口:增强安全性
- 灵活处理端口冲突:可以在不同项目使用不同端口
端口冲突是多项目开发中常见的问题,这种设计可以轻松避免。
PHP 扩展管理
常用开发扩展
Xdebug
ARG INSTALL_XDEBUG=false
RUN if [ ${INSTALL_XDEBUG} = true ]; then \
# 安装 Xdebug 并配置
pecl install xdebug && \
docker-php-ext-enable xdebug \
fi
Xdebug 是 PHP 的调试和分析工具。在 Laradock 中,可以通过环境变量控制是否安装:
WORKSPACE_INSTALL_XDEBUG=true
PHP_FPM_INSTALL_XDEBUG=true
实际使用配置(php.ini):
[xdebug]
xdebug.mode=debug
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.start_with_request=yes
PCOV
PCOV 是一个轻量级代码覆盖率驱动,比 Xdebug 更快:
- 专注于代码覆盖率分析
- 与 PHPUnit 完全兼容
- 性能影响比 Xdebug 小
在 Laravel 项目中使用示例:
php -dpcov.enabled=1 vendor/bin/phpunit --coverage-html coverage
Taint
Taint 是由 PHP 核心开发者鸟哥(惠新宸)开发的 PHP 扩展,用于检测 XSS 代码:
- 自动检测可能的 XSS 漏洞
- 低运行时开销
- 适合在开发环境中使用
数据库相关扩展
OCI8
ARG INSTALL_OCI8=false
ARG ORACLE_INSTANT_CLIENT_MIRROR=https://github.com/the-paulus/oracle-instantclient/raw/master/
ARG ORACLE_INSTANT_CLIENT_ARCH=x86_64
ARG ORACLE_INSTANT_CLIENT_MAJOR=18
ARG ORACLE_INSTANT_CLIENT_MINOR=3
RUN if [ ${INSTALL_OCI8} = true ]; then \
# 安装 Oracle Instantclient 和 PHP OCI8 扩展
...
fi
OCI8 用于连接 Oracle 数据库,通过 Oracle Call Interface 提供完整的功能:
- 支持 Oracle 的所有数据类型
- 处理大型对象(LOB)
- 支持绑定变量和存储过程
示例代码:
$conn = oci_connect('username', 'password', 'localhost/XE');
$stmt = oci_parse($conn, 'SELECT * FROM employees');
oci_execute($stmt);
while ($row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_NULLS)) {
var_dump($row);
}
Redis
Laradock 支持两种 Redis 扩展:
- PhpRedis:C 扩展,性能更好
- Predis:纯 PHP 实现,更灵活
PhpRedis 安装示例:
ARG INSTALL_PHPREDIS=false
RUN if [ ${INSTALL_PHPREDIS} = true ]; then \
pecl install redis && \
docker-php-ext-enable redis \
fi
性能优化扩展
OPcache
OPcache 通过将 PHP 脚本预编译的字节码存储在共享内存中来提高性能,减少加载和解析的开销:
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=0
在生产环境中,可以设置 validate_timestamps=0
来防止 OPcache 检查文件变化,进一步提高性能。
APCu
APCu 是一个用户数据缓存系统,可以在 PHP 进程中存储 key-value 数据:
apcu_store('my_key', 'my_value', 3600); // 存储数据,过期时间为 1 小时
$value = apcu_fetch('my_key'); // 读取数据
与 OPcache 不同,APCu 专注于用户数据缓存,而非代码缓存。
实用工具与配置
软件源和镜像
# 将应用源从 deb.debian.org 更改为阿里云源
sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \
sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list && \
sed -i 's/security-cdn.debian.org/mirrors.tuna.tsinghua.edu.cn/' /etc/apt/sources.list \
在国内环境使用 Laradock 时,配置国内镜像源可以大幅提升构建速度:
- 系统源:使用 TUNA 或阿里云源
- Composer:配置 Packagist 中国镜像
- NPM:配置淘宝 NPM 镜像
可以在 .env
文件中设置:
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org/
WORKSPACE_COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/
Node.js 配置
ARG INSTALL_NODE=false
ARG NODE_VERSION=node
ARG INSTALL_NPM_GULP=false
ARG INSTALL_NPM_BOWER=false
ARG INSTALL_NPM_VUE_CLI=false
ARG INSTALL_NPM_ANGULAR_CLI=false
ARG NPM_REGISTRY
RUN if [ ${INSTALL_NODE} = true ]; then \
# 安装 nvm 和 Node.js
...
fi
Laradock 的 Node.js 配置非常灵活:
- 使用 NVM 管理 Node.js 版本
- 支持配置 NPM 镜像源
- 可选安装常用前端工具(Vue CLI、Angular CLI 等)
- 支持 Yarn 和 PNPM 等现代包管理器
使用案例:
WORKSPACE_INSTALL_NODE=true
WORKSPACE_NODE_VERSION=16
WORKSPACE_NPM_REGISTRY=https://registry.npm.taobao.org/
WORKSPACE_INSTALL_NPM_VUE_CLI=true
常用命令工具
update-alternatives
update-alternatives
用于管理 Linux 系统中的命令替代版本:
# 设置默认 PHP 版本
update-alternatives --set php /usr/bin/php7.4
Laradock 使用这个命令管理多个 PHP 版本。
docker-php-ext-disable
# 禁用不需要的扩展(不需要重新编译)
docker-php-ext-disable xdebug pcov
Laradock 特有的实用脚本,允许:
- 在生产环境中禁用性能密集型扩展
- 保留扩展文件但不加载,避免重新编译
- 需要时快速重新启用扩展
这对于开发/生产环境切换非常有用,可以保持相同的镜像但有不同的扩展启用状态。
常用操作指南
基本使用流程
# 克隆 Laradock 仓库
git clone https://github.com/laradock/laradock.git
# 复制环境配置文件
cp .env.example .env
# 编辑配置文件,设置项目路径等
vim .env
# 构建并启动容器
docker compose up -d nginx mysql redis
常用维护命令
# 构建特定服务
docker compose build workspace php-fpm
# 进入容器
docker compose exec workspace bash
# 查看日志
docker compose logs nginx
# 停止所有容器
docker compose down
故障排除
端口冲突:修改
.env
文件中的端口映射NGINX_HOST_HTTP_PORT=8080 MYSQL_PORT=33060
权限问题:确保 PUID/PGID 设置正确
PUID=$(id -u) PGID=$(id -g)
内存不足:增加 Docker 分配的资源,或减少启用的服务
docker compose up -d nginx php-fpm mysql
高级功能
多项目环境
Laradock 支持同时运行多个项目:
.
├── laradock/
│ ├── docker-compose.yml
│ └── .env
├── project1/
├── project2/
└── project3/
配置示例:
APP_CODE_PATH_HOST=../:/var/www
NGINX_SITES_PATH=./nginx/sites/
然后为每个项目创建 Nginx 配置文件:
# ./nginx/sites/project1.conf
server {
server_name project1.test;
root /var/www/project1/public;
# ...
}
多架构支持
# 支持 ARM 和 x86 架构
FROM --platform=${TARGETPLATFORM} php:${PHP_VERSION}-fpm-alpine
ARG TARGETPLATFORM
ARG BUILDPLATFORM
Laradock 现代版本支持:
- 使用 Docker BuildKit 进行多架构构建
- 在 ARM 设备(M1/M2 Mac、树莓派)上本地开发
- 通过 GitHub Actions 实现跨平台自动构建
使用多架构镜像的命令:
# 显示支持的架构
docker manifest inspect laradock/workspace:latest
# 构建多架构镜像
docker buildx build --platform linux/amd64,linux/arm64 -t myname/myapp:latest .
CI/CD 集成
Laradock 可以与各种 CI/CD 工具集成:
# .gitlab-ci.yml 示例
stages:
- build
- test
- deploy
build:
stage: build
script:
- cd laradock
- docker compose build php-fpm workspace
test:
stage: test
script:
- cd laradock
- docker compose up -d php-fpm mysql
- docker compose exec workspace php artisan test
可以使用 Docker Compose 的 --profile
参数为不同环境创建配置:
# 开发环境
docker compose --profile dev up -d
# 测试环境
docker compose --profile test up -d
最佳实践
优化构建速度
使用 BuildKit:
DOCKER_BUILDKIT=1 docker compose build
创建层缓存:
# 先复制依赖文件,安装依赖,然后再复制应用代码 COPY composer.json composer.lock ./ RUN composer install --no-scripts --no-autoloader COPY . . RUN composer dump-autoload --optimize
多阶段构建:
FROM php:7.4-fpm AS builder # 安装构建依赖... FROM php:7.4-fpm # 只复制需要的文件 COPY --from=builder /var/www/vendor /var/www/vendor
安全最佳实践
避免使用 root 用户:
USER laradock
限制容器能力:
security_opt: - no-new-privileges:true
使用健康检查:
healthcheck: test: ["CMD", "php", "-v"] interval: 30s timeout: 10s retries: 3
定期更新基础镜像:
docker compose pull docker compose build --pull