はじめに
案件はオンプレかAWSだったりの現場作業なので、触る機会があまりありませんでした。
個人開発でWordPressのローカル環境が必要になって、VMの既存イメージから立ち上げ手間かかるし、いろいろライブラリやアプリケーション入れたくなっちゃうし、サクッとできる方法ないかなーと、ふと今までご縁のなかったDockerを使うことにしました。
とりあえずこれだけ覚えておけば現場でもOK
インストールは割愛。
Dockerインストールマニュフェスト
docker-compose.yml
でインストールしたいコンテナの情報を記載
以下WordPress立ち上げてみる。自分なりに何か調べてコメント記載した。
# Docker Composeのバージョン指定
version: '3'
# サービス(コンテナ)の定義
services:
# MySQLデータベースコンテナ
db:
# 使用するDockerイメージ(MySQL 8.0)
image: mysql:8.0
# ボリューム(データ永続化)
volumes:
# 名前付きボリューム db_data を /var/lib/mysql にマウント
# MySQLのデータベースファイルが保存される場所
# downしてもデータは残る
- db_data:/var/lib/mysql
# コンテナが停止したら自動で再起動
restart: always
# 環境変数(MySQLの設定)
environment:
# MySQLのrootパスワード
MYSQL_ROOT_PASSWORD: rootpassword
# 作成するデータベース名
MYSQL_DATABASE: wordpress
# WordPressが使うMySQLユーザー名
MYSQL_USER: wordpress
# WordPressが使うMySQLパスワード
MYSQL_PASSWORD: wordpress
# WordPressコンテナ
wordpress:
# dbコンテナが起動してから起動する
depends_on:
- db
# 使用するDockerイメージ(WordPress最新版)
image: wordpress:latest
# ポートマッピング(ホスト:コンテナ)
ports:
# ホストの8080番ポートをコンテナの80番ポートに転送
# http://192.168.184.129:8080 でアクセス可能
- "8080:80"
# コンテナが停止したら自動で再起動
restart: always
# 環境変数(WordPress→MySQL接続設定)
environment:
# MySQLサーバーのアドレス(サービス名:ポート)
WORDPRESS_DB_HOST: db:3306
# MySQLユーザー名(上のMYSQL_USERと同じ)
WORDPRESS_DB_USER: wordpress
# MySQLパスワード(上のMYSQL_PASSWORDと同じ)
WORDPRESS_DB_PASSWORD: wordpress
# 使用するデータベース名(上のMYSQL_DATABASEと同じ)
WORDPRESS_DB_NAME: wordpress
# ボリューム(ファイル共有)
volumes:
# ホストの ./wp-content を コンテナの /var/www/html/wp-content にマウント
# ホスト: /home/kohaku/wordpress/wp-content/
# コンテナ: /var/www/html/wp-content/
# テーマ、プラグイン、アップロードファイルがここに保存される
# 双方向リアルタイム同期、downしても残る
- ./wp-content:/var/www/html/wp-content
# 名前付きボリュームの定義
volumes:
# MySQLデータ用の永続ボリューム
# Docker管理下の領域に保存される
# down しても残る、down -v で削除される
db_data:2・
基本操作(最重要)
起動(バックグラウンド)
docker-compose up -d停止
docker-compose stop停止+コンテナ削除(データは消えない)
docker-compose down完全削除(コンテナ+ネットワーク+イメージキャッシュ)
※永続化していないデータは消えるので注意
docker-compose down --rmi all --volumes --remove-orphansコンテナ状態確認
実行中コンテナ一覧
docker ps全コンテナ一覧(停止中含む)
docker ps -aWordPressコンテナで作業したいとき
シェルに入る(bash)
docker-compose exec wordpress bashWP-CLI を使う例
docker-compose exec wordpress wp plugin listdocker-compose exec wordpress ls -ladocker-compose exeはリモートコマンド実行みたいな認識でよい
MySQLコンテナに入る
MySQL の中に入る(root)
docker-compose exec db mysql -u root -pデータベース一覧
show databases;ログを見る
WordPressのログ(Apache)
docker-compose logs -f wordpressMySQL のログ
docker-compose logs -f dbコンテナを再構築したいとき
イメージを再ビルド
docker-compose build再起動(停止 → 起動)
docker-compose restart不要な Docker 資源をまとめて掃除
使っていないコンテナ・ネットワーク・イメージを削除
docker system pruneさらに volume も削除(危険)
docker system prune -a --volumesバックアップ関連
ホスト側の WordPress ディレクトリを zip化
(例)
zip -r wp-backup.zip ./wpMySQL ダンプ
docker-compose exec db mysqldump -u root -p wordpress > backup.sql「よくある誤解 → 正しい理解」まとめ
❌ 誤解①:コンテナ内で変更すれば全部残る
✔ 正しい理解
「マウントした場所だけ残り、その他はコンテナ削除(down)で全部消える」。
❌ 誤解②:コンテナは“サーバー本体”だと思っていた
✔ 正しい理解
コンテナは“使い捨ての実行箱”。本体はイメージ(テンプレ)。
❌ 誤解③:docker-compose down は“停止するだけ”だと思っていた
✔ 正しい理解
down は停止+破壊(コンテナの OS 層を消す)まで行う。
❌ 誤解④:コンテナは仮想マシン(VM)と同じ
✔ 正しい理解
コンテナは OS を丸ごと仮想化しない。プロセスを隔離して動かしているだけ。軽量で高速。
安定版
version: "3.9"
services:
asset-build:
image: node:20-alpine
working_dir: /app
volumes:
- .:/app
command: sh /app/build-assets.sh
db:
image: mysql:8.0
container_name: wp-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
volumes:
- db_data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
ports:
- "3300:3306"
networks:
- wordpress-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpassword"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
command:
- --default-authentication-plugin=mysql_native_password
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --max_allowed_packet=256M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
wordpress:
depends_on:
db:
condition: service_healthy
#image: wordpress:latest
build: .
container_name: wp-main
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_DEBUG: true
WORDPRESS_CONFIG_EXTRA: |
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
define('DISABLE_WP_CRON', false);
define('AUTOMATIC_UPDATER_DISABLED', false);
volumes:
- ./wp:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
ports:
- "8080:80"
networks:
- wordpress-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/wp-admin/install.php"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
wpcli:
image: wordpress:cli
container_name: wp-cli
depends_on:
- wordpress
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
MYSQL_SSL_MODE: DISABLED
volumes:
- ./wp:/var/www/html
working_dir: /var/www/html
networks:
- wordpress-network
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: wp-pma
restart: always
depends_on:
db:
condition: service_healthy
environment:
PMA_HOST: db
PMA_PORT: 3306
PMA_USER: root
PMA_PASSWORD: rootpassword
UPLOAD_LIMIT: 256M
MEMORY_LIMIT: 512M
MAX_EXECUTION_TIME: 600
ports:
- "8081:80"
networks:
- wordpress-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# バックアップサービス(オプション)
backup:
image: fradelg/mysql-cron-backup:latest
container_name: wp-backup
restart: always
depends_on:
db:
condition: service_healthy
environment:
MYSQL_HOST: db
MYSQL_USER: root
MYSQL_PASS: rootpassword
MYSQL_DATABASE: wordpress
CRON_TIME: "0 2 * * *"
MAX_BACKUPS: 7
INIT_BACKUP: 0
GZIP_LEVEL: 9
volumes:
- ./backups:/backup
networks:
- wordpress-network
volumes:
db_data:
driver: local
driver_opts:
type: none
o: bind
device: ./mysql-data
networks:
wordpress-network:
driver: bridgephpunitが使えるよう #image: wordpress:latest コメントアウト。wordpress:latest は本番実行用イメージで、phpunit や composer が入っていない。テスト用途(WordPress公式テスト構成)を想定していない。そのため phpunit は phar 直実行か、テスト用に拡張したイメージが必要。
phpunitテストするときは以下のようにやるとテスト可能。xxxxxxxxは作っているプラグイン名。
docker compose run --rm wpcli sh -c '
curl -Ls https://phar.phpunit.de/phpunit-9.phar -o /tmp/phpunit &&
cd wp-content/plugins/xxxxxxxx &&
php /tmp/phpunit --do-not-cache-result -c phpunit.xml.dist
'wp-conten/plugins/xxxxxxxx/phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php" colors="true" verbose="true">
<testsuites>
<testsuite name="Plugin Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>wp-conten/plugins/xxxxxxxx/tests/bootstrap.php
<?php
// --------------------------------------
// テスト時のみ rate limit 無効化 <- 作っているプラグインのオプション設定とかここに記載
// --------------------------------------
define( 'AIGB_DISABLE_RATE_LIMIT', true );
// --------------------------------------
// WordPress 本体を読み込む
// (Docker内の実体)
// --------------------------------------
require_once dirname( __DIR__, 4 ) . '/wp-load.php';
// プラグイン本体を明示ロード
require_once dirname( __DIR__ ) . '/xxxxxxxx.php';
XXXXXXXX_Controller_Test.php
<?php
/**
* XXXXXXXX Controller Permission Tests
*
* @package XXXXXXXX
*/
use PHPUnit\Framework\TestCase;
class XXXXXXXX_Controller_Test extends TestCase {
protected function setUp(): void {
parent::setUp();
// 初期化書いていく
}
protected function tearDown(): void {
// 終了処理書いていく
parent::tearDown();
}
// 以降テストケース書いていくファイル名、クラス名ともに末尾 _TEST でした。TestCaseを継承。別の方法で、定義テストしようとしたら動かなかったんよね。
build-assets.shは、js&cssのminify実行用
#!/bin/sh
set -e
echo "== install tools =="
npm install -g postcss postcss-cli cssnano terser
CSS_DIR="wp/wp-content/plugins/xxxxxxxx/public/css"
JS_DIR="wp/wp-content/plugins/xxxxxxxx/public/js"
echo "== CSS minify =="
for f in "$CSS_DIR"/*.css; do
case "$f" in
*.min.css) continue ;;
esac
out="$(echo "$f" | sed 's/\.css$/.min.css/')"
echo " $f -> $out"
postcss "$f" -o "$out" -u cssnano
done
echo "== JS minify =="
for f in "$JS_DIR"/*.js; do
case "$f" in
*.min.js) continue ;;
esac
out="$(echo "$f" | sed 's/\.js$/.min.js/')"
echo " $f -> $out"
terser "$f" --compress --mangle --output "$out"
done
echo "== done =="んー、設定面倒くさいけど、構築爆速だから良いね。
mysqladminは使ってないけどポート変えて動くのかとか検証してみた。
テストもできるようになったので、安心安心安心!
おわりに
マウントしたアンマウントしたりは上書きの原因になるの注意。
今度はイメージ拡張とかトライしてみようと思います。
直近でAWSもそうだけど、サーバーレスの動きも定着しつつ、データ運用、アプリケーション対応に重要の比重が増し
もうサーバー設定ごにょごにょする時代は終りをむかえてきたのだよ。
その内、サーバの概念もアプリケーション概念もAIにより急速にわかっていくだろう。今そうなってるから。
ゲーム制作全然進んでないよ。
