使用容器进行PHP开发
先决条件
完成 将PHP应用程序容器化。
概述
在本节中,您将学习如何为您的容器化应用程序设置开发环境。这包括:
- 添加本地数据库并持久化数据
- 添加phpMyAdmin以与数据库进行交互
- 配置Compose以在您编辑和保存代码时自动更新正在运行的Compose服务
- 创建一个包含开发依赖项的开发容器
添加本地数据库并持久化数据
你可以使用容器来设置本地服务,比如数据库。 要为示例应用程序执行此操作,你需要执行以下操作:
- 更新
Dockerfile以安装连接到数据库的扩展 - 更新
compose.yaml文件以添加数据库服务和卷来持久化数据
更新Dockerfile以安装扩展
要安装PHP扩展,您需要更新Dockerfile。在IDE或文本编辑器中打开您的Dockerfile,然后更新内容。以下Dockerfile包含一个新行,用于安装pdo和pdo_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扩展的更多详细信息,请参阅 PHP的官方Docker镜像。
更新 compose.yaml 文件以添加数据库并持久化数据
在IDE或文本编辑器中打开compose.yaml文件。你会注意到它已经包含了关于PostgreSQL数据库和卷的注释说明。对于这个应用程序,你将使用MariaDB。有关MariaDB的更多详细信息,请参阅MariaDB官方Docker镜像。
在IDE或文本编辑器中打开src/database.php文件。您会注意到它读取环境变量以连接到数据库。
在compose.yaml文件中,您需要更新以下内容:
- 取消注释并更新MariaDB的数据库指令。
- 向服务器服务添加一个秘密以传入数据库密码。
- 将数据库连接环境变量添加到服务器服务中。
- 取消注释卷指令以持久化数据。
以下是更新后的 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运行应用程序之前,请注意此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
打开浏览器并在 http://localhost:9000/database.php查看应用程序。您应该会看到一个简单的网页应用程序,其中包含文本和一个每次刷新时都会增加的计数器。
在终端中按下 ctrl+c 来停止你的应用程序。
验证数据在数据库中持久化
在终端中,运行 docker compose rm 以移除您的容器,然后运行 docker compose up 以再次运行您的应用程序。
$ docker compose rm
$ docker compose up --build
刷新 http://localhost:9000/database.php 在你的浏览器中,并验证之前的计数是否仍然存在。如果没有卷,数据库数据在你移除容器后将不会持久化。
在终端中按下 ctrl+c 来停止你的应用程序。
添加 phpMyAdmin 以与数据库交互
你可以通过更新compose.yaml文件轻松地向你的应用程序堆栈添加服务。
更新您的compose.yaml以添加一个新的phpMyAdmin服务。更多详情,请参阅
phpMyAdmin官方Docker镜像。以下是更新后的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
打开
http://localhost:8080 在你的浏览器中以访问phpMyAdmin。使用root作为用户名和example作为密码登录。你现在可以通过phpMyAdmin与数据库进行交互。
在终端中按下 ctrl+c 来停止你的应用程序。
自动更新服务
使用Compose Watch在编辑和保存代码时自动更新正在运行的Compose服务。有关Compose Watch的更多详细信息,请参阅 使用Compose Watch。
在IDE或文本编辑器中打开你的compose.yaml文件,然后添加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
打开浏览器并验证应用程序是否在 http://localhost:9000/hello.php运行。
现在,您本地机器上应用程序源文件的任何更改将立即反映在运行的容器中。
在IDE或文本编辑器中打开hello.php,并将字符串Hello, world!更新为Hello, Docker!。
将更改保存到hello.php,然后等待几秒钟让应用程序同步。刷新
http://localhost:9000/hello.php 在您的浏览器中,并验证更新的文本是否出现。
在终端中按下ctrl+c以停止Compose Watch。在终端中运行docker compose down以停止应用程序。
创建一个开发容器
此时,当你运行容器化应用程序时,Composer 不会安装开发依赖项。虽然这个小镜像适合生产环境,但它缺少开发和测试时可能需要的工具和依赖项,并且不包括 tests 目录。你可以使用多阶段构建在同一个 Dockerfile 中为开发和生产构建阶段。更多详情,请参见
多阶段构建。
在Dockerfile中,您需要更新以下内容:
- 将
deps阶段分为两个阶段。一个阶段用于生产环境(prod-deps),另一个阶段(dev-deps)用于安装开发依赖。 - 创建一个通用的
base阶段。 - 为开发创建一个新的
development阶段。 - 更新
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
打开浏览器并在 http://localhost:9000/hello.php查看应用程序。您应该仍然会看到简单的“Hello, Docker!”应用程序。
在终端中按下 ctrl+c 来停止你的应用程序。
虽然应用程序看起来相同,但您现在可以使用开发依赖项。继续下一节,了解如何使用 Docker 运行测试。
摘要
在本节中,您了解了如何设置Compose文件以添加本地数据库并持久化数据。您还学习了如何使用Compose Watch在更新代码时自动同步应用程序。最后,您学习了如何创建一个包含开发所需依赖项的开发容器。
相关信息:
下一步
在下一节中,您将学习如何使用Docker运行单元测试。