はじめに
こんにちは、株式会社BuySell Technologies テクノロジー戦略本部 開発3部 Tech MK グループ(テックマーケティンググループ)の土屋です。 私は今年の8月1日から入社し、グループ会社である「株式会社タイムレス」の専属エンジニアとして、Webサイト制作全般を担当しております。 私が入社するまで、一部の運営サイトは前任者に委ねられていました。 しかし、私が入社したタイミングでは前任者の方は既に退職しており、手探りの中、Tech MK グループのメンバーによって保守・運用されている状況でした。
一人のエンジニアに依存していた状況を、チーム全体で効率的に運用できるようにすることが課題だったため、 属人化したWebサイト運用の問題を解消し、誰でも対応できる標準化された仕組みをこの3ヶ月間構築してきました。
- はじめに
- 理想と現状
- 問題(1):作業者によって環境が違うためバグの再現が難しかった。
- 問題(2):バージョン管理がされていないため、過去の変更履歴やトラブル対応が困難だった。
- 問題(3):手動デプロイによる作業ミスや、手間のかかる作業が効率化を阻害していた。
- 問題(4):コードが一部肥大化し、メンテナンス性やパフォーマンス性が低下していた。
- 問題(5):万が一データが消えてしまってもリカバリする手段がなかった。
- 問題(6):WPアカウントは共通アカウントで運用していた。
- 問題(7):脆弱性を検知する術がなかった。
- 最後に
理想と現状
前提として、Webサイトの保守・運用においてAさんに聞かないと理解できない、という状態はリスクが高いと言えます。 では、AさんがBさんに口頭で伝えながら2人が対応できる状態はどうでしょう。これもまだまだリスクが高い状態と言えると思います。
私が考える理想の状態は以下の通りです。
誰が対応しても同じ結果が得られる状態であること
運用に伴うドキュメントがチーム全体に共有/浸透されていること
新機能の追加やトラブル対応できる仕組みが整っていること
トラブルが起きないための予防ができていること
一部の運営サイトは以下の状態でした。
開発環境が定まっていない
コードのバージョン管理やデプロイのフローが定まっていない
コーディングルールや仕様が定まっていない
ファイルやDBなどのバックアップ体制がない
プラグインの脆弱性やアカウント周りのセキュリティ対策が不十分
ただ、前任者が一人で保守・運用を行っていたため、環境やフロー、ルールなどがなくても問題はないと言える状況です。 これから、チームで保守・運用をしていくとなると改善が必要でした。
現状と理想を図にすると、イメージとしては以下になります。
- 改善前
今回は以下のような状態を目指していきます。
- 改善後
CMSとしてWordPress(以下WP)で運用しているので、 フロント側だけでなく、バックエンド側の改善も必要になってきます。 今回は問題と改善を7つにまとめ、行った取り組みについて解説していきます。
問題(1):作業者によって環境が違うためバグの再現が難しかった。
改善(1):Docker(.wp-env)での開発環境を構築した。
【解決できたこと】
Dockerを使用することで、開発環境を統一できるようになり、環境の違いによるバグやトラブルを解消した。
バグが発生した際、どの環境でも同じ状態を再現できるようになり、迅速なデバッグが可能になった。
ホットリロードにより、コーディングやデバッグ作業の効率が向上した。
新しいメンバーが加わっても、簡単に同じ環境をセットアップできるようになり、サイト運用のスムーズな進行が実現した。
サイト運用が一人の場合は「Local WP」「STUDIO」などすぐにWP環境を構築できるツールでも問題ありませんが、 複数人の場合、どうしても環境依存の問題が発生します。
.wp-env
は簡単な設定ファイルによってWPの開発環境を構築できる仕組みを提供しており、
Dockerを使うことで複数のコンテナ(PHP、MySQL、WP)を簡単に起動できます。
また、テーマやプラグインをホットリロードで適用できるように設定されており、コード変更を即座にテストできます。
これにより、チームメンバー間でも同一の環境が手軽に共有でき、環境構築の手間を大幅に省けました。
【ポイント】
Dockerを起動後もDBのインポートやURLの変更、プラグインのインストールやWPの基本設定が必要になります。
それらの作業もできるだけコマンドラインで構築できるようにしておきます。
1. 依存ライブラリのインストール `npm i` 2. 初期データインポート用のDBダンプファイルを `./misc/data` 配下に設置 3. DockerでWordPress起動 `npx wp-env start` 4. `npx wp-env run cli wp db import ../data/{上記で用意したダンプファイル}` を実行 (ダンプファイルによっては先に `npx wp-env run cli wp db reset --yes` を実行する必要あり) 5. `npx wp-env run cli wp search-replace 'https://timeless-kaitori.com' 'http://localhost:8901' --skip-columns=guid` を実行 6. `npm run setup`を実行する。
このように残しておきつつ、コマンドでは難しい作業はテキストドキュメントとして残しておきます。
npm run setup
では、install.sh
シェルスクリプトを実行するようにし、WP-CLIで実行できるプラグインのインストールや言語設定、
テーマのコード品質を維持するためのcomposerのインストールにより、効率的に開発・コードチェックを行えるようになっています。
以下はnpm run setup
で実行されるシェルスクリプトの一部です。
wp plugin install プラグイン名 ...(略) wp language core install ja wp language plugin install --all ja cd wp-content/themes/timeless-kaitori/ && composer install
これで基本的には画面の操作は不要で環境構築が可能になります。
問題(2):バージョン管理がされていないため、過去の変更履歴やトラブル対応が困難だった。
改善(2):Git/GitHubを導入し、すべてのコード変更を記録するようにした。
【解決できたこと】
チーム全体でコードを共有し、誰でも変更点を把握できる体制を整備できた。
何か問題が起きたときに、即座に戻せる体制ができた。
コードレビューが実施できるようになり、コーダーの育成や品質の向上へと繋がった。
デプロイの自動化にも繋がり、効率的にテストや本番環境へのアップロードが可能になった。
バージョン管理がされていないこと自体がリスクが大きいと思いますが、 テックが精通していないサイトでは、Gitの導入がまだ進んでいない場合も少なくないようです。 複数人で保守・運用する以上は必要不可欠なのがバージョン管理(Git)です。
【ポイント】
前職では、Webサーバーの公開ディレクトリをGit管理の対象として、サーバーにもGitをインストールして運用していました。
公開したくないファイルやWPの操作に依存するファイルなどを.gitignore
から対象外にして、
デプロイする際は、リモートリポジトリで本番のブランチにマージしたのちに、
直接サーバーにSSHで入って公開ディレクトリからgit pull
でデプロイしていました。
この手法の問題点は...
手動操作が必要となり、オペレーションミスが発生しやすい。
必要なファイルが環境ごとに異なる場合、環境設定の再現性が低下し、デプロイ時の不具合のリスクが増す。
ビルド済みのファイルがコミットされることになるので、他のコミットとのコンフリクトが発生する可能性が高い。
サーバー上でGit操作を頻繁に行うと、リソース(CPUやディスクI/O)を消費するため、サーバーのパフォーマンスに影響を与える可能性がある。
このような問題をはらんでいるので、自動化されたCI/CDパイプラインの導入や、 ビルド済みファイルをサーバーに転送する方法が望ましく、GitとCI/CDツールはセットで導入しました。
問題(3):手動デプロイによる作業ミスや、手間のかかる作業が効率化を阻害していた。
改善(3):CI/CDツール(Buddy Works)を導入し、デプロイの自動化をした。
【解決できたこと】
自動でデプロイが行われるため、作業ミスが減少し、デプロイにかかる時間も大幅に短縮した。
チームメンバーが一貫したフローでデプロイできるようになり、作業がスムーズに進むようになった。
Slackの通知機能を利用することで、チーム全体にデプロイ状況をリアルタイムで共有できるようになった。
ロールバックが容易になり、問題発生時に迅速に以前の状態に戻すことが可能になった。
手動デプロイでは様々な問題をはらんでいました。 そこで、CI/CDツールの導入により自動デプロイが必要になってくるのですが、CI/CDツールと言っても様々なSaaSが存在します。
ツール | メリット | デメリット |
---|---|---|
GitHub Actions | GitHubとの連携、無料での利用範囲、豊富なマーケットプレイス | 設定の学習コストが高い、ランナーリソースの制限 |
Buddy Works | 直感的なUI、豊富な通知オプション、自社ホスティング可能 | 有料プランが中心、大規模なプロジェクトでの制約 |
CircleCI | 高速ビルド、キャッシュ機能、並列ジョブ | 初期設定が複雑、長時間ビルドでコストが高くなる |
Jenkins | オープンソースでコスト低、自社ホスティング、拡張性豊富 | メンテナンスが必要、UIが使いにくい |
GitLab CI/CD | GitLabとの強力な統合、無料機能範囲が広い、セルフホスティング可能 | 学習コストが高い、リソース負担が大きい |
Travis CI | シンプルな設定、GitHubとの相性が良い | パフォーマンスが遅い、有料プランが割高 |
直感的なUIやワークフロー作成の簡単さから「Buddy Works」を採用しました。
Slackの通知やビルドの実行、データの転送、CloudFrontのキャッシュクリアなど、デプロイに必要な作業はすべて自動化ができました。
【ポイント】
今回の改善でCSSをSass(SCSS)に切り替えたことで、ビルドが必要になりました。
CSSを軽量化するminifyを導入しているので、ビルドしたファイルをコミットしてしまうと、
他の作業でビルドした際に必ずコンフリクトが発生してしまいます。
ビルド前のSassファイルのみをコミットして、ビルドはBuddy Worksに任せることでコンフリクトが発生しなくなりました。 チーム全体での統一されたビルド環境を維持し、ビルドに関するトラブルを回避できるようになりました。
問題(4):コードが一部肥大化し、メンテナンス性やパフォーマンス性が低下していた。
改善(4):CSS/JS/PHPのコードのリファクタリングを行い保守性を向上した。
【解決できたこと】
Sass(SCSS)の導入でCSSを分割し、コードの可読性とメンテナンス性を向上した。
JSの不要なプログラムを整理し、サイトのパフォーマンスを改善できた。
URL構成の見直しにより、店舗ページやLPの管理が容易になり、保守性とSEOの効果を両立させた。
スタイルは元々、生のCSSでコーディングされていたのと、ひとつのファイルで構成されていたため、 コードが肥大化しメンテナンス性が低い状態でした。 まずはSass(SCSS)を導入し、コンポーネント単位でファイルを分割することでメンテナンス性を向上させました。
また、JSに関しても共通のファイルが複数のページで読み込まれており、 ページによっては不要なスクリプトが混在していて、パフォーマンスを低下させていました。 不要なスクリプトの整理を行いパフォーマンスの向上をさせました。
PHPに関しては、パラメータによって店舗ページやLPの出し分けを行っており、 独自のグローバル変数を、個別のカスタムテーマへ定義されていたので、コードの見通しが悪くなっていました。 極力WP標準の関数を使う形でリファクタリングしました。
【ポイント】
CSS命名規則が定まっていない中でのSass化だったので、とりあえずはページ単位でファイルを分けつつ、
共通のコンポーネントはそれぞれのパーツ毎にファイルを作成しました。
Bootstrapに近いOOCSSの記法が採用されていますが、書き方がバラバラだったりするのが課題です。
CSSに限った話ではなく、コーダーの個々の裁量に任せてコーディングを行うと、 サイトが大きくなるにつれて保守性が破綻してしまいますので、最初の設計やルールがとっても大切です。
まだベストな状態ではないので、将来的にサイトをリニューアルする際は、 技術選定の見直しやコーディングルールを新設することを検討しています。
問題(5):万が一データが消えてしまってもリカバリする手段がなかった。
改善(5):自動実行によるファイルおよびDBのバックアップ体制を構築した。
【解決できたこと】
- バックアップ体制を見直し、万が一の際に迅速に復旧できる体制を構築できた。
コードをGit管理していてもDBを使っている以上、WP上で更新されたデータはバージョン管理されていません。 WPは便利なもので、そういったデータをバックアップするプラグインというものがたくさん存在します。 今回利用したのは「BackWPup」というもので、WPサイトのバックアップを自動化するためのプラグインで、多くのユーザーから高い評価を受けています。 このプラグインは、ファイルやデータベースのバックアップをスケジュール設定に従って自動的に行い、万が一のトラブル時に備えることができます。
【ポイント】
前職ではそもそもテスト環境のバックアップはしておりませんでしたが、
テストと本番で差分があることは当たり前にあることなので、バックアップは必要になります。
バックアップの実行時間は深夜帯に設定することはもちろんですが、 テストサーバーは複数のサイトが共存しているので、自動実行の時間を変えることで負荷分散をしています。 理想は1サイト1サーバーですが、コスト的にそうもいかないケースがあると思いますので、実行時間を変えるなどの工夫が必要でした。
問題(6):WPアカウントは共通アカウントで運用していた。
改善(6):アカウントは個々に作成し、SSO(Single Sign-On)を導入した。
【解決できたこと】
都度ログイン情報を入力する手間が省けた。
不正ログインのリスクを低減し、セキュリティが向上した。
ユーザー認証が一元化され、ユーザーの追加・削除が集中管理できるようになった。
テーマファイルやプラグインの更新ができる人も、記事を更新するだけの人も同じ管理者権限のアカウントで運用していました。 そうすると、誤った操作をしてしまうと問題が生じてしまいますし、誰が操作したかもわかりません。 WP標準の権限別アカウントを付与することも改善のひとつになりますが、 サイト別にパスワードの管理が必要であったり、IP制限などの高度なセキュリティ対策としては不十分です。 バイセルでは全社的にMicrosoftのアカウントを付与しているので、それを使ったSSOを導入しました。
【ポイント】
SaaS側で認証を行うため、WP側でメールアドレスやパスワードを変更してしまうと、ログインできなくなってしまいます。
各ユーザーに対してその案内をすると共に、サイト内で利用できる機能を管理するためのプラグインとして「Adminimize」を併用して、
メールアドレスやパスワードの項目を非表示にするなどの対策をしました。
問題(7):脆弱性を検知する術がなかった。
改善(7):脆弱性検知のプラグイン「WPScan」を導入した。
【解決できたこと】
脆弱性の早期発見ができるようになった。
手動で行う手間を省き、自動で脆弱性チェックが可能になった。
不正アクセスのリスクを軽減できた。
WPはプログラムの脆弱性により、サイトの内容が改ざんされてしまうリスクがあります。 「WPScan」の導入により、コア、テーマ、プラグインの脆弱性情報をスキャンし、脆弱性が検出されると警告を出してくれます。 脆弱性を常に把握し、セキュリティリスクを最小限に抑えることができました。
【ポイント】
「WPScan」のスキャンには一定のサーバーリソースが必要で、特に大規模サイトやサーバーリソースが限られている場合、
スキャン中にサイトのパフォーマンスが一時的に低下する可能性があります。
自動スキャンを設定する場合は、バックアップなどの自動実行の時間を避けて設定しました。
最後に
今回の改善策は、あくまでもWebサイト保守・運用の基盤づくりの一環に過ぎず、正直、まだまだ改善できることはあります。 次のフェーズとしては、SEOの為のコンテンツ開発や、パフォーマンスやUX向上に向けたキャッシュの最適化やヘッドレスCMS化など。 やりたいことは山積みですが、コツコツと改善していきながら、またご紹介したいと思います。