WordPressを改造してデプロイして、という作業をきちんと管理しようとすると、ごちゃごちゃと考えることが多くなります。
個人サーバレベルですがある程度方法が固まってきたので、連載形式でそのあたりを書いてみたいと思います。
前提条件
次のような管理体制とします。
- サーバはVPS(sshで操作できるサーバ)
- WordPressのソースはgitで管理している
- ansibleでサーバ管理をしている
デプロイ方式はcapistranoのモデルにしたがう
ansibleでのデプロイ方法については、r_rudiさんにより良記事が日本語訳されています。
http://tdoc.info/blog/2015/01/14/deploying_with_ansible.html
この方式をWordPressに適用していくと、ディレクトリ構造は次のようになります。
.
├── releases
| ├── 20151002210144
| └── 20151002210406
├── shared
| └── uploads
└── current -> releases/20151002220433
デプロイ手順をおおざっぱにいうと次のようになります。
release
ディレクトリにgitからcloneする- cloneしたディレクトリ上に
wp-config.php
を作成する current
シンボリックリンクをcloneしたディレクトリに強制置換で振り向ける
このとき、アップロードした画像ファイルなどは維持されている必要があります。
wp-content/uploadsの維持
wp-content
ディレクトリにはプラグインやテーマなどが入りますが、このうちデプロイ時に維持すべきはwp-content/uploads
ディレクトリです。画像ファイルが入っています。
wp-content/uploads
はshared/uploads
に実体を置き、wp-content/uploads
はシンボリックリンクでshared/uploads
を見るようにします。
wp-content/plugins
とwp-content/themes
は修正・追加する場合があるため、管理画面でのインストールではなく、gitにコミットしての手動インストールにします。
wp-content/cache
やwp-content/ewww
などキャッシュファイルは、デプロイ時には維持せず消してしまいたいものです。これらはgit上に置かないようにすることで、git clone時に生成されないようにします。
wp-config.phpはansibleで作成する
wp-config.php
にはDBパスワードなどを書かないといけないため、gitにそのままコミットするのは避けたいです。かといって管理対象外とするのもまずいです。
そこで、ansible-vaultで暗号化して、playbookとしてgit管理することにします。
$ ansible-vault --vault-password-file ~/.vault_pass.txt edit roles/site_wordpress/vars/main.yml
host_vars/prod.yml
ではなくroles/site_wordpress/vars/main.yml
にしているのは、host_vars/prod.yml
にはIPアドレスなども書いており、暗号化でdiffが見えなくなるのを嫌ったためです。このあたりはincludeなどでうまく避ける方法もありそうですが、いまのところこうしています。stage環境と本番環境でDB名を変えるなどの必要が出てくる場合はhost_vars
に移動させたほうが良いでしょう。
変数を定義できたら、あとはtempleteモジュールで作成するだけです。元となるwp-config.php
はバージョン依存なのでWordPressのgitに入れたいところですが、変数が増えた時に対応できないためroles/site_wordpress/templates/wp-config.php.j2
のようにplaybookの一部としています。WordPressのバージョンアップをするときには要注意事項になります。
playbookソースコード
以上を踏まえて、roles/site_wordpress/tasks/main.yml
は次のようになります。
---
- name: '各種デプロイディレクトリ作成'
file: path=/app/{{vhost}}/{{item}} owner=appdept group=appdept recurse=yes state=directory
with_items:
- 'releases'
- 'shared'
- name: '各種データディレクトリ作成'
file: path=/app/{{vhost}}/{{item}} owner=appdept group=appdept mode=0777 state=directory
with_items:
- 'shared/uploads'
- name: 'リリースタイムスタンプ作成'
command: date '+%Y%m%d%H%M%S'
register: release_date
changed_when: false
- name: 'gitリポジトリclone'
git:
repo: git@gitlab.com:username/{{vhost}}.git
dest: /app/{{vhost}}/releases/{{release_date.stdout}}
version: '{{project_version}}'
depth: 1
accept_hostkey: yes
become_user: appdept
- name: 'wp-contentパーミッション設定'
file: path=/app/{{vhost}}/releases/{{release_date.stdout}}/wp-content mode='g+w,o+w' recurse=yes state=directory
- name: 'sharedシンボリックリンク作成'
file:
path: '/app/{{vhost}}/releases/{{release_date.stdout}}/{{item.target}}'
src: '/app/{{vhost}}/shared/{{item.src}}'
state: link
with_items:
- { target: 'wp-content/uploads', src: 'uploads' }
- name: 'wp-config.php作成'
template: src={{item}}.j2 dest=/app/{{vhost}}/releases/{{release_date.stdout}}/{{item}} owner=appdept group=appdept
with_items:
- 'wp-config.php'
- name: 'currentシンボリックリンク置換'
file:
path: '/app/{{vhost}}/current'
src: 'releases/{{release_date.stdout}}'
state: link
- name: 'cron設定'
cron:
name: 'wp_cron'
cron_file: 'wp_{{vhost}}'
job: '/usr/bin/php -q /app/{{vhost}}/current/wp-cron.php 2>&1'
user: apache
minute: '*/5'
appdeptユーザはソースコード配備用ユーザです。apacheユーザはhttpdサービス(apacheかnginxかその他)の実行ユーザです。
「gitリポジトリclone」のrepoパラメータは適時変えてください。vhost変数はバーチャルホスト名で、httpdサービスの設定にも用いているものです。
playbook実行時にproject_version変数を設定するようにします。
ansible-playbook --vault-password-file ~/.vault_pass.txt -i hosts --extra-vars "project_version=master" prod.yml --tags blog
前のバージョンに戻したい場合は「project_version=master」を「project_version=v4.0.0」などにします。あらかじめgitにタグを打っておく必要があります。
このplaybookのまずい点として、--check
でエラーになります。release_date.stdout
変数が定義されないためで、もっとうまいやり方がありそうです。
参考サイト
http://tdoc.info/blog/2015/01/14/deploying_with_ansible.html
最近のコメント