開発者ドキュメント

Ubuntu14.04でAnsibleを使用して基本的なPHPアプリケーションをデプロイする方法

序章

このチュートリアルでは、Ansibleを使用して基本的なPHPアプリケーションをプロビジョニングするプロセスについて説明します。 このチュートリアルの最後の目標は、ターゲットのDropletで単一のSSH接続や手動コマンドを実行せずに、新しいWebサーバーで基本的なPHPアプリケーションを提供することです。

PHPアプリケーションの例としてLaravelフレームワークを使用しますが、すでに独自のフレームワークやアプリケーションを持っている場合は、これらの手順を簡単に変更して他のフレームワークやアプリケーションをサポートできます。

前提条件

このチュートリアルでは、Ansibleを使用して、Ubuntu 14.04ドロップレットにNginx、PHP、およびその他のサービスをインストールして構成します。 このチュートリアルは基本的なAnsibleの知識に基づいているため、Ansibleを初めて使用する場合は、最初にこの基本的なAnsibleチュートリアルを読むことができます。

このチュートリアルに従うには、次のものが必要です。

ステップ1—Ansibleをインストールする

最初のステップは、Ansibleをインストールすることです。 これは、PPA(Personal Package Archive)をインストールし、aptを使用してAnsibleパッケージをインストールすることで簡単に実行できます。

まず、apt-add-repositoryコマンドを使用してPPAを追加します。

  1. sudo apt-add-repository ppa:ansible/ansible

それが終わったら、aptキャッシュを更新します。

  1. sudo apt-get update

最後に、Ansibleをインストールします。

  1. sudo apt-get install ansible

Ansibleがインストールされたら、作業用の新しいディレクトリを作成し、基本構成をセットアップします。 デフォルトでは、Ansibleは/etc/ansible/hostsにあるhostsファイルを使用します。このファイルには、管理しているすべてのサーバーが含まれています。 このファイルは一部のユースケースでは問題ありませんが、グローバルであるため、ここで必要なものではありません。

このチュートリアルでは、ローカルホストファイルを作成し、代わりにそれを使用します。 これを行うには、作業ディレクトリ内に新しいAnsible構成ファイルを作成します。これを使用して、Ansibleに同じディレクトリ内のhostsファイルを探すように指示できます。

新しいディレクトリを作成します(このチュートリアルの残りの部分で使用します)。

  1. mkdir ~/ansible-php

新しいディレクトリに移動します。

  1. cd ~/ansible-php/

ansible.cfgという名前の新しいファイルを作成し、nanoまたはお気に入りのテキストエディタを使用して編集できるように開きます。

  1. nano ansible.cfg

以下をansible.cfgファイルにコピーして、[defaults]グループのhostsの値でhostfile構成オプションを追加します。

ansible.cfg
[defaults]
hostfile = hosts

ansible.cfgファイルを保存して閉じます。 次に、hostsファイルを作成します。このファイルには、アプリケーションをデプロイするPHPドロップレットのIPアドレスが含まれています。

  1. nano hosts

以下をコピーしてphpのセクションを追加し、your_server_ipをサーバーのIPアドレスに置き換え、sammyをPHPの前提条件で作成したsudo非rootユーザーに置き換えます滴。

ホスト
[php]
your_server_ip ansible_ssh_user=sammy

hostsファイルを保存して閉じます。 簡単なチェックを実行して、新しいphpグループのpingモジュールを呼び出して、Ansibleが期待どおりにホストに接続できることを確認しましょう。

  1. ansible php -m ping

以前にそのホストにログインしたことがあるかどうかによっては、SSHホスト認証チェックを取得する場合があります。 pingは正常な応答で返されるはずです。これは、次のようになります。

出力
111.111.111.111 | success >> {
    "changed": false,
    "ping": "pong"
}

これでAnsibleがインストールおよび構成されました。 Webサーバーのセットアップに進むことができます。

ステップ2—必要なパッケージのインストール

このステップでは、Ansibleとaptを使用していくつかの必要なシステムパッケージをインストールします。 特に、gitnginxsqlite3mcrypt、およびいくつかのphp5-*パッケージをインストールします。

aptモジュールを追加して必要なパッケージをインストールする前に、基本的なプレイブックを作成する必要があります。 チュートリアルを進めながら、このプレイブックに基づいて作成します。 php.ymlという新しいプレイブックを作成します。

  1. 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オプションを使用することを忘れないでください。

  1. ansible-playbook php.yml --ask-sudo-pass

ステップ3—システム構成ファイルの変更

このセクションでは、PHPドロップレットのシステム構成ファイルの一部を変更します。 変更する最も重要な構成オプション(後の手順で説明するNginxのファイルを除く)は、php5-fpmcgi.fix_pathinfoオプションです。これは、デフォルト値がセキュリティリスクであるためです。

まず、このファイルに追加するすべてのセクションについて説明し、次にphp.ymlファイル全体をコピーして貼り付けるために含めます。

lineinfileモジュールを使用して、ファイル内の構成値が期待どおりであることを確認できます。 これは、ジェネリック正規表現を使用して実行できるため、Ansibleは、パラメーターが含まれる可能性のあるほとんどのフォームを理解できます。 また、変更を有効にするためにphp5-fpmnginxを再起動する必要があるため、新しい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-fpmserviceモジュールで再起動されないというバグがあります。

修正がリリースされるまで、次のように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を開いて再度編集します。

  1. 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

最後に、ハンドブックを実行します。

  1. 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ファイルを開いて編集します。

  1. 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

プレイブックを保存して閉じてから、実行します。

  1. 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ファイルを開いて編集します。

  1. 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

最後に、ハンドブックを実行します。

  1. 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ファイルを開いて編集します。

  1. 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

プレイブックを保存して実行します。

  1. ansible-playbook php.yml --ask-sudo-pass

これで、Composerは実行されるたびにAPP_KEYの変更を停止します。

ステップ6—環境変数の更新

このステップでは、アプリケーションの環境変数を更新します。

Laravelには、APP_ENVlocalに、APP_DEBUGtrueに設定するデフォルトの.envファイルが付属しています。 それぞれproductionfalseに交換したいと思います。 これは、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ファイルを開いて編集します。

  1. 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

プレイブックを保存して実行します。

  1. 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という名前の新しいファイルを作成します。

  1. nano nginx.conf

このサーバーブロックをそのファイル内に保存します。 このNginx構成の詳細については、このチュートリアルのステップ4を確認してください。 以下の変更は、Laravelパブリックディレクトリの場所を指定し、Nginxがhostsファイルでserver_nameとしてinventory_hostname変数で定義したホスト名を使用するようにします。

nginx.conf
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ファイルを開きます。

  1. nano php.yml

タスクセクションの最後にこのnginxタスクを追加します。 php.ymlファイル全体は次のようになります。

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

プレイブックを保存して再度実行します。

  1. 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ドロップレットに直接ログインして、単一の手動コマンドを実行する必要なしに、すべてが完了しました。

モバイルバージョンを終了