リアルタイム反映!Dockerを使ったWordPressの効率的な開発環境構築
はじめに
WordPressの開発環境を効率的に管理するために、Dockerを利用した環境構築方法を紹介します。このガイドでは、ファイルの編集、SCSSやTypeScriptのバンドル、データベースの同期、デプロイの手順を詳しく説明します。
目的
1. FTPでファイルを一つずつ編集する非効率さを解消
FTPでファイルを手動でアップロードして編集するのは時間がかかります。
この環境を使えば、もっと簡単にファイル管理ができます。
2. SCSSやimg、TSファイルをバンドル
スタイルや画像、TypeScriptファイルを効率よくまとめて管理します。
Gulpを使って、これらを自動的にバンドルします。
3. バンドルされたデータをリアルタイムで反映
変更した内容が即座にバンドルされます。
生成したデータはブラウザの再読み込みを介さずリアルタイムで反映されます。
この環境では、Gulpを使って、ファイルの変更を監視します。
4. WordPressの開発効率を向上
開発環境を整えることで、WordPressのテーマやプラグインの開発がスムーズになります。
5. 開発環境で編集したデータベースを本番環境に反映
開発環境で作業したデータベースの内容を本番環境に同期します。
本番環境と開発環境のデータベース同期を容易にします。
6. 本番環境を直接操作せず、Nodeやnpmのバージョン管理を簡素化
本番環境を直接触らずに、Dockerを使って環境を管理します。
Nodeやnpmのバージョン管理もDockerで一元管理するため、ローカルの開発環境に依存したバグを防ぐことができます。
開発環境の構成
.
├── .cz-config.cjs
├── .env
├── .env.example
├── .github
│ └── workflows
├── .gitignore
├── .husky
├── Makefile
├── README.md
├── build
├── docker
│ ├── app
│ ├── browsersync
│ └── mysql
├── docker-compose.init.yml
├── docker-compose.yml
├── package.json
├── pnpm-lock.yaml
├── scripts
│ ├── export_all.sh
│ ├── export_db.sh
│ ├── export_src.sh
│ └── functions.sh
├── src
│ ├── assets
│ ├── gulpfile.js
│ ├── package.json
│ ├── plugins
│ ├── rollup.config.js
│ ├── themes
│ ├── tsconfig.json
│ └── uploads
└── wordpress
使用ツールと技術
- Docker
- WordPress
- Gulp
- PHP
- Apache
- Node.js
- MariaDB
- Husky
- phpMyAdmin
- SCSS
- TypeScript
- Github actions
環境構築手順
1. 環境変数の設定
env.example
を基に.env
ファイルを作成します。
# -------------------------------------------
# Wordpress
# -------------------------------------------
WP_VERSION=
# -------------------------------------------
# Mysql
# -------------------------------------------
MYSQL_DATABASE=
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_ROOT_PASSWORD=
MYSQL_HOST=
2. 初期セットアップ
初めて環境を構築する場合は、以下の手順を実行します。
make init
http://localhost
にアクセスし、WordPressの初期設定を行います。完了後、コンテナを停止します。
make down
3. 既存プロジェクトの移行
src
フォルダに既存のWordPress関連ファイルを配置します。
データベースを本番環境と同期させる場合は、ダンプファイルをdocker/mysql/initdb
に配置します。
make prepare
再びコンテナを起動します。
make down
了解しました。それでは、「デプロイについて」セクションを手動と自動で分け、開発環境構築の手順と処理の内容を分けて説明します。
4. デプロイについて
手動デプロイ
手動でデプロイを行う場合の手順です。
-
scripts/export_all.sh
を実行し、build
フォルダにデプロイ情報を生成します。scripts/export_all.sh
- WordPressのみデプロイする場合は、
scripts/export_src.sh
を実行します。scripts/export_src.sh
- データベースのみデプロイする場合は、
scripts/export_db.sh
を実行します。scripts/export_db.sh
処理内容
-
export_all.sh
: データベースとWordPressのファイルをエクスポートします。#!/bin/bash current_path="`dirname \"$0\"`" sh "$current_path/export_db.sh" sh "$current_path/export_src.sh"
-
export_src.sh
: WordPressのファイルをエクスポートします。#!/bin/bash current_path="$(dirname "$0")" source "$current_path/functions.sh" # .envファイルを読み込む if [ -f "$current_path/../.env" ]; then export $(cat "$current_path/../.env" | grep -v '#' | awk '/=/ {print $1}') fi # コンテナが手動で起動されたかどうか container_manually_started=false # 環境変数からWordPressのイメージバージョンを取得 WP_VERSION=${WP_VERSION:-latest} image_name="wordpress:$WP_VERSION" service_name="wordpress" # ビルドディレクトリが存在することを確認 create_build_directory echo "WordPressファイルをエクスポート中" # コンテナが起動していない場合は起動 start_container_if_not_started "$service_name" # 指定されたイメージからコンテナ名を取得 container_id=$(get_container_id $service_name) # デバッグ用のログを追加 echo "デバッグ情報:" echo "コンテナID: $container_id" echo "サービス名: $service_name" if [ -z "$container_id" ]; then echo "コンテナが見つかりません。コピーをスキップします。" exit 1 fi echo "Building src files..." # Browsersyncサービスを起動し、最適化設定でGulpビルドを実行 docker-compose run -e NODE_ENV=production browsersync node_modules/.bin/gulp build # DockerのCOPYメソッドを使用して、WordPressコンテナ内のファイルをホストマシンにコピー docker cp $container_id:/var/www/html/ ./build # ファイルのエクスポートが成功したことを通知 echo "ファイルのエクスポートに成功" # コンテナが手動で起動された場合、コンテナを停止 if [ "$container_manually_started" = true ] ; then docker-compose stop "$service_name" > /dev/null docker-compose stop db > /dev/null fi
-
export_db.sh
: データベースをエクスポートします。#!/bin/bash current_path="$(dirname "$0")" source "$current_path/functions.sh" # .envファイルを読み込む if [ -f "$current_path/../.env" ]; then export $(cat "$current_path/../.env" | grep -v '#' | awk '/=/ {print $1}') fi # コンテナが手動で起動されたか、すでに起動されていたかどうか container_manually_started=false service_name="db" # ビルドディレクトリが存在することを確認 create_build_directory echo "データベースのエクスポートが完了するまでお待ちください..."; # コンテナが起動していない場合は起動 start_container_if_not_started "$service_name" # コンテナ名を取得 container_id=$(get_container_id $service_name) # MYSQLデータベースをエクスポートするコマンドを実行し、ホストマシンにコピー docker exec "$container_id" bash -c "mysqldump -h'$MYSQL_HOST' -u'$MYSQL_USER' -p'$MYSQL_PASSWORD' '$MYSQL_DATABASE' > /db.sql" || { echo "データベースのエクスポート中にエラーが発生しました" exit 1 } docker cp $container_id:/db.sql ./build/db.sql echo "データベースが正常にコピーされました。" # コンテナが手動で起動された場合は停止 if [ "$container_manually_started" = true ] ; then docker-compose stop "$service_name" > /dev/null fi
自動デプロイ
自動でデプロイを行う場合の手順です。
- GitHub Actionsを使用して、自動デプロイを設定します。
- mainブランチが更新されると自動でデプロイされます。
処理内容
-
.github/workflows/deploy.yml
:## .github/workflows/deploy.yml name: Deploy to FTP on: workflow_dispatch: push: branches: - main jobs: deploy: name: DeployCoreServer runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Sync files uses: SamKirkland/FTP-Deploy-Action@v4.3.5 with: server: ${{ secrets.FTP_SERVER }} username: ${{ secrets.FTP_USERNAME }} password: ${{ secrets.FTP_PASSWORD }} server-dir: ${{ secrets.FTP_SERVER_DIR }} local-dir: ./src/
Makefileのコマンド
-
init
: 初期セットアップ -
prepare
: コンテナのビルドと起動 -
down
: コンテナの停止 -
build
: コンテナのビルド -
up
: コンテナの起動 -
ps
: コンテナのステータス確認 -
clear
: Dockerシステムのクリア -
logs
: 全てのコンテナのログを確認 -
logs-app
: アプリケーションコンテナのログを確認 -
logs-db
: データベースコンテナのログを確認
Gulpの設定
Gulpを使用してSCSS、img、TSファイルをバンドルします。以下はgulpfile.js
の内容です。
import browserSync from 'browser-sync';
import pkg from 'gulp';
const { src, dest, watch, series, parallel } = pkg;
import gulpif from 'gulp-if';
import plumber from 'gulp-plumber';
import notify from 'gulp-notify';
import imagemin from 'gulp-imagemin';
import mozjpeg from 'imagemin-mozjpeg';
import changed from 'gulp-changed';
import postcss from 'gulp-postcss';
import mqpacker from 'css-mqpacker';
import sortCSSmq from 'sort-css-media-queries';
import dartSass from 'sass';
import bulkSass from 'gulp-sass-glob-use-forward';
import gulpSass from 'gulp-sass';
const sass = gulpSass(dartSass);
import cleanCSS from 'gulp-clean-css';
import autoprefixer from 'autoprefixer';
import { rollup } from 'rollup';
import { deleteAsync } from 'del';
import path from 'path';
import minmax from 'postcss-media-minmax';
// Rollupの設定ファイル
import deploy from './rollup.config.js';
const paths = {
rootDir: 'dist',
styles: {
src: 'src/css/**/*.scss',
dest: 'dist/css',
},
scripts: {
src: 'src/js/**/*.{js,jsx,ts,tsx}',
dest: 'dist/js',
},
images: {
src: 'src/img/**/*.{jpg,jpeg,png,svg,gif}',
dest: 'dist/img',
},
dist: {},
};
// Browsersync <- Browsersyncによる再表示とローカルサーバー起動の設定
const server = browserSync.create();
const serve = (done) => {
server.init({
proxy: "wordpress",
port: 3000,
open: true,
notify: true
});
done();
};
const reload = (done) => {
server.reload();
done();
};
// Clean
const clean = () => {
return deleteAsync(['dist/**', '!dist']);
};
// SCSS
const styles = (done) => {
src(paths.styles.src)
.pipe(plumber({ errorHandler: notify.onError('Error: <%= error.message %>') }))
.pipe(bulkSass())
.pipe(sass.sync({ outputStyle: 'expanded' }))
.pipe(postcss([minmax(), autoprefixer(), mqpacker({ sort: sortCSSmq })]))
.pipe(gulpif(process.env.NODE_ENV === 'production', cleanCSS()))
.pipe(dest(paths.styles.dest))
.pipe(server.stream()); // CSSのホットリロード
done();
};
// Script
let rollupCache = null;
const scripts = async (done) => {
const bundle = await rollup({ ...deploy, cache: rollupCache });
rollupCache = bundle.cache;
await bundle.write(deploy.output);
done();
};
// Image
const Imagemin = (done) => {
src(paths.images.src)
.pipe(changed(paths.images.dest))
.pipe(imagemin([mozjpeg({ quality: 90 })]))
.pipe(dest(paths.images.dest));
done();
};
const watchFiles = () => {
watch(paths.scripts.src, series(scripts, reload)); // JavaScriptのホットリロード
watch(paths.styles.src, styles); // CSSのホットリロード
watch(paths.images.src, Imagemin); // 画像の変更を監視
watch(paths.styles.src).on('unlink', (filePath) => {
if (!/^_/.test(path.parse(filePath).name))
deleteAsync(filePath.replace(/src\/css/, paths.styles.dest).replace(/.scss$/, '.css'));
});
watch(paths.images.src).on('unlink', (filePath) => deleteAsync(filePath.replace(/src\/img/, paths.images.dest)));
watch(paths.images.src).on('change', (filePath) => deleteAsync(filePath.replace(/src\/img/, paths.images.dest)));
};
export const dist = series(parallel(styles, scripts, Imagemin));
export const dev = series(dist, serve, watchFiles);
export const production = series(dist, serve, watchFiles);
export const build = series(clean, dist);
export default dev;
デバッグとログ管理
デプロイに失敗した場合は、GitHub Secretのデータが正しく登録されているか確認します。ログの確認には以下のMakefileコマンドを使用します。
make logs
make logs-app
make logs-db
BrowserSyncの設定
開発環境で使用しているBrowserSyncの設定やホットリロードを実現するための手順は以下の通りです:
- データをバンドルし、バンドルしたデータはvolumeに保存される。
- volumeデータはWordPressのコンテナに同期される。
- BrowserSyncはファイルの変更を監視する。
- BrowserSyncのproxyにWordPressを設定する。
docker/browsersync/Dockerfile
FROM node:14
WORKDIR /var/www/html
# Copying our package.json containing all the necessary dependencies
COPY package.json /var/www/html/package.json
# Installing Gulp, BrowserSync and other necessary packages
RUN npm i
# Copy all the Gulp related files
COPY ./gulpfile.js ./gulpfile.js
COPY ./rollup.config.js ./rollup.config.js
COPY ./tsconfig.json ./tsconfig.json
# Exposing port 3000 for the page to be served via BrowserSync
EXPOSE 3000
# Exposing port 3001 for the admin console for BrowserSync
EXPOSE 3001
CMD ["npm run dev"]
まとめ
サーバー環境に合わせてDockerをセットアップするのは手間ですが、
編集のたびにFTPで接続する必要がなくなるのはいいですね!
Discussion