Как развернуть простое PHP-приложение с помощью Ansible в Ubuntu 14.04

Вступление

В этом руководстве описывается процесс подготовки базового приложения PHP с использованием Ansible. Цель в конце этого учебника - заставить ваш новый веб-сервер обслуживать простое PHP-приложение без единого SSH-соединения или ручного запуска команды на целевой Droplet.

Мы будем использовать Laravel framework в качестве примера приложения PHP, но эти инструкции могут быть легко изменены для поддержки других сред и приложений, если у вас уже есть свои собственные.

Предпосылки

В этом руководстве мы будем использовать Ansible для установки и настройки Nginx, PHP и других сервисов в Ubuntu 14.04 Droplet. Этот учебник основан на базовых знаниях Ansible, поэтому, если вы новичок в Ansible, вы можете прочитать его по адресу https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-an- Сначала ubuntu-12-04-vps [это основное руководство по Ansible].

Чтобы следовать этому уроку, вам понадобится:

  • Одна капля Ubuntu 14.04 любого размера, которую мы будем использовать для настройки и развертывания нашего PHP-приложения. IP-адрес этой машины будет упоминаться как ++ в этом руководстве.

  • Одна капля Ubuntu 14.04, которая будет использоваться для Ansible. Это дроплет, в который вы войдете, чтобы пройти весь урок.

  • Sudo некорневые пользователи, настроенный для обеих капель.

  • Ключи SSH для Ansible Droplet для авторизации входа в Droplet развертывания PHP, который можно настроить, следуя https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys—​2 [этот урок] на вашей Ansible Droplet.

Шаг 1 - Установка Ansible

Первым шагом является установка Ansible. Это легко сделать, установив PPA (Personal Package Archive) и установив пакет Ansible с помощью + apt +.

Сначала добавьте PPA с помощью команды + apt-add-repository +.

sudo apt-add-repository ppa:ansible/ansible

Как только это закончится, обновите кеш + apt +.

sudo apt-get update

Наконец, установите Ansible.

sudo apt-get install ansible

После установки Ansible мы создадим новый каталог для работы и настроим базовую конфигурацию. По умолчанию Ansible использует файл hosts, расположенный в + / etc / ansible / hosts +, который содержит все серверы, которыми он управляет. Хотя этот файл подходит для некоторых случаев использования, он глобальный, что здесь не то, что нам нужно.

Для этого урока мы создадим локальный файл hosts и используем его вместо этого. Мы можем сделать это, создав новый файл конфигурации Ansible в нашем рабочем каталоге, который мы можем использовать, чтобы сказать Ansible искать файл hosts в том же каталоге.

Создайте новый каталог (который мы будем использовать до конца этого урока).

mkdir ~/ansible-php

Перейдите в новый каталог.

cd ~/ansible-php/

Создайте новый файл с именем + ansible.cfg + и откройте его для редактирования, используя + nano + или ваш любимый текстовый редактор.

nano ansible.cfg

Добавьте в опцию конфигурации + hostfile + со значением + hosts + в группе + [defaults] +, скопировав следующее в файл + ansible.cfg +.

ansible.cfg

[defaults]
hostfile = hosts

Сохраните и закройте файл + ansible.cfg +. Затем мы создадим файл + hosts +, который будет содержать IP-адрес капли PHP, где мы будем развертывать наше приложение.

nano hosts

Скопируйте нижеприведенное, чтобы добавить в раздел + php +, заменив ` IP-адресом вашего сервера и ` на пользователя sudo, не являющегося пользователем root, который вы создали в предварительных условиях на PHP Droplet.

хостов

[php]
ansible_ssh_user=

Сохраните и закройте файл + hosts +. Давайте выполним простую проверку, чтобы убедиться, что Ansible может подключиться к хосту, как и ожидалось, вызвав модуль + ping + в новой группе + php +.

ansible php -m ping

Вы можете получить проверку подлинности хоста SSH, в зависимости от того, заходили ли вы ранее на этот хост. Пинг должен вернуться с успешным ответом, который выглядит примерно так:

Выход

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

