Docker教程 · 2024年11月11日

使用容器进行 PHP 开发

使用容器进行 PHP 开发

完成 。

在本部分中,您将了解如何为容器化应用程序设置开发环境。这包括:

  • 添加本地数据库并持久化数据
  • 添加phpMyAdmin与数据库交互
  • 配置 Compose 以在您编辑和保存代码时自动更新正在运行的 Compose 服务
  • 创建包含开发依赖项的开发容器

您可以使用容器来设置本地服务,例如数据库。要对示例应用程序执行此操作,您需要执行以下操作:

  • 更新Dockerfile以安装扩展以连接到数据库
  • 更新compose.yaml文件以添加数据库服务和卷来保存数据

要安装 PHP 扩展,您需要更新Dockerfile.在 IDE 或文本编辑器中打开 Dockerfile,然后更新内容。以下 Dockerfile包括安装pdopdo_mysql 扩展的一条新线路。所有评论已被删除。


# syntax=docker/dockerfile:1  FROM composer:lts as deps WORKDIR /app RUN --mount=type=bind,source=composer.json,target=composer.json \  --mount=type=bind,source=composer.lock,target=composer.lock \  --mount=type=cache,target=/tmp/cache \  composer install --no-dev --no-interaction  FROM php:8.2-apache as final RUN docker-php-ext-install pdo pdo_mysql RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY --from=deps app/vendor/ /var/www/html/vendor COPY ./src /var/www/html USER www-data

有关安装 PHP 扩展的更多详细信息,请参阅 。

compose.yaml在 IDE 或文本编辑器中打开文件。您会注意到它已经包含 PostgreSQL 数据库和卷的注释掉指令。对于此应用程序,您将使用 MariaDB。有关 MariaDB 的更多详细信息,请参阅 。

src/database.php在 IDE 或文本编辑器中打开文件。您会注意到它读取环境变量以便连接到数据库。

在该compose.yaml文件中,您需要更新以下内容:

  1. 取消注释并更新 MariaDB 的数据库说明。
  2. 向服务器服务添加一个secret以传入数据库密码。
  3. 将数据库连接环境变量添加到服务器服务中。
  4. 取消注释卷指令以保留数据。

以下是更新后的compose.yaml文件。所有评论已被删除。


services:  server:  build:  context: .  ports:  - 9000:80  depends_on:  db:  condition: service_healthy  secrets:  - db-password  environment:  - PASSWORD_FILE_PATH=/run/secrets/db-password  - DB_HOST=db  - DB_NAME=example  - DB_USER=root  db:  image: mariadb  restart: always  user: root  secrets:  - db-password  volumes:  - db-data:/var/lib/mysql  environment:  - MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db-password  - MARIADB_DATABASE=example  expose:  - 3306  healthcheck:  test: ["CMD", "/usr/local/bin/healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"]  interval: 10s  timeout: 5s  retries: 5 volumes:  db-data: secrets:  db-password:  file: db/password.txt

笔记

要了解有关 Compose 文件中的说明的更多信息,请参阅 。

在使用 Compose 运行应用程序之前,请注意此 Compose 文件使用 secrets并指定一个password.txt文件来保存数据库的密码。您必须创建此文件,因为它不包含在源存储库中。

在该docker-php-sample目录中,创建一个名为 的新目录db,并在该目录内创建一个名为password.txt.在 IDE 或文本编辑器中打开password.txt并添加以下密码。密码必须位于单行中,文件中不得有任何其他行。


example

保存并关闭password.txt文件。

您的目录中现在应该有以下内容docker-php-sample


├── docker-php-sample/ │ ├── .git/ │ ├── db/ │ │ └── password.txt │ ├── src/ │ ├── tests/ │ ├── .dockerignore │ ├── .gitignore │ ├── compose.yaml │ ├── composer.json │ ├── composer.lock │ ├── Dockerfile │ ├── README.Docker.md │ └── README.md

运行以下命令来启动您的应用程序。


$ docker compose up --build 

查看应用程序 。您应该看到一个简单的 Web 应用程序,其中包含文本和每次刷新时都会递增的计数器。

ctrl+c终端停止您的应用程序。

在终端中,运行docker compose rm以删除容器,然后运行docker compose up以再次运行应用程序。


$ docker compose rm $ docker compose up --build 

在浏览器中刷新 并验证之前的计数是否仍然存在。如果没有卷,删除容器后数据库数据将不会保留。

ctrl+c终端停止您的应用程序。

您可以通过更新文件轻松地将服务添加到应用程序堆栈中compose.yaml

更新您的compose.yamlphpMyAdmin 添加新服务。有关更多详细信息,请参阅 。以下是更新后的compose.yaml文件。


services:  server:  build:  context: .  ports:  - 9000:80  depends_on:  db:  condition: service_healthy  secrets:  - db-password  environment:  - PASSWORD_FILE_PATH=/run/secrets/db-password  - DB_HOST=db  - DB_NAME=example  - DB_USER=root  db:  image: mariadb  restart: always  user: root  secrets:  - db-password  volumes:  - db-data:/var/lib/mysql  environment:  - MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db-password  - MARIADB_DATABASE=example  expose:  - 3306  healthcheck:  test: ["CMD", "/usr/local/bin/healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"]  interval: 10s  timeout: 5s  retries: 5  phpmyadmin:  image: phpmyadmin  ports:  - 8080:80  depends_on:  - db  environment:  - PMA_HOST=db volumes:  db-data: secrets:  db-password:  file: db/password.txt

