使用容器進行 PHP 開發

先決條件

完成容器化 PHP 應用程式

概述

在本節中,你將學習如何為容器化應用程式設定開發環境。這包括:

  • 新增本地資料庫並持久化資料
  • 新增 phpMyAdmin 與資料庫互動
  • 配置 Compose 以在你編輯和儲存程式碼時自動更新正在執行的 Compose 服務
  • 建立一個包含開發依賴項的開發容器

新增本地資料庫並持久化資料

你可以使用容器來設定本地服務,例如資料庫。要為示例應用程式執行此操作,你需要執行以下步驟:

  • 更新 Dockerfile 以安裝連線到資料庫的擴充套件
  • 更新 compose.yaml 檔案以新增資料庫服務和捲來持久化資料

更新 Dockerfile 以安裝擴充套件

要安裝 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 擴充套件的更多詳細資訊,請參閱PHP 官方 Docker 映象

更新 compose.yaml 檔案以新增資料庫並持久化資料

在 IDE 或文字編輯器中開啟 compose.yaml 檔案。你會注意到它已經包含 PostgreSQL 資料庫和卷的註釋掉的說明。對於此應用程式,你將使用 MariaDB。有關 MariaDB 的更多詳細資訊,請參閱MariaDB 官方 Docker 映象

在 IDE 或文字編輯器中開啟 src/database.php 檔案。你會注意到它讀取環境變數以連線到資料庫。

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 執行應用程式之前,請注意此 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

開啟瀏覽器,在以下地址檢視應用程式:https://:9000/database.php。你應該會看到一個簡單的 Web 應用程式,其中包含文字和一個每次重新整理時都會遞增的計數器。

在終端中按 ctrl+c 停止你的應用程式。

驗證資料在資料庫中持久化

在終端中,執行 docker compose rm 刪除你的容器,然後執行 docker compose up 再次執行你的應用程式。

$ docker compose rm
$ docker compose up --build

在瀏覽器中重新整理https://: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

開啟https://: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

開啟瀏覽器並驗證應用程式是否正在以下地址執行:https://:9000/hello.php

現在,對本地機器上應用程式原始檔的任何更改都將立即反映在正在執行的容器中。

在 IDE 或文字編輯器中開啟 hello.php,並將字串 Hello, world! 更新為 Hello, Docker!

儲存對 hello.php 的更改,然後等待幾秒鐘讓應用程式同步。在瀏覽器中重新整理https://:9000/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

開啟瀏覽器,在以下地址檢視應用程式:https://:9000/hello.php。你應該仍然看到簡單的“Hello, Docker!”應用程式。

在終端中按 ctrl+c 停止你的應用程式。

雖然應用程式看起來相同,但你現在可以使用開發依賴項了。繼續下一節,瞭解如何使用 Docker 執行測試。

總結

在本節中,你瞭解瞭如何設定 Compose 檔案以新增本地資料庫並持久化資料。你還學習瞭如何使用 Compose Watch 在更新程式碼時自動同步應用程式。最後,你學習瞭如何建立一個包含開發所需依賴項的開發容器。

相關資訊

後續步驟

在下一節中,你將學習如何使用 Docker 執行單元測試。

頁面選項