Ansible теперь установлен и настроен; мы можем перейти к настройке нашего веб-сервера.

Шаг 2 - Установка необходимых пакетов

На этом шаге мы установим некоторые необходимые системные пакеты, используя Ansible и + apt +. В частности, мы установим + git +, + nginx +, + sqlite3 +, + mcrypt + и несколько пакетов + php5 - * +.

Прежде чем мы добавим модуль + apt + для установки нужных нам пакетов, нам нужно создать базовую книгу воспроизведения. Мы будем опираться на эту книгу при прохождении учебника. Создайте новую пьесу под названием + php.yml +.

nano php.yml

Вставьте в следующую конфигурацию. В первых двух строках указывается группа хостов, которую мы хотим использовать (+ 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 +, чтобы установить пакеты на Droplet. Не забудьте использовать опцию + - ask-sudo-pass +, если вашему пользователю sudo в PHP Droplet требуется пароль.

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

Шаг 3 - Изменение файлов конфигурации системы

В этом разделе мы изменим некоторые файлы конфигурации системы в PHP Droplet. Наиболее важный параметр конфигурации, который нужно изменить (кроме файлов Nginx, о которых будет рассказано на следующем шаге), это параметр + cgi.fix_pathinfo + в + php5-fpm +, поскольку значение по умолчанию представляет угрозу безопасности.

Сначала мы объясним все разделы, которые мы собираемся добавить в этот файл, а затем включим весь файл + php.yml +, который вы сможете скопировать и вставить.

Модуль lineinfile может использоваться для обеспечения того, чтобы значение конфигурации в файле было именно таким, как мы ожидаем. Это может быть сделано с использованием общего regular выражения, поэтому Ansible может понять большинство форм, в которых этот параметр, вероятно, находится. Нам также потребуется перезапустить + php5-fpm + и + nginx +, чтобы изменения вступили в силу, поэтому нам нужно добавить также два обработчика, в новый раздел + handlers +. Обработчики идеально подходят для этого, так как они запускаются только при изменении задачи. Они также запускаются в конце книги воспроизведения, поэтому несколько задач могут вызывать один и тот же обработчик, и он будет запускаться только один раз.

Раздел для выполнения выше будет выглядеть так:

 - 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

Далее, мы также должны убедиться, что модуль + 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

Наконец, запустите playbook.

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

Теперь в Droplet установлены все необходимые пакеты, а базовая конфигурация настроена и готова к работе.

Шаг 4 - Клонирование Git-репозитория

В этом разделе мы клонируем репозиторий фреймворка Laravel в ваш дроплет с помощью Git. Как и в шаге 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 +, - это исходный репозиторий. В этом случае мы также определим пункт назначения и сообщим Ansible не обновлять хранилище, если оно уже существует, установив + update = no +. Поскольку мы используем Laravel, мы будем использовать URL-адрес репозитория git + https: // github.com / laravel / laravel.git +.

Однако нам нужно запустить задачу как пользователь + www-data, чтобы убедиться, что разрешения правильные. Чтобы сделать это, мы можем сказать Ansible запускать команду от имени определенного пользователя, используя + sudo +. Окончательное задание будет выглядеть так:

- 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

Добавьте вышеупомянутые задачи в playbook; конец файла должен соответствовать следующему:

...

 - 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 +, которая устанавливает все необходимые зависимости и затем выполняет шаги создания проекта, определенные в разделе + post-create-project-cmd + файла + composer.json +. Это лучший способ убедиться, что приложение правильно настроено для первого использования.

Мы можем использовать следующую задачу Ansible для загрузки и установки Composer глобально как + / usr / local / bin / composer +. Затем он будет доступен любому, кто использует дроплет, включая Ansible.

- 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, который мы можем использовать. В нашем случае мы хотим сообщить Composer, где находится наш проект (используя параметр + working_dir +), и запустить команду + create-project +. Нам также необходимо добавить параметр + optimize_autoloader = no +, поскольку этот флаг не поддерживается командой + create-project +. Как и команда + 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

Наконец, запустите playbook.

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

Что произойдет, если мы снова запустим Ansible сейчас? + Composer create-project + будет запущен снова, и в случае Laravel это означает новый + APP_KEY +. Поэтому вместо этого мы хотим, чтобы эта задача запускалась только после нового клона. Мы можем убедиться, что он запускается только один раз, зарегистрировав переменную с результатами задачи + git clone +, а затем проверив эти результаты в задаче + composer create-project +. Если задача + git clone + была Changed, то мы запускаем + composer create-project +, если нет, она пропускается.

  • Примечание: * Похоже, что в некоторых версиях модуля Ansible + composer + есть ошибка, и он может выводить OK вместо Changed, поскольку игнорирует выполнение сценариев, даже если не было установлено никаких зависимостей.

Откройте файл + 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

Затем найдите задачу + 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

Сохраните playbook и запустите его:

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

Теперь Composer перестанет менять + APP_KEY + при каждом запуске.

Шаг 6 - Обновление переменных среды

На этом этапе мы обновим переменные среды для нашего приложения.

Laravel поставляется с файлом по умолчанию + .env +, который устанавливает + APP_ENV + в + local + и + APP_DEBUG + в + true +. Мы хотим поменять их местами на + 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

Сохраните и запустите playbook:

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

Модуль + lineinfile + очень полезен для быстрой настройки любого текстового файла и отлично подходит для правильной установки переменных среды, подобных этой.

Шаг 7 - Настройка Nginx

В этом разделе мы настроим Nginx для обслуживания приложения PHP.

Если вы посещаете свою Droplet в своем веб-браузере сейчас (т.е. + http: /// +), вы увидите страницу по умолчанию Nginx вместо страницы нового проекта Laravel. Это потому, что нам все еще нужно настроить наш веб-сервер Nginx для обслуживания приложения из каталога + / var / www / laravel / public +. Для этого нам нужно обновить конфигурацию Nginx по умолчанию с этим каталогом и добавить поддержку + php-fpm +, чтобы он мог обрабатывать PHP-скрипты.

Создайте новый файл с именем + nginx.conf +:

nano nginx.conf

Сохраните этот блок сервера в этом файле. Вы можете проверить Шаг 4 из https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-14-04#step-four -% E2% 80% 94-configure-nginx-to-use-our-php-processor [это руководство] для получения более подробной информации об этой конфигурации Nginx; нижеприведенные изменения указывают, где находится общедоступный каталог 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 + скопирует один или несколько файлов в * без каких-либо изменений *, а + template + скопирует отдельные файлы и разрешит все переменные в этом файле. Поскольку в нашем конфигурационном файле мы использовали + {{inventory_hostname}} +, мы используем модуль + template +, поэтому он преобразуется в IP-адрес, который мы использовали в файле + hosts +. Таким образом, нам не нужно жестко кодировать файлы конфигурации, которые использует Ansible.

Тем не менее, как обычно при написании заданий, мы должны рассмотреть, что произойдет с Droplet. Поскольку мы меняем конфигурацию 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 + теперь должен выглядеть так:

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

Сохраните и снова запустите playbook:

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

По завершении вернитесь в браузер и обновите страницу. Теперь вы должны увидеть новую страницу проекта Laravel!

Заключение

В этом руководстве рассматривается развертывание приложения PHP с общедоступным репозиторием. Хотя он идеально подходит для изучения принципов работы Ansible, вы не всегда будете работать над полностью открытыми проектами с открытыми репозиториями. Это означает, что вам нужно будет аутентифицировать + git clone + на шаге 3 с вашим личным репозиторием. Это очень легко сделать с помощью ключей SSH.

Например, когда у вас есть ключи развертывания SSH, созданные и установленные в вашем хранилище, вы можете использовать Ansible, чтобы скопировать и настроить их на вашем сервере перед задачей + git clone +:

- 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

Это должно позволить серверу правильно аутентифицировать и развернуть ваше приложение.

«» «»»

Вы только что развернули простое PHP-приложение на веб-сервере Nginx на основе Ubuntu, используя Composer для управления зависимостями! Все это было выполнено без необходимости входа непосредственно в PHP Droplet и запуска одной ручной команды.

Related