使用 Docker Compose 設定 Laravel 開發環境
本指南演示瞭如何使用 Docker 和 Docker Compose 為 Laravel 應用程式配置開發環境。它在 PHP-FPM 的生產映象之上構建,然後添加了面向開發人員的功能(例如 Xdebug)以簡化除錯。透過將開發容器基於已知的生產映象,可以使兩個環境保持緊密一致。
此設定包括 PHP-FPM、Nginx 和 PostgreSQL 服務(儘管您可以輕鬆地將 PostgreSQL 替換為其他資料庫,例如 MySQL 或 MariaDB)。所有內容都在容器中執行,因此您可以在不更改主機系統的情況下進行隔離開發。
注意要嘗試即用型配置,請下載 Laravel Docker 示例 倉庫。它包含用於開發和生產的預配置設定。
專案結構
my-laravel-app/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── docker/
│ ├── common/
│ │ └── php-fpm/
│ │ └── Dockerfile
│ ├── development/
│ │ ├── php-fpm/
│ │ │ └── entrypoint.sh
│ │ ├── workspace/
│ │ │ └── Dockerfile
│ │ └── nginx
│ │ ├── Dockerfile
│ │ └── nginx.conf
│ └── production/
├── compose.dev.yaml
├── compose.prod.yaml
├── .dockerignore
├── .env
├── vendor/
├── ...
此佈局表示一個典型的 Laravel 專案,Docker 配置儲存在統一的 docker
目錄中。您將找到兩個 Compose 檔案——compose.dev.yaml
(用於開發)和 compose.prod.yaml
(用於生產)——以使您的環境保持獨立和可管理。
該環境包括一個 workspace
服務,一個用於構建前端資產、執行 Artisan 命令以及專案可能需要的其他 CLI 工具的邊車容器。雖然這個額外的容器可能看起來不尋常,但它是 **Laravel Sail** 和 **Laradock** 等解決方案中常見的模式。它還包括 **Xdebug** 以幫助除錯。
為 PHP-FPM 建立 Dockerfile
此 Dockerfile 透過安裝 Xdebug 並調整使用者許可權來簡化本地開發,從而擴充套件了生產映象。這樣,您的開發環境與生產環境保持一致,同時仍然提供額外的除錯功能和改進的檔案掛載。
# Builds a dev-only layer on top of the production image
FROM production AS development
# Use ARGs to define environment variables passed from the Docker build command or Docker Compose.
ARG XDEBUG_ENABLED=true
ARG XDEBUG_MODE=develop,coverage,debug,profile
ARG XDEBUG_HOST=host.docker.internal
ARG XDEBUG_IDE_KEY=DOCKER
ARG XDEBUG_LOG=/dev/stdout
ARG XDEBUG_LOG_LEVEL=0
USER root
# Configure Xdebug if enabled
RUN if [ "${XDEBUG_ENABLED}" = "true" ]; then \
pecl install xdebug && \
docker-php-ext-enable xdebug && \
echo "xdebug.mode=${XDEBUG_MODE}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.idekey=${XDEBUG_IDE_KEY}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.log=${XDEBUG_LOG}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.log_level=${XDEBUG_LOG_LEVEL}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.client_host=${XDEBUG_HOST}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini ; \
echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini ; \
fi
# Add ARGs for syncing permissions
ARG UID=1000
ARG GID=1000
# Create a new user with the specified UID and GID, reusing an existing group if GID exists
RUN if getent group ${GID}; then \
group_name=$(getent group ${GID} | cut -d: -f1); \
useradd -m -u ${UID} -g ${GID} -s /bin/bash www; \
else \
groupadd -g ${GID} www && \
useradd -m -u ${UID} -g www -s /bin/bash www; \
group_name=www; \
fi
# Dynamically update php-fpm to use the new user and group
RUN sed -i "s/user = www-data/user = www/g" /usr/local/etc/php-fpm.d/www.conf && \
sed -i "s/group = www-data/group = $group_name/g" /usr/local/etc/php-fpm.d/www.conf
# Set the working directory
WORKDIR /var/www
# Copy the entrypoint script
COPY ./docker/development/php-fpm/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# Switch back to the non-privileged user to run the application
USER www-data
# Change the default command to run the entrypoint script
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
為 Workspace 建立 Dockerfile
工作區容器為資產編譯、Artisan/Composer 命令和其他 CLI 任務提供了一個專用 shell。這種方法遵循 Laravel Sail 和 Laradock 的模式,將所有開發工具整合到一個容器中以方便使用。
# docker/development/workspace/Dockerfile
# Use the official PHP CLI image as the base
FROM php:8.4-cli
# Set environment variables for user and group ID
ARG UID=1000
ARG GID=1000
ARG NODE_VERSION=22.0.0
# Install system dependencies and build libraries
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
unzip \
libpq-dev \
libonig-dev \
libssl-dev \
libxml2-dev \
libcurl4-openssl-dev \
libicu-dev \
libzip-dev \
&& docker-php-ext-install -j$(nproc) \
pdo_mysql \
pdo_pgsql \
pgsql \
opcache \
intl \
zip \
bcmath \
soap \
&& pecl install redis xdebug \
&& docker-php-ext-enable redis xdebug\
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
&& apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Use ARG to define environment variables passed from the Docker build command or Docker Compose.
ARG XDEBUG_ENABLED
ARG XDEBUG_MODE
ARG XDEBUG_HOST
ARG XDEBUG_IDE_KEY
ARG XDEBUG_LOG
ARG XDEBUG_LOG_LEVEL
# Configure Xdebug if enabled
RUN if [ "${XDEBUG_ENABLED}" = "true" ]; then \
docker-php-ext-enable xdebug && \
echo "xdebug.mode=${XDEBUG_MODE}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.idekey=${XDEBUG_IDE_KEY}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.log=${XDEBUG_LOG}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.log_level=${XDEBUG_LOG_LEVEL}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \
echo "xdebug.client_host=${XDEBUG_HOST}" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini ; \
echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini ; \
fi
# If the group already exists, use it; otherwise, create the 'www' group
RUN if getent group ${GID}; then \
useradd -m -u ${UID} -g ${GID} -s /bin/bash www; \
else \
groupadd -g ${GID} www && \
useradd -m -u ${UID} -g www -s /bin/bash www; \
fi && \
usermod -aG sudo www && \
echo 'www ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# Switch to the non-root user to install NVM and Node.js
USER www
# Install NVM (Node Version Manager) as the www user
RUN export NVM_DIR="$HOME/.nvm" && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash && \
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" && \
nvm install ${NODE_VERSION} && \
nvm alias default ${NODE_VERSION} && \
nvm use default
# Ensure NVM is available for all future shells
RUN echo 'export NVM_DIR="$HOME/.nvm"' >> /home/www/.bashrc && \
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> /home/www/.bashrc && \
echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> /home/www/.bashrc
# Set the working directory
WORKDIR /var/www
# Override the entrypoint to avoid the default php entrypoint
ENTRYPOINT []
# Default command to keep the container running
CMD ["bash"]
注意如果您更喜歡每個服務一個容器的方法,只需省略工作區容器併為每個任務執行單獨的容器。例如,您可以為 PHP 指令碼使用專用的
php-cli
容器,並使用node
容器來處理資產構建。
建立用於開發的 Docker Compose 配置
這是設定開發環境的 compose.yaml
檔案
services:
web:
image: nginx:latest # Using the default Nginx image with custom configuration.
volumes:
# Mount the application code for live updates
- ./:/var/www
# Mount the Nginx configuration file
- ./docker/development/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
ports:
# Map port 80 inside the container to the port specified by 'NGINX_PORT' on the host machine
- "80:80"
environment:
- NGINX_HOST=localhost
networks:
- laravel-development
depends_on:
php-fpm:
condition: service_started # Wait for php-fpm to start
php-fpm:
# For the php-fpm service, we will use our common PHP-FPM Dockerfile with the development target
build:
context: .
dockerfile: ./docker/common/php-fpm/Dockerfile
target: development
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
XDEBUG_ENABLED: ${XDEBUG_ENABLED:-true}
XDEBUG_MODE: develop,coverage,debug,profile
XDEBUG_HOST: ${XDEBUG_HOST:-host.docker.internal}
XDEBUG_IDE_KEY: ${XDEBUG_IDE_KEY:-DOCKER}
XDEBUG_LOG: /dev/stdout
XDEBUG_LOG_LEVEL: 0
env_file:
# Load the environment variables from the Laravel application
- .env
user: "${UID:-1000}:${GID:-1000}"
volumes:
# Mount the application code for live updates
- ./:/var/www
networks:
- laravel-development
depends_on:
postgres:
condition: service_started # Wait for postgres to start
workspace:
# For the workspace service, we will also create a custom image to install and setup all the necessary stuff.
build:
context: .
dockerfile: ./docker/development/workspace/Dockerfile
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
XDEBUG_ENABLED: ${XDEBUG_ENABLED:-true}
XDEBUG_MODE: develop,coverage,debug,profile
XDEBUG_HOST: ${XDEBUG_HOST:-host.docker.internal}
XDEBUG_IDE_KEY: ${XDEBUG_IDE_KEY:-DOCKER}
XDEBUG_LOG: /dev/stdout
XDEBUG_LOG_LEVEL: 0
tty: true # Enables an interactive terminal
stdin_open: true # Keeps standard input open for 'docker exec'
env_file:
- .env
volumes:
- ./:/var/www
networks:
- laravel-development
postgres:
image: postgres:16
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
- POSTGRES_DB=app
- POSTGRES_USER=laravel
- POSTGRES_PASSWORD=secret
volumes:
- postgres-data-development:/var/lib/postgresql/data
networks:
- laravel-development
redis:
image: redis:alpine
networks:
- laravel-development
networks:
laravel-development:
volumes:
postgres-data-development:
注意確保您的 Laravel 專案根目錄中有一個包含必要配置的
.env
檔案。您可以使用.env.example
檔案作為模板。
執行開發環境
要啟動開發環境,請使用
$ docker compose -f compose.dev.yaml up --build -d
執行此命令可在分離模式下構建並啟動開發環境。當容器完成初始化後,訪問 https:/// 以檢視您的 Laravel 應用程式執行。
摘要
透過在生產映象之上構建並新增 Xdebug 等除錯工具,您建立了一個與生產環境緊密匹配的 Laravel 開發工作流程。可選的工作區容器簡化了資產構建和執行 Artisan 命令等任務。如果您更喜歡每個服務一個單獨的容器(例如,專用的 php-cli
和 node
容器),則可以跳過工作區方法。無論哪種方式,Docker Compose 都提供了一種高效、一致的方式來開發您的 Laravel 專案。