0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

公式 WordPress Docker で 自作テーマ・プラグイン以外を git 管理外にしつつ快適に開発する(+ Claude Code 対応)

0
Last updated at Posted at 2026-06-08

サマリ

既存の WordPress サイトを、AI エージェントを利用しつつ安全に修正できるように、下記の構成を組んでみました。

構成は 自作テーマ・プラグイン git 管理 / wp-content 全体は repo に置くが git 外 / WordPress 本体は公式 Docker image に任せる + UID 整合 + dev container 内 Claude Code です。本記事はその 構成全体 をまとめます。

設計判断・思想は別記事(末尾の関連記事)に書きました。

  • Docker の bind mount は wp-content だけ、WordPress 本体は公式 WordPress Docker image を利用する
  • wp-config.php.htaccess は read-only bind で永続化
  • www-data の UID を build 時にホスト UID へ揃え、パーミッションを統一する
  • .vscode/settings.jsonintelephense.environment.includePaths にコンテナ内パスを渡し、ホストに WordPress 本体のソースを置かずにエディタのコードサポートを使用可能に
  • Dockerfile に INSTALL_CLAUDE build arg を入れて、dev container 内に Claude Code を同梱

実現したこと

構成を組んでみて、結果として以下が手に入りました。

  • テーマ・プラグインの「自分が書いたコード」だけ追跡されるgit status に出るのは wp-content/themes/mytheme/ 配下だけ。本体や uploads は除外し、純粋に自分のコードだけが履歴に残ります。
  • WordPress 本体のバージョン更新が image タグの変更だけで済むdocker-compose.ymlimage: wordpress:6.9-php8.4-apache のタグを切り替えて、コンテナと匿名ボリュームを破棄するだけ。
  • wp-content の中身を本番から持ってこれる.gitignore がリポジトリルートに集約してあるので、本番サーバから wp-content/ を持ってきて差し替えても ignore ルールが上書きで消えない
  • VS Code から WordPress 本体関数の実装に飛べる — ホスト側のリポ(ワークスペース)には WordPress コアが無いのに、エディタからは見えている状態。Intelephense にコンテナ内 /var/www/html/wp-admin, /var/www/html/wp-includesincludePaths として渡している。
  • UID 整合で bind mount の権限事故が起きないwww-data の UID を Docker ホストの UID に揃えるよう build しているので、bind mount したファイルの所有権が一致。Apache / Claude Code / VS Code どれがファイルを書いても権限の食い違いが起きない
  • Claude Code を container 内で動かせるINSTALL_CLAUDE=true の build arg で Dockerfile が claude を container 内にインストール。.claude/ は named volume で永続化。Docker 内の隔離環境で安全に AI エージェントを利用できる。

構成のあらまし

詳細は派生記事に記載しましたので、要点のみです。

ディレクトリ構成

repo-root/
├── .gitignore                  ← 自作テーマ・プラグインのみ追跡
├── .vscode/
│   └── settings.json           ← Intelephense の設定
├── docker-compose.yml
├── Dockerfile                  ← UID 整合 + Claude Code 同梱
├── docker/
│   └── wp/
│       ├── wp-config.php       ← bind 用ローカル wp-config (Read Only)
│       └── .htaccess           ← bind 用ローカル .htaccess (Read Only)
├── wordpress/                  ← repo 内には置くが git 管理対象は wp-content/themes/mytheme/ のみ
│   └── wp-content/
│       ├── themes/
│       │   └── mytheme/        ← 自作テーマ(git 管理)
│       ├── plugins/            ← 本番から コピー(gitignored)
│       └── uploads/            ← 本番から コピー(gitignored)
└── .devcontainer/
    ├── devcontainer.json
    └── docker-compose.yml      ← devcontainer 用

docker-compose.yml の要点

一部抜粋、全文は下記付録に掲載しています

services:
  wp:
    build:
      context: .
      args:
        USER_UID: '${UID:-1000}'
        USER_GID: '${GID:-1000}'
        INSTALL_CLAUDE: "false"
    ports:
      - "8080:80"
    volumes:
      - ./wordpress/wp-content:/var/www/html/wp-content
      - ./docker/wp/wp-config.php:/var/www/html/wp-config.php:ro
      - ./docker/wp/.htaccess:/var/www/html/.htaccess:ro
    depends_on:
      db:
        condition: service_healthy
  • bind mount は wp-content のみ — コア(wp-admin/ wp-includes/)は Docker WordPress image のものを利用
  • wp-config.php.htaccess は read-only bind — ローカル専用の設定(DB 接続先や WP_DEBUG 等)を永続化
  • UID は build arg でホスト UID に合わせる

Dockerfile の要点

UID 整合と Claude Code 同梱の部分だけ抜粋、全文は下記付録に掲載しています:

FROM wordpress:6.9-php8.4-apache

