使用容器進行 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 映像檔

**注意**

要深入瞭解 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.phphttp://localhost:9000/hello.php建立開發容器

此時,當您執行容器化應用程式時,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

開啟瀏覽器並在 http://localhost:9000/hello.php摘要

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

相關資訊