Ubuntu14.04でAnsibleを使用して基本的なPHPアプリケーションをデプロイする方法
序章
このチュートリアルでは、Ansibleを使用して基本的なPHPアプリケーションをプロビジョニングするプロセスについて説明します。 このチュートリアルの最後の目標は、ターゲットのDropletで単一のSSH接続や手動コマンドを実行せずに、新しいWebサーバーで基本的なPHPアプリケーションを提供することです。
PHPアプリケーションの例としてLaravelフレームワークを使用しますが、すでに独自のフレームワークやアプリケーションを持っている場合は、これらの手順を簡単に変更して他のフレームワークやアプリケーションをサポートできます。
前提条件
このチュートリアルでは、Ansibleを使用して、Ubuntu 14.04ドロップレットにNginx、PHP、およびその他のサービスをインストールして構成します。 このチュートリアルは基本的なAnsibleの知識に基づいているため、Ansibleを初めて使用する場合は、最初にこの基本的なAnsibleチュートリアルを読むことができます。
このチュートリアルに従うには、次のものが必要です。
-
PHPアプリケーションの構成とデプロイに使用する任意のサイズのUbuntu14.04ドロップレット1つ。 このマシンのIPアドレスは、チュートリアル全体で
your_server_ip
と呼ばれます。 -
Ansibleに使用される1つのUbuntu14.04ドロップレット。 これは、このチュートリアル全体でログインするドロップレットです。
-
Sudo非ルートユーザーが両方のドロップレット用に構成されています。
-
Ansible DropletのSSHキーを使用して、PHPデプロイメントDropletへのログインを承認します。これは、AnsibleDropletでこのチュートリアルに従って設定できます。
ステップ1—Ansibleをインストールする
最初のステップは、Ansibleをインストールすることです。 これは、PPA(Personal Package Archive)をインストールし、apt
を使用してAnsibleパッケージをインストールすることで簡単に実行できます。
まず、apt-add-repository
コマンドを使用してPPAを追加します。
- sudo apt-add-repository ppa:ansible/ansible
それが終わったら、apt
キャッシュを更新します。
- sudo apt-get update
最後に、Ansibleをインストールします。
- sudo apt-get install ansible
Ansibleがインストールされたら、作業用の新しいディレクトリを作成し、基本構成をセットアップします。 デフォルトでは、Ansibleは/etc/ansible/hosts
にあるhostsファイルを使用します。このファイルには、管理しているすべてのサーバーが含まれています。 このファイルは一部のユースケースでは問題ありませんが、グローバルであるため、ここで必要なものではありません。
このチュートリアルでは、ローカルホストファイルを作成し、代わりにそれを使用します。 これを行うには、作業ディレクトリ内に新しいAnsible構成ファイルを作成します。これを使用して、Ansibleに同じディレクトリ内のhostsファイルを探すように指示できます。
新しいディレクトリを作成します(このチュートリアルの残りの部分で使用します)。
- mkdir ~/ansible-php
新しいディレクトリに移動します。
- cd ~/ansible-php/
ansible.cfg
という名前の新しいファイルを作成し、nano
またはお気に入りのテキストエディタを使用して編集できるように開きます。
- nano ansible.cfg
以下をansible.cfg
ファイルにコピーして、[defaults]
グループのhosts
の値でhostfile
構成オプションを追加します。
[defaults]
hostfile = hosts
ansible.cfg
ファイルを保存して閉じます。 次に、hosts
ファイルを作成します。このファイルには、アプリケーションをデプロイするPHPドロップレットのIPアドレスが含まれています。
- nano hosts
以下をコピーしてphp
のセクションを追加し、your_server_ip
をサーバーのIPアドレスに置き換え、sammy
をPHPの前提条件で作成したsudo非rootユーザーに置き換えます滴。
[php]
your_server_ip ansible_ssh_user=sammy
hosts
ファイルを保存して閉じます。 簡単なチェックを実行して、新しいphp
グループのping
モジュールを呼び出して、Ansibleが期待どおりにホストに接続できることを確認しましょう。
- ansible php -m ping
以前にそのホストにログインしたことがあるかどうかによっては、SSHホスト認証チェックを取得する場合があります。 pingは、次のような正常な応答で返されるはずです。
111.111.111.111 | success >> {
"changed": false,
"ping": "pong"
}
これでAnsibleがインストールおよび構成されました。 Webサーバーのセットアップに進むことができます。
ステップ2—必要なパッケージのインストール
このステップでは、Ansibleとapt
を使用していくつかの必要なシステムパッケージをインストールします。 特に、git
、nginx
、sqlite3
、mcrypt
、およびいくつかのphp5-*
パッケージをインストールします。
apt
モジュールを追加して必要なパッケージをインストールする前に、基本的なプレイブックを作成する必要があります。 チュートリアルを進めながら、このプレイブックに基づいて作成します。 php.yml
という新しいプレイブックを作成します。
- nano php.yml
次の構成で貼り付けます。 最初の2行は、使用するホストグループ(php
)を指定し、デフォルトでsudo
を使用してコマンドを実行するようにします。 残りは、必要なパッケージを含むモジュールを追加します。 これを独自のアプリケーション用にカスタマイズするか、Laravelアプリケーションの例に従っている場合は以下の構成を使用できます。
---
- hosts: php
sudo: yes
tasks:
- name: install packages
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- mcrypt
- nginx
- php5-cli
- php5-curl
- php5-fpm
- php5-intl
- php5-json
- php5-mcrypt
- php5-sqlite
- sqlite3
php.yml
ファイルを保存します。 最後に、ansible-playbook
を実行して、パッケージをドロップレットにインストールします。 PHPドロップレットのsudoユーザーがパスワードを必要とする場合は、--ask-sudo-pass
オプションを使用することを忘れないでください。
- ansible-playbook php.yml --ask-sudo-pass
ステップ3—システム構成ファイルの変更
このセクションでは、PHPドロップレットのシステム構成ファイルの一部を変更します。 変更する最も重要な構成オプション(後の手順で説明するNginxのファイルを除く)は、php5-fpm
のcgi.fix_pathinfo
オプションです。これは、デフォルト値がセキュリティリスクであるためです。
まず、このファイルに追加するすべてのセクションについて説明し、次にphp.yml
ファイル全体を含めてコピーして貼り付けます。
lineinfileモジュールを使用して、ファイル内の構成値が期待どおりであることを確認できます。 これは、一般的な正規表現を使用して実行できるため、Ansibleは、パラメーターが含まれる可能性のあるほとんどのフォームを理解できます。 また、変更を有効にするためにphp5-fpm
とnginx
を再起動する必要があるため、新しいhandlers
セクションに2つのハンドラーも追加する必要があります。 ハンドラーは、タスクが変更されたときにのみ起動されるため、これに最適です。 また、プレイブックの最後で実行されるため、複数のタスクが同じハンドラーを呼び出すことができ、1回だけ実行されます。
上記を実行するセクションは次のようになります。
- name: ensure php5-fpm cgi.fix_pathinfo=0
lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
notify:
- restart php5-fpm
- restart nginx
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
注:Ansibleバージョン1.9.1のバグ
Ansibleバージョン1.9.1には、ハンドラーで使用したように、php5-fpm
がservice
モジュールで再起動されないというバグがあります。
修正がリリースされるまで、次のようにrestart php5-fpm
ハンドラーをservice
コマンドの使用からshell
コマンドの使用に変更することでこの問題を回避できます。
- name: restart php5-fpm
shell: service php5-fpm restart
これにより、問題が回避され、php5-fpm
が正しく再起動されます。
次に、php5-mcrypt
モジュールが有効になっていることも確認する必要があります。 これは、シェルタスクでphp5enmod
スクリプトを実行し、20-mcrypt.ini
ファイルが有効になっているときに適切な場所にあることを確認することで実行されます。 タスクが特定のファイルを作成することをAnsibleに伝えていることに注意してください。 そのファイルが存在する場合、タスクは実行されません。
- name: enable php5 mcrypt module
shell: php5enmod mcrypt
args:
creates: /etc/php5/cli/conf.d/20-mcrypt.ini
ここで、php.yml
を開いて再度編集します。
- nano php.yml
上記のタスクとハンドラーを追加して、ファイルが以下と一致するようにします。
---
- hosts: php
sudo: yes
tasks:
- name: install packages
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- mcrypt
- nginx
- php5-cli
- php5-curl
- php5-fpm
- php5-intl
- php5-json
- php5-mcrypt
- php5-sqlite
- sqlite3
- name: ensure php5-fpm cgi.fix_pathinfo=0
lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
notify:
- restart php5-fpm
- restart nginx
- name: enable php5 mcrypt module
shell: php5enmod mcrypt
args:
creates: /etc/php5/cli/conf.d/20-mcrypt.ini
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
最後に、ハンドブックを実行します。
- ansible-playbook php.yml --ask-sudo-pass
これで、Dropletに必要なすべてのパッケージがインストールされ、基本構成がセットアップされ、準備が整いました。
ステップ4—Gitリポジトリのクローンを作成する
このセクションでは、Gitを使用してLaravelフレームワークリポジトリをドロップレットに複製します。 手順3と同様に、プレイブックに追加するすべてのセクションについて説明し、php.yml
ファイル全体を含めてコピーして貼り付けます。
Gitリポジトリのクローンを作成する前に、/var/www
が存在することを確認する必要があります。 これを行うには、ファイルモジュールを使用してタスクを作成します。
- name: create /var/www/ directory
file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700
上記のように、Gitモジュールを使用してリポジトリをDropletに複製する必要があります。 git clone
コマンドに通常必要なのはソースリポジトリだけなので、プロセスは単純です。 この場合、宛先も定義し、update=no
を設定して、リポジトリがすでに存在する場合は更新しないようにAnsibleに指示します。 Laravelを使用しているため、使用するgitリポジトリのURLはhttps://github.com/laravel/laravel.git
です。
ただし、権限が正しいことを確認するには、www-data
ユーザーとしてタスクを実行する必要があります。 これを行うには、sudo
を使用して特定のユーザーとしてコマンドを実行するようにAnsibleに指示できます。 最終的なタスクは次のようになります。
- name: Clone git repository
git: >
dest=/var/www/laravel
repo=https://github.com/laravel/laravel.git
update=no
sudo: yes
sudo_user: www-data
注:SSHベースのリポジトリの場合、accept_hostkey=yes
を追加して、SSHホストの検証でタスクがハングしないようにすることができます。
前と同じように、php.yml
ファイルを開いて編集します。
- nano php.yml
上記のタスクをプレイブックに追加します。 ファイルの終わりは次のように一致する必要があります。
...
- name: enable php5 mcrypt module
shell: php5enmod mcrypt
args:
creates: /etc/php5/cli/conf.d/20-mcrypt.ini
- name: create /var/www/ directory
file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700
- name: Clone git repository
git: >
dest=/var/www/laravel
repo=https://github.com/laravel/laravel.git
update=no
sudo: yes
sudo_user: www-data
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
プレイブックを保存して閉じてから、実行します。
- ansible-playbook php.yml --ask-sudo-pass
ステップ5—Composerを使用してアプリケーションを作成する
このステップでは、Composerを使用してPHPアプリケーションとその依存関係をインストールします。
Composerにはcreate-project
コマンドがあり、必要なすべての依存関係をインストールしてから、composer.json
ファイルのpost-create-project-cmd
セクションで定義されたプロジェクト作成手順を実行します。 これは、アプリケーションが最初に使用するために正しくセットアップされていることを確認するための最良の方法です。
次のAnsibleタスクを使用して、Composerを/usr/local/bin/composer
としてグローバルにダウンロードおよびインストールできます。 その後、Ansibleを含め、Dropletを使用するすべての人がアクセスできるようになります。
- name: install composer
shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
args:
creates: /usr/local/bin/composer
Composerがインストールされていると、使用できるComposerモジュールがあります。 この例では、(working_dir
パラメーターを使用して)プロジェクトの場所をComposerに通知し、create-project
コマンドを実行します。 このフラグはcreate-project
コマンドではサポートされていないため、optimize_autoloader=no
パラメーターも追加する必要があります。 git
コマンドと同様に、これもwww-data
ユーザーとして実行して、アクセス許可が有効であることを確認します。 すべてをまとめると、次のタスクが実行されます。
- name: composer create-project
composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
sudo: yes
sudo_user: www-data
注:create-project
タスクは、新しいDropletでかなりの時間がかかる場合があります。これは、Composerのキャッシュが空であり、すべてを新しいものにダウンロードする必要があるためです。
次に、php.yml
ファイルを開いて編集します。
- nano php.yml
tasks
セクションの最後、handlers
の上に上記のタスクを追加して、プレイブックの最後が次のようになるようにします。
...
- name: Clone git repository
git: >
dest=/var/www/laravel
repo=https://github.com/laravel/laravel.git
update=no
sudo: yes
sudo_user: www-data
- name: install composer
shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
args:
creates: /usr/local/bin/composer
- name: composer create-project
composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
sudo: yes
sudo_user: www-data
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
最後に、ハンドブックを実行します。
- ansible-playbook php.yml --ask-sudo-pass
今再びAnsibleを実行するとどうなりますか? composer create-project
が再び実行され、Laravelの場合、これは新しいAPP_KEY
を意味します。 したがって、代わりに必要なのは、そのタスクを新しいクローンの後でのみ実行するように設定することです。 git clone
タスクの結果に変数を登録し、composer create-project
タスク内でそれらの結果を確認することにより、1回だけ実行されることを確認できます。 git clone
タスクがChangedの場合、composer create-project
を実行し、そうでない場合はスキップされます。
注: Ansible composer
モジュールの一部のバージョンにバグがあるようで、Changedの代わりにOKを出力する場合があります。依存関係がインストールされていなくても、スクリプトが実行されたことは無視されます。
php.yml
ファイルを開いて編集します。
- nano php.yml
git clone
タスクを見つけます。 次のように、register
オプションを追加して、タスクの結果をcloned
変数に保存します。
- name: Clone git repository
git: >
dest=/var/www/laravel
repo=https://github.com/laravel/laravel.git
update=no
sudo: yes
sudo_user: www-data
register: cloned
次に、composer create-project
タスクを見つけます。 when
オプションを追加して、cloned
変数をチェックし、変数が変更されているかどうかを確認します。
- name: composer create-project
composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
sudo: yes
sudo_user: www-data
when: cloned|changed
プレイブックを保存して実行します。
- ansible-playbook php.yml --ask-sudo-pass
これで、Composerは実行されるたびにAPP_KEY
の変更を停止します。
ステップ6—環境変数の更新
このステップでは、アプリケーションの環境変数を更新します。
Laravelには、APP_ENV
をlocal
に、APP_DEBUG
をtrue
に設定するデフォルトの.env
ファイルが付属しています。 それぞれproduction
とfalse
に交換したいと思います。 これは、lineinfile
モジュールと次のタスクを使用して簡単に実行できます。
- name: set APP_DEBUG=false
lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
- name: set APP_ENV=production
lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production
php.yml
ファイルを開いて編集します。
- nano php.yml
このタスクをプレイブックに追加します。 ファイルの終わりは次のように一致する必要があります。
...
- name: composer create-project
composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
sudo: yes
sudo_user: www-data
when: cloned|changed
- name: set APP_DEBUG=false
lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
- name: set APP_ENV=production
lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
プレイブックを保存して実行します。
- ansible-playbook php.yml --ask-sudo-pass
lineinfile
モジュールは、テキストファイルをすばやく微調整するのに非常に便利であり、このような環境変数が正しく設定されていることを確認するのに最適です。
ステップ7—Nginxの構成
このセクションでは、PHPアプリケーションを提供するようにNginxを構成します。
今すぐWebブラウザでドロップレットにアクセスした場合(つまり http://your_server_ip/
)、Laravelの新しいプロジェクトページの代わりにNginxのデフォルトページが表示されます。 これは、/var/www/laravel/public
ディレクトリからアプリケーションを提供するようにNginxWebサーバーを構成する必要があるためです。 これを行うには、そのディレクトリでNginxのデフォルト構成を更新し、php-fpm
のサポートを追加して、PHPスクリプトを処理できるようにする必要があります。
nginx.conf
という名前の新しいファイルを作成します。
- nano nginx.conf
このサーバーブロックをそのファイル内に保存します。 このNginx構成の詳細については、このチュートリアルのステップ4を確認してください。 以下の変更は、Laravelパブリックディレクトリの場所を指定し、Nginxがhosts
ファイルでserver_name
としてinventory_hostname
変数で定義したホスト名を使用するようにします。
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /var/www/laravel/public;
index index.php index.html index.htm;
server_name {{ inventory_hostname }};
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/laravel/public;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
nginx.conf
ファイルを保存して閉じます。
これで、テンプレートモジュールを使用して、新しい構成ファイルをプッシュできます。 template
モジュールは、copy
モジュールと見た目も音も非常に似ていますが、大きな違いがあります。 copy
は、変更を加えずに全体に1つ以上のファイルをコピーします。一方、template
は、単一のファイルをコピーし、ファイル内のすべての変数を解決します。 構成ファイル内で{{ inventory_hostname }}
を使用したため、template
モジュールを使用して、hosts
ファイルで使用したIPアドレスに解決されます。 このように、Ansibleが使用する構成ファイルをハードコーディングする必要はありません。
ただし、タスクを作成するときはいつものように、ドロップレットで何が起こるかを考慮する必要があります。 Nginxの構成を変更しているため、Nginxとphp-fpm
を再起動する必要があります。 これは、notify
オプションを使用して行われます。
- name: Configure nginx
template: src=nginx.conf dest=/etc/nginx/sites-available/default
notify:
- restart php5-fpm
- restart nginx
php.yml
ファイルを開きます。
- nano php.yml
タスクセクションの最後にこのnginxタスクを追加します。 php.yml
ファイル全体は次のようになります。
---
- hosts: php
sudo: yes
tasks:
- name: install packages
apt: name={{ item }} update_cache=yes state=latest
with_items:
- git
- mcrypt
- nginx
- php5-cli
- php5-curl
- php5-fpm
- php5-intl
- php5-json
- php5-mcrypt
- php5-sqlite
- sqlite3
- name: ensure php5-fpm cgi.fix_pathinfo=0
lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
notify:
- restart php5-fpm
- restart nginx
- name: enable php5 mcrypt module
shell: php5enmod mcrypt
args:
creates: /etc/php5/cli/conf.d/20-mcrypt.ini
- name: create /var/www/ directory
file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700
- name: Clone git repository
git: >
dest=/var/www/laravel
repo=https://github.com/laravel/laravel.git
update=no
sudo: yes
sudo_user: www-data
register: cloned
- name: install composer
shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
args:
creates: /usr/local/bin/composer
- name: composer create-project
composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
sudo: yes
sudo_user: www-data
when: cloned|changed
- name: set APP_DEBUG=false
lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
- name: set APP_ENV=production
lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production
- name: Configure nginx
template: src=nginx.conf dest=/etc/nginx/sites-available/default
notify:
- restart php5-fpm
- restart nginx
handlers:
- name: restart php5-fpm
service: name=php5-fpm state=restarted
- name: restart nginx
service: name=nginx state=restarted
プレイブックを保存して再度実行します。
- ansible-playbook php.yml --ask-sudo-pass
完了したら、ブラウザに戻って更新します。 Laravelの新しいプロジェクトページが表示されます。
結論
このチュートリアルでは、パブリックリポジトリを使用したPHPアプリケーションのデプロイについて説明します。 Ansibleがどのように機能するかを学ぶのに最適ですが、オープンリポジトリを使用して完全にオープンソースのプロジェクトに取り組んでいるとは限りません。 これは、ステップ3のgit clone
をプライベートリポジトリで認証する必要があることを意味します。 これは、SSHキーを使用して非常に簡単に実行できます。
たとえば、SSHデプロイキーを作成してリポジトリに設定したら、git clone
タスクの前に、Ansibleを使用してそれらをサーバーにコピーして構成できます。
- name: create /var/www/.ssh/ directory
file: dest=/var/www/.ssh/ state=directory owner=www-data group=www-data mode=0700
- name: copy private ssh key
copy: src=deploykey_rsa dest=/var/www/.ssh/id_rsa owner=www-data group=www-data mode=0600
これにより、サーバーがアプリケーションを正しく認証してデプロイできるようになります。
Composerを使用して依存関係を管理するUbuntuベースのNginxWebサーバーに基本的なPHPアプリケーションをデプロイしました。 PHPドロップレットに直接ログインして、単一の手動コマンドを実行する必要なしに、すべてが完了しました。