[PHP] CodeIgniterで複数サイトを効率的に開発するディレクトリ構造を考えてみた

CodeIgniterは、ディレクトリ構造をかなり自由に決められるフレームワークです。そこで、複数のCodeIgniterサイトを一つのサーバーで運用する際に、できる限りコンパクトに、効率良く開発する方法を考えてみました。

※CodeIgniter 3を前提としています

方針

開発の効率と、セキュリティの両面で考えました。

開発効率を上げるために

  • Gitで管理する
  • ローカルからgit pushしたものをwebhookで同期する
  • 同じコードはかかない。共有する
  • 編集する項目を極力減らす

セキュリティを上げるために

  • 本番サーバーは直接編集しない
  • DocumentRootにはindex.phpだけ置く
  • アプリ本体には、apacheやnginx経由では、読み出しのみを許可する

運用の流れ

実運用では、下記のような流れで開発環境から公開までたどり着くように想定しています。

  1. 開発環境からGitlabのstgブランチにpush
  2. Gitlabがwebhook.phpを叩く(stgディレクトリのレポジトリをgit pull)
  3. ステージング環境でチェック
  4. masterブランチにMerge Requests && 受け入れ
  5. Gitlabがwebhook.phpを叩く(masterディレクトリのレポジトリをgit pull)
  6. 公開

ディクトリ構造

masterは公開用(example.com)、stgは公開前のステージング用(stg.example.com)です。gitのmasterブランチ、stgブランチにpushされたら、webhookで自動的に更新される流れを想定しています。

本当は、公開、ステージング、開発、ローカルの4段階制にしておくのがいいんですが、CodeIgniterの環境変数がproductionとdevelopmentの2つを想定しているので、開発=ローカルとして考えています。

ci3
└── .git
└── application
      └── core
      └── helpers
      └── hooks
      └── libraries
      └── third_party
└── system
apps
└── web01
      └── master
            └── .git
            └── application
                  └── config
                  └── controllers
                  └── models
                  └── views
      └── stg
            └── .git
            └── application
                  └── config
                  └── controllers
                  └── models
                  └── views
└── web02
      └── master
      └── stg

cache
└── web01
      └── master
            └── cache
      └── stg
            └── cache
└── web02
public_html
└── web01
      └── master // example.com
            └── .htaccess // SetENV production
            └── index.php
            └── webhook.php
      └── stg  // stg.example.com
            └── .htaccess // SetENV production
            └── index.php
            └── webhook.php
└── web02

コア部分と共有プログラムをci3ディレクトリに集約

CodeIgniterのコア部分と、third_partyプラグインなどは、基本的に使い回しなので共通のci3ディレクトリに配置します。

ci3
└── .git
└── application
      └── core
      └── helpers
      └── hooks
      └── libraries
      └── third_party
└── system

このディレクトリも.gitで管理しているので、サーバーをまたいでCodeIgniterサイトを開発していたとしても、git cloneすれば一発で他のサイトと同じ状況を作り出せます。

ただしデメリットもあって、複数サイトを運営している場合は、他のサイトでエラーが起こる可能性もあるため、それぞれでテストを行う必要があります。また、サーバーをまたぐ場合は、git pull忘れによるコミットのズレなどを回避する必要があります。(その点を考えると、ci3ディレクトリに入れるのは、third_partyだけにするほうが良いかもしれません。)

アプリケーション本体はappディレクトリに

続いて、アプリ本体はappディレクトリに入れました。各サイトごと、公開ディレクトリ、ステージングディレクトリごとに管理しています。coreやhooksなどの共有部分は、上記のci3からシンボリックリンクを張ります。

apps
└── web01
      └── prod
            └── .git
            └── application
                  └── config
                  └── controllers
                  └── models
                  └── views
      └── stg
            └── .git
            └── application
                  └── config
                  └── controllers
                  └── models
                  └── views

gitのpost-receiveを利用して、公開ディレクトリ、ステージングディレクトリにデプロイする方法もありますが、今回はGitlabの推奨するwebhookを使って、それぞれのレポジトリブランチをgit pullする前提にしています。

キャッシュは専用ディレクトリに

CodeIgniterのキャッシュは、それぞれ違う中身になるので、Gitlabの管理外の場所 & DocumentRootの外にしたいということで、専用ディレクトリを配置しました。ここはroot以外ではapacheしかさわれません。

cache
└── web01
      └── master
            └── cache
      └── stg
            └── cache

DocumentRootにはindexとwebhookだけを配置

スパムな方たちは、「zip.php」とか「setting.php」とかをありもしないファイルを総攻撃してくるので、公開ディレクトリにはどうしても出さないといけない2ファイルだけを置きました。

public_html
└── web01
      └── master
            └── index.php
            └── webhook.php
      └── stg
            └── index.php
            └── webhook.php

index.phpはCodeIgniterのindex.phpファイルです。公開もステージングもどちらもCodeIgniterで使う環境変数はproductionです。

webhook.phpは、Gitlabなどのwebhook機能を受け付けるために用意してあります。Gitlab等から来たrefの中身を見て、masterブランチなのかstgブランチなのかで条件分けをして、それぞれ更新する設定にします。

総括

ディレクトリ構造はかなり複雑になってしまいましたが、CodeIgniterのデフォルトの構成よりかは、効率とセキュリティにある程度配慮できたと思います。

運用方法は人それぞれですので、自分好みの設定を使ってみてください。