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 -uid -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 版本兼容的扩展和工具:

  1. 使用 php -r 内联执行 PHP 命令获取版本信息
  2. 通过嵌套条件语句处理不同的 PHP 版本需求
  3. 支持多种 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 扩展:

  1. PhpRedis:C 扩展,性能更好
  2. 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 时,配置国内镜像源可以大幅提升构建速度:

  1. 系统源:使用 TUNA 或阿里云源
  2. Composer:配置 Packagist 中国镜像
  3. 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

故障排除

  1. 端口冲突:修改 .env 文件中的端口映射

    NGINX_HOST_HTTP_PORT=8080
    MYSQL_PORT=33060
    
  2. 权限问题:确保 PUID/PGID 设置正确

    PUID=$(id -u)
    PGID=$(id -g)
    
  3. 内存不足:增加 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

最佳实践

优化构建速度

  1. 使用 BuildKit

    DOCKER_BUILDKIT=1 docker compose build
    
  2. 创建层缓存

    # 先复制依赖文件,安装依赖,然后再复制应用代码
    COPY composer.json composer.lock ./
    RUN composer install --no-scripts --no-autoloader
    COPY . .
    RUN composer dump-autoload --optimize
    
  3. 多阶段构建

    FROM php:7.4-fpm AS builder
    # 安装构建依赖...
    
    FROM php:7.4-fpm
    # 只复制需要的文件
    COPY --from=builder /var/www/vendor /var/www/vendor
    

安全最佳实践

  1. 避免使用 root 用户

    USER laradock
    
  2. 限制容器能力

    security_opt:
      - no-new-privileges:true
    
  3. 使用健康检查

    healthcheck:
      test: ["CMD", "php", "-v"]
      interval: 30s
      timeout: 10s
      retries: 3
    
  4. 定期更新基础镜像

    docker compose pull
    docker compose build --pull
    

References