# WordPress 本体は image 由来
# www-data の UID をホストに揃える
ARG USER_UID=1000
ARG USER_GID=1000
RUN groupmod --non-unique -g ${USER_GID} www-data \
 && usermod  --non-unique -u ${USER_UID} -d /home/www-data -s /bin/bash www-data \
 && mkdir -p /home/www-data/.claude /home/www-data/.config/gh \
 && chown -R www-data:www-data /var/www /home/www-data

# Claude Code を container 内にインストール(dev container 用)
ARG INSTALL_CLAUDE=false
RUN if [ "$INSTALL_CLAUDE" = "true" ]; then \
        curl -fsSL https://claude.ai/install.sh -o /tmp/claude-install.sh && \
        su www-data -c "bash /tmp/claude-install.sh" && \
        rm /tmp/claude-install.sh; \
    fi

公式 image の ENTRYPOINT(= docker-entrypoint.sh) と CMD(= apache2-foreground)はそのまま。手を加えるのは UID と Claude のインストールだけ、というシンプルな拡張です。

.gitignore の方針

自作テーマだけ追跡するホワイトリスト方式:

/wordpress/wp-content/themes/*
!/wordpress/wp-content/themes/index.php
!/wordpress/wp-content/themes/mytheme/

.gitignore の詳細は以下の派生記事にまとめました。

WordPress サイトの .gitignore レシピ — 自作テーマ・プラグインだけ git 管理するパターン

Intelephense の設定

{
  "intelephense.environment.includePaths": [
    "/var/www/html/wp-admin",
    "/var/www/html/wp-includes"
  ]
}

詳細は以下の派生記事にまとめています。

ワークスペースに WordPress 本体が無くても VS Code の PHP 補完を効かせる — dev container × Intelephense

entrypoint の挙動

UID 整合の取り扱いを考えていた当初、docker-entrypoint.sh 内に wp-content の中身を tar --exclude で保護しつつコアを流し込む処理 があるのを見つけ、これを活用できないか試してみました。

結果はうまくいかず、関連の GitHub Issue / Discussion を調べたところ、これは Kubernetes 等の永続ストレージ運用や bind mount で永続化された /var/www/html とコアの配布を両立させる merge ロジック(末尾 参考[1][2])で、本構成には合わないと分かりました。

UID 整合は build 時の groupmod / usermod で完結させています。

まとめ

  • WordPress を「自作テーマ・プラグインだけ git 管理、WordPress 本体は公式 image 任せ、wp-content は repo に置くが git 外」という構成にしたところ、快適な開発環境になりました。
  • UID 整合と Claude Code 同梱で、AI エージェントを安全に同居させる開発環境ができる
  • VS Code Intelephense にコンテナ内パスを includePaths で渡せば、ホスト側に WordPress 本体を置かずに実装ジャンプできる
  • 開発環境を Docker 内 dev container として動かしているので、AI エージェントを使っても怖くない
  • AI エージェントに WordPress 本体のコードも参照させたい場合は、コンテナ内の /var/www/html 配下を読みに行くよう指示してください

ニッチな構成ですが、似たような要件(WordPress で自作テーマ・プラグインを作成している、AI と協業したい)の人にとっては落としどころとして参考になるかもしれません。もし、より良い方法をご存じでしたら教えていただけますと幸いです。

関連記事

「なぜこの構成にしたか」「気づき」など設計判断の論考は別記事にまとめました。

WordPress の AI コーディングエージェント開発を安全に利用する Docker 環境構築 — 設計ノート

付録: 設定ファイル全文

本文中では要点だけを抜粋しましたので、ここに全文を掲載します。コピペで使うときの参考にどうぞ。

掲載する 4 ファイル:

  • docker-compose.yml — 基本構成(wp / db)
  • Dockerfile — image のビルド定義
  • .devcontainer/devcontainer.json — VS Code Dev Container 用の設定
  • .devcontainer/docker-compose.yml — devcontainer 用 override(INSTALL_CLAUDE: "true".claude / gh 設定の永続化)

docker-compose.yml

services:
  wp:
    build:
      context: .
      args:
        INSTALL_CLAUDE: "false"
        # host uid/gid に www-data を揃える。WSL の id が 1000:1000 と違う
        # 環境では .env で UID / GID を設定してから docker compose build。
        USER_UID: '${UID:-1000}'
        USER_GID: '${GID:-1000}'
    ports:
      - "8080:80"
    environment:
      # 必要に応じて .env で上書きしてください
      WORDPRESS_DB_HOST:      '${WORDPRESS_DB_HOST:-db}'
      WORDPRESS_DB_USER:      '${WORDPRESS_DB_USER:-wpuser}'
      WORDPRESS_DB_PASSWORD:  '${WORDPRESS_DB_PASSWORD:-dummy}'
      WORDPRESS_DB_NAME:      '${WORDPRESS_DB_NAME:-wp}'
      WORDPRESS_TABLE_PREFIX: '${WORDPRESS_TABLE_PREFIX:-wp_}'
      WORDPRESS_DEBUG:        '${WORDPRESS_DEBUG:-1}'
    volumes:
      - ./wordpress/wp-content:/var/www/html/wp-content
      # ローカル専用 .htaccess (Read Only)
      - ./docker/wp/.htaccess:/var/www/html/.htaccess:ro
      # ローカル専用 wp-config.php  (Read Only)
      - ./docker/wp/wp-config.php:/var/www/html/wp-config.php:ro
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.4
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      # wp 側と同じ ${VAR:-default} を共有して、.env で片方変えると両方追従する
      MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD:-root}'
      MYSQL_DATABASE:      '${WORDPRESS_DB_NAME:-wp}'
      MYSQL_USER:          '${WORDPRESS_DB_USER:-wpuser}'
      MYSQL_PASSWORD:      '${WORDPRESS_DB_PASSWORD:-dummy}'
    volumes:
      - db-data:/var/lib/mysql
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -h localhost -uroot -p$$MYSQL_ROOT_PASSWORD --silent"]
      interval: 5s
      retries: 20
      start_period: 30s

volumes:
  db-data:

Dockerfile

FROM wordpress:6.9-php8.4-apache

# dev container として使うときに重宝する道具一式と、GitHub CLI(公式の apt repository を経由)。
# 好みで足し引きしてください。
RUN apt-get update && apt-get install -y --no-install-recommends \
        nano less vim-tiny \
        git ssh wget curl gnupg ca-certificates \
        jq ripgrep procps rsync \
        default-mysql-client \
    && install -dm 755 /etc/apt/keyrings \
    && curl -fsSL -o /etc/apt/keyrings/githubcli-archive-keyring.gpg https://cli.github.com/packages/githubcli-archive-keyring.gpg \
    && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
         > /etc/apt/sources.list.d/github-cli.list \
    && apt-get update \
    && apt-get install -y --no-install-recommends gh \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# WP-CLI: バージョン固定
ARG WP_CLI_VERSION=2.12.0
ARG WP_CLI_SHA256=ce34ddd838f7351d6759068d09793f26755463b4a4610a5a5c0a97b68220d85c
RUN curl -fsSL -o /usr/local/bin/wp \
        "https://github.com/wp-cli/wp-cli/releases/download/v${WP_CLI_VERSION}/wp-cli-${WP_CLI_VERSION}.phar" \
    && echo "${WP_CLI_SHA256}  /usr/local/bin/wp" | sha256sum -c - \
    && chmod +x /usr/local/bin/wp

# www-data の UID をホストに揃える
ARG USER_UID=1000
ARG USER_GID=1000
RUN groupmod --non-unique -g ${USER_GID} www-data \
    && usermod --non-unique -u ${USER_UID} -d /home/www-data -s /bin/bash www-data \
    && mkdir -p /home/www-data/.claude /home/www-data/.config/gh \
    && chown -R www-data:www-data /var/www /home/www-data

ARG INSTALL_CLAUDE=false
RUN if [ "$INSTALL_CLAUDE" = "true" ]; then \
        curl -fsSL https://claude.ai/install.sh -o /tmp/claude-install.sh && \
        su www-data -c "bash /tmp/claude-install.sh" && \
        rm /tmp/claude-install.sh; \
    fi
ENV PATH="/home/www-data/.local/bin:$PATH"

.devcontainer/devcontainer.json

{
  "name": "wordpress-local",

  "dockerComposeFile": [
    "../docker-compose.yml",
    "docker-compose.yml"
  ],

  "service": "wp",
  "workspaceFolder": "/workspaces/wordpress-local",

  "customizations": {
    "vscode": {
      "extensions": [
        "Anthropic.claude-code",
        "bmewburn.vscode-intelephense-client"
      ]
    }
  },

  "remoteUser": "www-data"
}

.devcontainer/docker-compose.yml

dev container 用の追加設定。INSTALL_CLAUDE: "true" で Claude Code を image に同梱、リポをワークスペースディレクトリ /workspaces/wordpress-local に bind、.claudegh の config を named volume に永続化しています。

services:
  wp:
    build:
      args:
        INSTALL_CLAUDE: "true"
    volumes:
      - .:/workspaces/wordpress-local
      - claude-config:/home/www-data/.claude
      - gh-config:/home/www-data/.config/gh

volumes:
  claude-config:
  gh-config:

参考

  1. docker-library/wordpress Discussion #623 — Custom theme / plugins running on Kuberneteshttps://github.com/docker-library/wordpress/discussions/623 / 公式 image の wp-content merge ロジックが Kubernetes PVC・bind mount 永続化シナリオでどう機能するかの議論
  2. docker-library/wordpress Issue #506 — "wp-content" persisted, "akismet" updated, container restarted, "akismet" downgradedhttps://github.com/docker-library/wordpress/issues/506 / entrypoint が wp-content 配下を tar --exclude するようになった経緯
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?