如何在 Ubuntu 14.04 上使用 Ansible 部署基本 PHP 应用程序

介绍

本教程涵盖了使用 Ansible 提供基本 PHP 应用程序的过程,本教程结束时的目标是让您的新 Web 服务器在目标 Droplet 上运行一个基本的 PHP 应用程序,而无需单一的 SSH 连接或手动命令。

我们将使用Laravel框架(https://github.com/laravel/laravel)作为一个PHP应用程序的例子,但这些指令可以很容易地修改以支持其他框架和应用程序,如果你已经有自己的。

前提条件

对于本教程,我们将使用Ansible在Ubuntu 14.04 Droplet上安装和配置Nginx,PHP和其他服务。本教程基于基本的Ansible知识,所以如果您是Ansible的新人,您可以先阅读此基本的Ansible教程(https://andsky.com/tech/tutorials/how-to-install-and-configure-ansible-on-an-ubuntu-12-04-vps)。

要遵循本教程,您将需要:

步骤 1 - 安装 Ansible

第一步是安装 Ansible. 这是通过安装PPA(个人包存档案)和安装Ansible包的apt来轻松实现的。

首先,使用apt-add-repository命令添加 PPA。

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

一旦完成,更新apt缓存。

1sudo apt-get update

最后,安装 Ansible。

1sudo apt-get install ansible

一旦安装 Ansible,我们将创建一个新的目录来工作,并设置一个基本的配置. 默认情况下,Ansible使用位于 /etc/ansible/hosts 的主机文件,其中包含它管理的所有服务器。

对于本教程,我们将创建一个本地主机文件,并使用它,我们可以通过在我们的工作目录中创建一个新的Ansible配置文件,我们可以使用它告诉Ansible在同一目录中搜索一个主机文件。

创建一个新的目录(我们将用于本教程的其余部分)。

1mkdir ~/ansible-php

移动到新目录。

1cd ~/ansible-php/

创建一个名为ansible.cfg的新文件,并使用nano或您最喜欢的文本编辑器打开它进行编辑。

1nano ansible.cfg

[默认]组中添加hostfile配置选项,将hosts值复制到ansible.cfg文件中。

1[label ansible.cfg]
2[defaults]
3hostfile = hosts

保存并关闭ansible.cfg文件.接下来,我们将创建主机文件,该文件将包含PHP Droplet的IP地址,我们将部署我们的应用程序。

1nano hosts

复制下面的部分,以添加一个php,取代your_server_ip为您的服务器IP地址和sammy为您在PHP Droplet的前提条件中创建的sudo非根用户。

1[label hosts]
2[php]
3your_server_ip ansible_ssh_user=sammy

保存和关闭主机文件. 让我们运行一个简单的检查,以确保Ansible能够按预期连接到主机,通过在新的php组上调用ping模块。

1ansible php -m ping

您可能会收到 SSH 主机身份验证检查,这取决于您是否曾经登录过该主机。

1[label Output]
2111.111.111.111 | success >> {
3    "changed": false,
4    "ping": "pong"
5}

Ansible现在正在安装和配置;我们可以继续设置我们的Web服务器。

步骤 2 — 安装必要的包

在此步骤中,我们将使用 Ansible 和 apt 安装一些所需的系统包,具体来说,我们将安装git,nginx,sqlite3,mcrypt,以及一些php5-* 包。

在我们添加apt模块来安装我们想要的包之前,我们需要创建一个基本的播放簿。

1nano php.yml

插入下面的配置. 第一两个行指定我们想要使用的主机组(‘php’),并确保它默认运行命令与‘sudo’。 其余的添加到一个模块中,我们需要的包。 您可以自定义为自己的应用程序,或使用下面的配置,如果你跟随示例Laravel应用程序。

 1---
 2- hosts: php
 3  sudo: yes
 4
 5  tasks:
 6
 7  - name: install packages
 8    apt: name={{ item }} update_cache=yes state=latest
 9    with_items:
10      - git
11      - mcrypt
12      - nginx
13      - php5-cli
14      - php5-curl
15      - php5-fpm
16      - php5-intl
17      - php5-json
18      - php5-mcrypt
19      - php5-sqlite
20      - sqlite3

保存php.yml文件. 最后,运行ansible-playbook以在Droplet上安装软件包. 如果您的PHP Droplet上的 sudo用户需要密码,请不要忘记使用--ask-sudo-pass选项。

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

步骤3 - 更改系统配置文件

在本节中,我们将修改PHP Droplet上的一些系统配置文件。更改最重要的配置选项(除了Nginx的文件,这将在以后的步骤中被覆盖)是php5-fpm中的cgi.fix_pathinfo选项,因为默认值是一种安全风险。

我们首先将解释我们将添加到此文件的所有部分,然后包括整个php.yml文件,您可以复制和粘贴。

线性文件模块可以用来确保文件中的配置值与我们所期望的完全一致. 这可以用一个通用的正则表达式来完成,因此Ansible可以理解参数可能包含的大多数形式. 我们还需要重新启动php5-fpm'和nginx',以确保变化生效,因此我们需要在新的`手 ' 部分增加两个处理器。 处理器是完美的,因为只有在任务改变时才被发射. 它们也运行在游戏本末端,因此多个任务可以叫同一位处理器,它只会跑一次.

做上面的部分将看起来像这样:

 1- name: ensure php5-fpm cgi.fix_pathinfo=0
 2    lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
 3    notify:
 4      - restart php5-fpm
 5      - restart nginx
 6
 7  handlers:
 8    - name: restart php5-fpm
 9      service: name=php5-fpm state=restarted
10
11    - name: restart nginx
12      service: name=nginx state=restarted

<$>[注意] [标签: Ansible 版本 1.9.1 错误]在 Ansible 版本 1.9.1 中存在一个错误,该错误阻止了使用服务模块重新启动php5-fpm,正如我们在我们的处理器中所使用的那样。

在发布修复之前,您可以通过将重新启动 php5-fpm处理器从使用服务命令更改为使用命令来处理这个问题,如下:

1- name: restart php5-fpm
2      shell: service php5-fpm restart

这将绕过问题,并正确地重新启动php5-fpm。

接下来,我们还需要确保php5-mcrypt模块已启用,这样做是通过运行php5enmod脚本与壳任务,并检查20-mcrypt.ini文件在启用时处于正确的位置。

1- name: enable php5 mcrypt module
2    shell: php5enmod mcrypt
3    args:
4      creates: /etc/php5/cli/conf.d/20-mcrypt.ini

现在,打开php.yml重新编辑。

1nano php.yml

添加上面的任务和处理器,以便文件匹配下面的任务:

 1---
 2- hosts: php
 3  sudo: yes
 4
 5  tasks:
 6
 7  - name: install packages
 8    apt: name={{ item }} update_cache=yes state=latest
 9    with_items:
10      - git
11      - mcrypt
12      - nginx
13      - php5-cli
14      - php5-curl
15      - php5-fpm
16      - php5-intl
17      - php5-json
18      - php5-mcrypt
19      - php5-sqlite
20      - sqlite3
21
22  - name: ensure php5-fpm cgi.fix_pathinfo=0
23    lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
24    notify:
25      - restart php5-fpm
26      - restart nginx
27
28  - name: enable php5 mcrypt module
29    shell: php5enmod mcrypt
30    args:
31      creates: /etc/php5/cli/conf.d/20-mcrypt.ini
32
33  handlers:
34    - name: restart php5-fpm
35      service: name=php5-fpm state=restarted
36
37    - name: restart nginx
38      service: name=nginx state=restarted

最后,点击播放本。

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

Droplet 现在已经安装了所有所需的包和基本配置,并做好了准备。

第4步:克隆Git存储库

在本节中,我们将使用Git将Laravel框架存储库克隆到我们的Droplet中,就像在第三步中一样,我们将解释我们将添加到播放簿的所有部分,然后包括整个php.yml文件,您可以复制和粘贴。

在我们克隆我们的 Git 存储库之前,我们需要确保 /var/www 存在。

1- name: create /var/www/ directory
2  file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700

正如上面提到的,我们需要使用 Git 模块来将存储库克隆到我们的 Droplet. 这个过程很简单,因为我们通常只需要一个git clone命令是源存储库。 在这种情况下,我们还会定义目的地,并告诉 Ansible不要通过设置update=no来更新存储库,如果已经存在的话。 因为我们正在使用 Laravel,我们将使用的 git 存储库 URL是https://github.com/laravel/laravel.git

但是,我们需要作为www-data用户运行任务,以确保权限是正确的。 要做到这一点,我们可以告诉Ansible使用sudo来运行命令。

1- name: Clone git repository
2  git: >
3    dest=/var/www/laravel
4    repo=https://github.com/laravel/laravel.git
5    update=no
6  sudo: yes
7  sudo_user: www-data

注意 :对于基于 SSH 的存储库,您可以添加 `accept_hostkey=yes' 以防止 SSH 主机验证挂起任务。

如前所述,打开php.yml文件进行编辑。

1nano php.yml

将上述任务添加到播放簿中;文件的结尾应如下:

 1...
 2
 3  - name: enable php5 mcrypt module
 4    shell: php5enmod mcrypt
 5    args:
 6      creates: /etc/php5/cli/conf.d/20-mcrypt.ini
 7
 8  - name: create /var/www/ directory
 9    file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700
10
11  - name: Clone git repository
12    git: >
13      dest=/var/www/laravel
14      repo=https://github.com/laravel/laravel.git
15      update=no
16    sudo: yes
17    sudo_user: www-data
18
19  handlers:
20    - name: restart php5-fpm
21      service: name=php5-fpm state=restarted
22
23    - name: restart nginx
24      service: name=nginx state=restarted

保存并关闭播放簿,然后运行它。

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

1- name: install composer
2  shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
3  args:
4    creates: /usr/local/bin/composer

有了 Composer 安装,我们可以使用一个 Composer 模块。在我们的情况下,我们希望告诉 Composer 我们的项目所在位置(使用),并运行create-project命令。我们还需要添加optimize_autoloader=no参数,因为这个标志不受create-project命令的支持。像git命令一样,我们也希望将此命令作为www-data用户运行,以确保权限有效。

1- name: composer create-project
2  composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
3  sudo: yes
4  sudo_user: www-data

注意 :在新鲜的 Droplet 上,创建项目的任务可能需要相当长的时间,因为 Composer 将有空缓存,并且需要下载新鲜的内容。

现在,打开php.yml文件进行编辑。

1nano php.yml

任务部分的末尾,在处理器上方添加上述任务,以便玩本的末尾匹配如下:

 1...
 2
 3  - name: Clone git repository
 4    git: >
 5      dest=/var/www/laravel
 6      repo=https://github.com/laravel/laravel.git
 7      update=no
 8    sudo: yes
 9    sudo_user: www-data
10
11  - name: install composer
12    shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
13    args:
14      creates: /usr/local/bin/composer
15
16  - name: composer create-project
17    composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
18    sudo: yes
19    sudo_user: www-data
20
21  handlers:
22    - name: restart php5-fpm
23      service: name=php5-fpm state=restarted
24
25    - name: restart nginx
26      service: name=nginx state=restarted

最后,点击播放本。

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

如果我们再次运行Ansible现在会发生什么? 共同创造-项目 ' 将再次运行,就Laravel而言,这意味着一个新的APP_KEY'。 所以我们想要的就是把任务设定在 新的克隆人之后。 我们只能通过将一个变量与 " git Clone " 任务的结果一起登记,然后在 " composer Creat-project " 任务范围内检查这些结果,来确保运行一次。 如果 " git Clone " 任务是_Changed_,那么我们运行 " composer Creat-project " ,如果不是,它就被跳过.

注意: 某些版本的 Ansible composer 模块似乎存在一个错误,它可能会输出 OK 而不是 Changed,因为它忽略了即使没有安装依赖性,也执行了脚本。

打开php.yml文件进行编辑。

1nano php.yml

添加注册选项以将任务的结果保存到克隆变量中,如下:

1- name: Clone git repository
2  git: >
3    dest=/var/www/laravel
4    repo=https://github.com/laravel/laravel.git
5    update=no
6  sudo: yes
7  sudo_user: www-data
8  register: cloned

接下来,找到创作者创建项目任务. 添加何时选项来检查克隆变量,看看它是否已更改。

1- name: composer create-project
2  composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
3  sudo: yes
4  sudo_user: www-data
5  when: cloned|changed

保存 playbook,然后运行它:

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

现在,Composer 将停止在每次运行时更改APP_KEY

第6步:更新环境变量

在此步骤中,我们将更新我们的应用程序的环境变量。

Laravel 配备了默认 .env 文件,将 APP_ENV 设置为 本地APP_DEBUG 设置为 true. 我们要分别将它们交换为 productionfalse

1- name: set APP_DEBUG=false
2  lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
3
4- name: set APP_ENV=production
5  lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production

打开php.yml文件进行编辑。

1nano php.yml

将此任务添加到播放簿中,该文件的结尾应如下:

 1...
 2
 3  - name: composer create-project
 4    composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
 5    sudo: yes
 6    sudo_user: www-data
 7    when: cloned|changed
 8
 9  - name: set APP_DEBUG=false
10    lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
11
12  - name: set APP_ENV=production
13    lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production
14
15  handlers:
16    - name: restart php5-fpm
17      service: name=php5-fpm state=restarted
18
19    - name: restart nginx
20      service: name=nginx state=restarted

保存并运行 Playbook:

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

lineinfile模块对于任何文本文件的快速调整非常有用,并且非常适合确保这样的环境变量正确设置。

第7步:配置 Nginx

在本节中,我们将配置一个 Nginx 来服务 PHP 应用程序。

如果您现在访问您的 Droplet 在您的 Web 浏览器中(即 http://your_server_ip/),您将看到 Nginx 默认页面而不是 Laravel 新项目页面. 这是因为我们仍然需要配置我们的 Nginx Web 服务器来从 /var/www/laravel/public 目录中服务应用程序。 为了做到这一点,我们需要更新我们的 Nginx 默认配置与该目录,并添加对 php-fpm 的支持,以便它可以处理 PHP 脚本。

创建一个名为「nginx.conf」的新文件:

1nano nginx.conf

在文件中保存此服务器块 。 您可以检查 [此教程] (https://andsky.com/tech/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) 步骤 4, 了解关于 Nginx 配置的更多细节; 下面的修改是指定 Laravel 公共目录的位置, 并确保 Nginx 使用 hosts 文件所定义的主机名为 server_name , 其变量为instory_ hostname .

 1[label nginx.conf]
 2server {
 3    listen 80 default_server;
 4    listen [::]:80 default_server ipv6only=on;
 5
 6    root /var/www/laravel/public;
 7    index index.php index.html index.htm;
 8
 9    server_name {{ inventory_hostname }};
10
11    location / {
12        try_files $uri $uri/ =404;
13    }
14
15    error_page 404 /404.html;
16    error_page 500 502 503 504 /50x.html;
17    location = /50x.html {
18        root /var/www/laravel/public;
19    }
20
21    location ~ \.php$ {
22        try_files $uri =404;
23        fastcgi_split_path_info ^(.+\.php)(/.+)$;
24        fastcgi_pass unix:/var/run/php5-fpm.sock;
25        fastcgi_index index.php;
26        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
27        include fastcgi_params;
28    }
29}

保存并关闭nginx.conf文件。

现在,我们可以使用模板模块来推动我们的新配置文件跨越. " 超时 " 模块的外观和声音可能与 " 复制 " 模块非常相近,但差异很大。 复制'将复制一个或一个以上的文件,横跨**,不作任何修改** ,而复制'将复制一个文件,并解决文件中的所有变量。 因为我们在配置文件中使用了QQ目录_hostname }}`,所以我们使用"template"模块,从而解入我们在"hosts"文件中使用的IP地址. 这样,我们不需要硬编码Ansible使用的配置文件.

但是,通常在写作时,我们需要考虑在Droplet上会发生什么。由于我们正在改变 Nginx 配置,我们需要重新启动 Nginx 和php-fpm

1- name: Configure nginx
2  template: src=nginx.conf dest=/etc/nginx/sites-available/default
3  notify:
4    - restart php5-fpm
5    - restart nginx

打开您的php.yml文件:

1nano php.yml

在任务部分的末尾添加这个 nginx 任务. 整个 php.yml 文件现在应该是这样的:

 1[label php.yml]
 2---
 3- hosts: php
 4  sudo: yes
 5
 6  tasks:
 7
 8  - name: install packages
 9    apt: name={{ item }} update_cache=yes state=latest
10    with_items:
11      - git
12      - mcrypt
13      - nginx
14      - php5-cli
15      - php5-curl
16      - php5-fpm
17      - php5-intl
18      - php5-json
19      - php5-mcrypt
20      - php5-sqlite
21      - sqlite3
22
23  - name: ensure php5-fpm cgi.fix_pathinfo=0
24    lineinfile: dest=/etc/php5/fpm/php.ini regexp='^(.*)cgi.fix_pathinfo=' line=cgi.fix_pathinfo=0
25    notify:
26      - restart php5-fpm
27      - restart nginx
28
29  - name: enable php5 mcrypt module
30    shell: php5enmod mcrypt
31    args:
32      creates: /etc/php5/cli/conf.d/20-mcrypt.ini
33
34  - name: create /var/www/ directory
35    file: dest=/var/www/ state=directory owner=www-data group=www-data mode=0700
36
37  - name: Clone git repository
38    git: >
39      dest=/var/www/laravel
40      repo=https://github.com/laravel/laravel.git
41      update=no
42    sudo: yes
43    sudo_user: www-data
44    register: cloned
45
46  - name: install composer
47    shell: curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
48    args:
49      creates: /usr/local/bin/composer
50
51  - name: composer create-project
52    composer: command=create-project working_dir=/var/www/laravel optimize_autoloader=no
53    sudo: yes
54    sudo_user: www-data
55    when: cloned|changed
56
57  - name: set APP_DEBUG=false
58    lineinfile: dest=/var/www/laravel/.env regexp='^APP_DEBUG=' line=APP_DEBUG=false
59
60  - name: set APP_ENV=production
61    lineinfile: dest=/var/www/laravel/.env regexp='^APP_ENV=' line=APP_ENV=production
62
63  - name: Configure nginx
64    template: src=nginx.conf dest=/etc/nginx/sites-available/default
65    notify:
66      - restart php5-fpm
67      - restart nginx
68
69  handlers:
70    - name: restart php5-fpm
71      service: name=php5-fpm state=restarted
72
73    - name: restart nginx
74      service: name=nginx state=restarted

保存并重新运行播放簿:

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

一旦完成,回到您的浏览器并更新. 您现在应该看到Laravel新项目页面!

结论

本教程涵盖了部署PHP应用程序与公共存储库。虽然它是完美的学习如何Ansible工作,你不会总是工作在完全开源的项目与开放的存储库. 这意味着你需要在步骤3与你的私人存储库验证git克隆

例如,一旦您的 SSH 部署密钥创建并设置到您的存储库中,您可以使用 Ansible 将它们复制并配置到您的服务器上,然后执行git clone任务:

1- name: create /var/www/.ssh/ directory
2  file: dest=/var/www/.ssh/ state=directory owner=www-data group=www-data mode=0700
3
4- name: copy private ssh key
5  copy: src=deploykey_rsa dest=/var/www/.ssh/id_rsa owner=www-data group=www-data mode=0600

这应该允许服务器正确验证和部署您的应用程序。


您刚刚在基于Ubuntu的Nginx网络服务器上部署了一个基本的PHP应用程序,使用Composer来管理依赖! 所有这些都完成了,无需直接登录PHP Droplet并运行单个手动命令。

Published At
Categories with 技术
comments powered by Disqus