在终端中,运行docker compose up以再次运行您的应用程序。


$ docker compose up --build 

在浏览器中打开 访问phpMyAdmin。使用root用户名和example密码登录。您现在可以通过 phpMyAdmin 与数据库交互。

ctrl+c终端停止您的应用程序。

使用 Compose Watch 在您编辑和保存代码时自动更新正在运行的 Compose 服务。有关 Compose Watch 的更多详细信息,请参阅 。

compose.yaml在 IDE 或文本编辑器中打开文件,然后添加 Compose Watch 指令。以下是更新后的compose.yaml文件。


services:  server:  build:  context: .  ports:  - 9000:80  depends_on:  db:  condition: service_healthy  secrets:  - db-password  environment:  - PASSWORD_FILE_PATH=/run/secrets/db-password  - DB_HOST=db  - DB_NAME=example  - DB_USER=root  develop:  watch:  - action: sync  path: ./src  target: /var/www/html  db:  image: mariadb  restart: always  user: root  secrets:  - db-password  volumes:  - db-data:/var/lib/mysql  environment:  - MARIADB_ROOT_PASSWORD_FILE=/run/secrets/db-password  - MARIADB_DATABASE=example  expose:  - 3306  healthcheck:  test: ["CMD", "/usr/local/bin/healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"]  interval: 10s  timeout: 5s  retries: 5  phpmyadmin:  image: phpmyadmin  ports:  - 8080:80  depends_on:  - db  environment:  - PMA_HOST=db volumes:  db-data: secrets:  db-password:  file: db/password.txt

运行以下命令以使用 Compose Watch 运行您的应用程序。


$ docker compose watch 

打开浏览器并验证应用程序是否正在 运行。

对本地计算机上应用程序源文件的任何更改现在都将立即反映在正在运行的容器中。

在 IDE 或文本编辑器中打开hello.php并将字符串更新Hello, world!Hello, Docker!.

保存更改hello.php,然后等待几秒钟以使应用程序同步。在浏览器中刷新 并验证是否显示更新的文本。

ctrl+c终端中的 来停止 Compose Watch。docker compose down在终端中运行以停止应用程序。

此时,当您运行容器化应用程序时,Composer 不会安装开发依赖项。虽然这个小映像非常适合生产,但它缺少开发时可能需要的工具和依赖项,并且不包含目录tests。您可以使用多阶段构建在同一个 Dockerfile 中构建开发和生产阶段。有关更多详细信息,请参阅 。

在 中Dockerfile,您需要更新以下内容:

  1. deps舞台分为两个阶段。一个阶段用于生产 ( prod-deps),一个阶段 ( dev-deps) 用于安装开发依赖项。
  2. 创建一个共同的base舞台。
  3. development开创发展新阶段。
  4. 更新final阶段以从新prod-deps阶段复制依赖项。

以下是Dockerfile修改前和修改后的情况。

前 后



# syntax=docker/dockerfile:1  FROM composer:lts as deps WORKDIR /app RUN --mount=type=bind,source=composer.json,target=composer.json \  --mount=type=bind,source=composer.lock,target=composer.lock \  --mount=type=cache,target=/tmp/cache \  composer install --no-dev --no-interaction  FROM php:8.2-apache as final RUN docker-php-ext-install pdo pdo_mysql RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY --from=deps app/vendor/ /var/www/html/vendor COPY ./src /var/www/html USER www-data


# syntax=docker/dockerfile:1  FROM composer:lts as prod-deps WORKDIR /app RUN --mount=type=bind,source=./composer.json,target=composer.json \  --mount=type=bind,source=./composer.lock,target=composer.lock \  --mount=type=cache,target=/tmp/cache \  composer install --no-dev --no-interaction  FROM composer:lts as dev-deps WORKDIR /app RUN --mount=type=bind,source=./composer.json,target=composer.json \  --mount=type=bind,source=./composer.lock,target=composer.lock \  --mount=type=cache,target=/tmp/cache \  composer install --no-interaction  FROM php:8.2-apache as base RUN docker-php-ext-install pdo pdo_mysql COPY ./src /var/www/html  FROM base as development COPY ./tests /var/www/html/tests RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" COPY --from=dev-deps app/vendor/ /var/www/html/vendor  FROM base as final RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY --from=prod-deps app/vendor/ /var/www/html/vendor USER www-data

compose.yaml通过添加针对开发阶段的指令来更新您的文件。

以下是该compose.yaml文件的更新部分。


services:  server:  build:  context: .  target: development  # ...

您的容器化应用程序现在将安装开发依赖项。

运行以下命令来启动您的应用程序。


$ docker compose up --build 

查看应用程序 。您仍然应该看到简单的“Hello, Docker!”应用。

ctrl+c终端停止您的应用程序。

虽然应用程序看起来相同,但您现在可以使用开发依赖项。继续下一部分,了解如何使用 Docker 运行测试。

在本部分中,您了解了如何设置 Compose 文件以添加本地数据库并保留数据。您还了解了如何使用 Compose Watch 在更新代码时自动同步您的应用程序。最后,您学习了如何创建包含开发所需的依赖项的开发容器。

相关信息:

在下一节中,您将学习如何使用 Docker 运行单元测试。