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

介绍

本教程介绍使用Ansible配置基本PHP应用程序的过程。本教程结束时的目标是让您新Web服务器为基本的PHP应用程序提供服务,而无需在目标腾讯CVM上运行单个SSH连接或手动命令。

我们将使用Laravel框架作为示例PHP的应用程序,但是如果您已经拥有自己的框架和应用程序,则可以轻松修改这些指令以支持其他框架和应用程序。

先决条件

在本教程中,我们将使用Ansible在Ubuntu 14.04 腾讯CVM上安装和配置Nginx,PHP和其他服务。

要学习本教程,您需要:

  • 我们将用于配置和部署我们的PHP应用程序的任何大小的Ubuntu 14.04 腾讯CVM。整个教程将引用本机的IP地址your_server_ip
  • 一个将用于Ansible的Ubuntu 14.04 腾讯CVM。这也是您将在本教程的整个过程中登录的腾讯CVM。
  • 为两个腾讯CVM配置的Sudo非root用户,没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后在购买服务器
  • Ansible 腾讯CVM的SSH密钥授权在PHP部署腾讯CVM上登录

第一步是安装Ansible。这可以轻松通过用apt来安装PPA(个人包存档)和安装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文件,该文件包含它正在管理的所有服务器。虽然该文件适用于某些用例,但它是全局的,这也不是我们想要的。

在本教程中,我们将创建一个本地hosts文件并使用它。我们可以通过在工作目录中创建一个新的Ansible配置文件来完成此操作,我们可以使用它来告诉Ansible在同一目录中查找hosts文件。

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

mkdir ~/ansible-php

进入新目录。

cd ~/ansible-php/

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

nano ansible.cfg

通过将以下内容复制到文件ansible.cfg中,从而在[defaults]组中添加值为hostshostfile配置文件。

[defaults]
hostfile = hosts

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

nano hosts

复制以下内容以添加部分php,替换your_server_ip为您的服务器IP地址并且将sammy替换为您在PHP 腾讯CVM的先决条件中创建的sudo非root用户。

主机

[php]
your_server_ip ansible_ssh_user=sammy

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

ansible php -m ping

您可能会遇到一个SSH主机身份验证的检查,具体取决于您之前是否曾登录过该主机。ping应该会成功响应,该响应看起来应该像这样:

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

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

第2步 - 安装必需的包

在这一步中,我们将使用Ansible和apt来安装一些必需的系统包。特别是,我们将安装gitnginxsqlite3mcrypt,和一对 php5-* 包。

在我们添加apt模块以安装我们想要的软件包之前,我们需要创建一个基本的playbook。在学习本教程时,我们将以此手册为基础。创建一个名为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以在腾讯CVM上安装软件包。如果您的PHP 腾讯CVM上的sudo用户需要密码,请不要忘记使用该--ask-sudo-pass选项。

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

第3步 - 修改系统配置文件

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

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

lineinfile模块可用于确保文件中的配置值完全符合我们的预期。这可以使用通用正则表达式完成,因此Ansible可以理解参数可能包含的大多数表单。我们还需要重新启动php5-fpmnginx来确保更改生效,因此我们还需要添加两个处理程序,一个新的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错误

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模块已启用。这是通过使用shell任务运行脚本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

腾讯CVM现在已经安装了所有必需的软件包,并且已经准备好了基本配置。

第4步 - 克隆Git存储库

在本节中,我们将使用Git将Laravel框架存储库克隆到腾讯CVM上。与步骤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模块将存储库克隆到腾讯CVM上。这个过程很简单,因为我们通常需要的一个git clone命令就是源存储库。在这种情况下,我们还将定义目标,并告知Ansible如果已存在则不通过设置更新存储库update=no。因为我们使用的是Laravel,我们将使用的git存储库URL 是: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

将上述任务添加到剧本中; 文件的末尾应与以下内容匹配:

...
​
  - 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任务以/usr/local/bin/composer的身份来全局下载和安装Composer 。然后任何使用腾讯CVM的人都可以访问它,包括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任务可能会花费大量时间在新的腾讯CVM上,因为Composer将有一个空缓存,并且需要下载所有新鲜的内容。

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

nano php.yml

tasks部分末尾添加上面的任务,并且在handlers的上面,以便playbook的结尾符合以下内容:

...
​
  - 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任务中检查这些结果来确保它只运行一次。如果git clone任务已更改,那么我们运行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
  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附带一个默认的.env文件,该文件用于设置APP_ENVto localAPP_DEBUGto true。我们想分别用他们俩交换 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文件进行编辑。

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

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

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

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

nano nginx.conf

将此服务器块保存在该文件中。您可以查看本教程的第4步来了解有关此Nginx配置的更多详细信息; 下面的修改明确了Laravel公开目录的位置,并确保Nginx使用我们在hosts文件中定义主机名作为 server_nameinventory_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将复制一个或多个文件而不进行任何更改,同时template复制单个文件并解析文件中的所有变量。因为我们在配置文件中使用过{{ inventory_hostname }},所以我们使用template模块将其解析为我们在hosts文件中使用的IP地址。这样,我们就不需要对Ansible使用的配置文件进行硬编码。

但是,正如编写任务时一样,我们需要考虑腾讯CVM上会发生什么。因为我们正在更改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的Nginx Web服务器上部署了一个基本的PHP应用程序来管理依赖项!所有这些都已完成,无需直接登录到您的PHP腾讯CVM并运行单个手动命令。

更多Ubuntu 教程请前往腾讯云+社区学习更多知识。


参考文献:《How To Deploy a Basic PHP Application Using Ansible on Ubuntu 14.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏博客园迁移

jenkins自动部署应用到tomcat中,编译后shell脚本的简单示例

1.先配置好jenkins需要用到的其他外部组件  jdk,maven,git/svn

28730
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Pydio托管文件共享服务器

随着云的采用增加,越来越多的数据被远程存储。从音乐到图片再到个人文档,很多人都将文件上传到他们不管理的服务器上。如果您希望将文件保存在您控制的服务器上,则可以使...

46200
来自专栏北京马哥教育

HTTP 协议漫谈

简介 网络上已经有不少介绍 HTTP 的好文章,对HTTP的一些细节介绍的比较好,所以本篇文章不会对 HTTP 的细节进行深究,而是从够高和更结构化的角度将 H...

322110
来自专栏耕耘实录

Ansible的安装与使用初探

受控端:192.168.237.202、192.168.237.203(一共2台)

8940
来自专栏Spark学习技巧

Kafka单节点至集群的安装部署及注意事项

kafka简介 kafka的重要作用: 发布和订阅 像消息传递系统一样读写数据流。 处理 编写实时响应事件的可伸缩流处理应用程序 存储系统 将数据流安全地存储...

45270
来自专栏IT技术精选文摘

Nginx入门指南

NGINX 是一款来自俄罗斯的HTTP 和反向代理(reverse proxy)服务器、邮件服务器,以及通用的 TCP/UDP 代理服务器,以其高性能被业界广泛...

233100
来自专栏weixuqin 的专栏

一些杂想(服务器篇)

8420
来自专栏互联网大杂烩

Structs框架

Structs框架结构采用MVC设计模式,同时包含客户端(client),请求以及业务逻辑处理(Business Logic),而MVC模式主要由模型(Mode...

8920
来自专栏FreeBuf

使用CMSTP绕过AppLocker的方法介绍

CMSTP是一个与Microsoft连接管理器配置文件安装程序关联的二进制文件。它接受INF文件,这些文件可以通过恶意命令武器化,以脚本(SCT)和DLL的形式...

12830
来自专栏用户2442861的专栏

每天一个linux命令(61):wget命令

http://www.cnblogs.com/peida/archive/2013/03/18/2965369.html

31120

扫码关注云+社区

领取腾讯云代金券