• 用tsuru部署PHP应用
  • 概述
  • 在tsuru中创建应用
  • 应用的代码
  • 通过Git部署
  • 列出依赖
  • 运行应用
  • 使用服务
  • 定制平台
  • 进一步探索

    用tsuru部署PHP应用

    概述

    本文档是在tsuru中部署一个简单的PHP应用的实战指南。例子应用是一个关联MySQL服务的简单Wordpress项目。适用于任何基于apache的php应用。

    在tsuru中创建应用

    使用app-create命令创建应用:

    1. $ tsuru app-create <app-name> <app-platform>

    对于PHP来说,应用平台是,你猜,php!让我们脑洞大开,开发一个从未有人做过的教学应用:一个博客,而且它的名字也应该是很有创意,让我们叫它blog

    1. $ tsuru app-create blog php

    使用platform-list命令列出所有的可用的平台。使用app-list查看你所有的应用。

    1. $ tsuru app-list
    2. +-------------+-------------------------+--------------------------+
    3. | Application | Units State Summary | Address |
    4. +-------------+-------------------------+--------------------------+
    5. | blog | 0 of 0 units in-service | blog.192.168.50.4.nip.io |
    6. +-------------+-------------------------+--------------------------+

    应用的代码

    本文档不会专注于介绍如何用php实现博客,你可以从wordpress下载完整源码:http://wordpress.org/latest.zip。 下面是在项目中要做的事情:

    1. # Download and unpack wordpress
    2. $ wget http://wordpress.org/latest.zip
    3. $ unzip latest.zip
    4. # Preparing wordpress for tsuru
    5. $ cd wordpress
    6. # Notify tsuru about the necessary packages
    7. $ echo php5-mysql > requirements.apt
    8. # Preparing the application to receive the tsuru environment related to the mysql service
    9. $ sed "s/'database_name_here'/getenv('MYSQL_DATABASE_NAME')/; \
    10. s/'username_here'/getenv('MYSQL_USER')/; \
    11. s/'localhost'/getenv('MYSQL_HOST')/; \
    12. s/'password_here'/getenv('MYSQL_PASSWORD')/" \
    13. wp-config-sample.php > wp-config.php
    14. # Creating a local Git repository
    15. $ git init
    16. $ git add .
    17. $ git commit -m 'initial project version'

    通过Git部署

    在创建新的应用时,tsuru会显示你应该使用的Git远程分支。用app-info命令可以获得其信息:

    1. $ tsuru app-info --app blog
    2. Application: blog
    3. Repository: git@192.168.50.4.nip.io:blog.git
    4. Platform: php
    5. Teams: admin
    6. Address: blog.192.168.50.4.nip.io
    7. Owner: admin@example.com
    8. Team owner: admin
    9. Deploys: 0
    10. Pool: theonepool
    11. App Plan:
    12. +---------------+--------+------+-----------+--------+---------+
    13. | Name | Memory | Swap | Cpu Share | Router | Default |
    14. +---------------+--------+------+-----------+--------+---------+
    15. | autogenerated | 0 MB | 0 MB | 100 | | false |
    16. +---------------+--------+------+-----------+--------+---------+

    Git远程分支被用来通过Git部署应用。当修改被推送到tsuru远程分支时,项目同时也被部署:

    1. $ git push git@192.168.50.4.nip.io:blog.git master
    2. Counting objects: 1295, done.
    3. Delta compression using up to 4 threads.
    4. Compressing objects: 100% (1271/1271), done.
    5. Writing objects: 100% (1295/1295), 6.09 MiB | 5.65 MiB/s, done.
    6. Total 1295 (delta 102), reused 0 (delta 0)
    7. remote: text
    8. remote: Deploying the PHP application...
    9. remote: tar: Removing leading `/' from member names
    10. #########################################
    11. # OMIT DEPENDENCIES STEPS (see below) #
    12. #########################################
    13. remote:
    14. remote: ---- Building application image ----
    15. remote: ---> Sending image to repository (51.40MB)
    16. remote: ---> Cleaning up
    17. remote:
    18. remote: ---- Starting 1 new unit ----
    19. remote: ---> Started unit 027c2a31a0...
    20. remote:
    21. remote: ---- Binding and checking 1 new units ----
    22. remote: ---> Bound and checked unit 027c2a31a0
    23. remote:
    24. remote: ---- Adding routes to 1 new units ----
    25. remote: ---> Added route to unit 027c2a31a0
    26. remote:
    27. remote: OK
    28. To git@192.168.50.4.nip.io:blog.git
    29. * [new branch] master -> master

    如果遇到"Permission denied (publickey)."的错误,请确保你是团队一员并把公钥加到tsuru中。用key-add命令添加公钥:

    1. $ tsuru key-add mykey ~/.ssh/id_dsa.pub

    使用git remote add命令来避免每次push代码时都要输入整个远程仓库的链接:

    1. $ git remote add tsuru git@192.168.50.4.nip.io:blog.git

    然后运行:

    1. $ git push tsuru master
    2. Everything up-to-date

    从此之后就可以省略掉—app标记:

    1. $ tsuru app-info
    2. Application: blog
    3. Repository: git@192.168.50.4.nip.io:blog.git
    4. Platform: php
    5. Teams: admin
    6. Address: blog.192.168.50.4.nip.io
    7. Owner: admin@example.com
    8. Team owner: admin
    9. Deploys: 1
    10. Pool: theonepool
    11. Units: 1
    12. +------------+---------+
    13. | Unit | State |
    14. +------------+---------+
    15. | 027c2a31a0 | started |
    16. +------------+---------+
    17. App Plan:
    18. +---------------+--------+------+-----------+--------+---------+
    19. | Name | Memory | Swap | Cpu Share | Router | Default |
    20. +---------------+--------+------+-----------+--------+---------+
    21. | autogenerated | 0 MB | 0 MB | 100 | | false |
    22. +---------------+--------+------+-----------+--------+---------+

    列出依赖

    在上一个部分我们忽略了部署过程的依赖。在tsuru中,一个应用可以有两种依赖:

    • 操作系统级别的依赖, 以底层操作系统使用的包管理器为代表(比如: yumapt-get);
    • 平台依赖, 以平台/语言依赖的包管理工具为代表(在Python中是pip)。
      所有的apt-get依赖必须在requirements.apt文件中指定,放在应用的根目录,同理,pip的依赖也必须放在应用根目录名为requirements.txt的文件中。因为要用PHP连接MySQL,我们只需要用apt-get安装php5-mysql包,因此requirements.apt内容如下:
    1. php5-mysql

    下面是安装这些依赖的完整输出:

    1. % git push tsuru master
    2. #####################################
    3. # OMIT #
    4. #####################################
    5. Counting objects: 1155, done.
    6. Delta compression using up to 4 threads.
    7. Compressing objects: 100% (1124/1124), done.
    8. Writing objects: 100% (1155/1155), 4.01 MiB | 327 KiB/s, done.
    9. Total 1155 (delta 65), reused 0 (delta 0)
    10. remote: Cloning into '/home/application/current'...
    11. remote: Reading package lists...
    12. remote: Building dependency tree...
    13. remote: Reading state information...
    14. remote: The following extra packages will be installed:
    15. remote: libmysqlclient18 mysql-common
    16. remote: The following NEW packages will be installed:
    17. remote: libmysqlclient18 mysql-common php5-mysql
    18. remote: 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
    19. remote: Need to get 1042 kB of archives.
    20. remote: After this operation, 3928 kB of additional disk space will be used.
    21. remote: Get:1 http://archive.ubuntu.com/ubuntu/ quantal/main mysql-common all 5.5.27-0ubuntu2 [13.7 kB]
    22. remote: Get:2 http://archive.ubuntu.com/ubuntu/ quantal/main libmysqlclient18 amd64 5.5.27-0ubuntu2 [949 kB]
    23. remote: Get:3 http://archive.ubuntu.com/ubuntu/ quantal/main php5-mysql amd64 5.4.6-1ubuntu1 [79.0 kB]
    24. remote: Fetched 1042 kB in 1s (739 kB/s)
    25. remote: Selecting previously unselected package mysql-common.
    26. remote: (Reading database ... 23874 files and directories currently installed.)
    27. remote: Unpacking mysql-common (from .../mysql-common_5.5.27-0ubuntu2_all.deb) ...
    28. remote: Selecting previously unselected package libmysqlclient18:amd64.
    29. remote: Unpacking libmysqlclient18:amd64 (from .../libmysqlclient18_5.5.27-0ubuntu2_amd64.deb) ...
    30. remote: Selecting previously unselected package php5-mysql.
    31. remote: Unpacking php5-mysql (from .../php5-mysql_5.4.6-1ubuntu1_amd64.deb) ...
    32. remote: Processing triggers for libapache2-mod-php5 ...
    33. remote: * Reloading web server config
    34. remote: ...done.
    35. remote: Setting up mysql-common (5.5.27-0ubuntu2) ...
    36. remote: Setting up libmysqlclient18:amd64 (5.5.27-0ubuntu2) ...
    37. remote: Setting up php5-mysql (5.4.6-1ubuntu1) ...
    38. remote: Processing triggers for libc-bin ...
    39. remote: ldconfig deferred processing now taking place
    40. remote: Processing triggers for libapache2-mod-php5 ...
    41. remote: * Reloading web server config
    42. remote: ...done.
    43. remote: sudo: unable to resolve host 8cf20f4da877
    44. remote: sudo: unable to resolve host 8cf20f4da877
    45. remote: debconf: unable to initialize frontend: Dialog
    46. remote: debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
    47. remote: debconf: falling back to frontend: Readline
    48. remote: debconf: unable to initialize frontend: Dialog
    49. remote: debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
    50. remote: debconf: falling back to frontend: Readline
    51. remote:
    52. remote: Creating config file /etc/php5/mods-available/mysql.ini with new version
    53. remote: debconf: unable to initialize frontend: Dialog
    54. remote: debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
    55. remote: debconf: falling back to frontend: Readline
    56. remote:
    57. remote: Creating config file /etc/php5/mods-available/mysqli.ini with new version
    58. remote: debconf: unable to initialize frontend: Dialog
    59. remote: debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
    60. remote: debconf: falling back to frontend: Readline
    61. remote:
    62. remote: Creating config file /etc/php5/mods-available/pdo_mysql.ini with new version
    63. remote:
    64. remote: ---> App will be restarted, please check its log for more details...
    65. remote:
    66. To git@192.168.50.4.nip.io:blog.git
    67. * [new branch] master -> master

    运行应用

    如你所见,部署的输出信息中有一个步骤叫做"重启你的应用"。在这个步骤中,如果应用在运行,tsuru会重启它,如果没有运行,tsuru会启动它。应用部署成功,可以通过app-list命令获得IP或者主机名,然后用浏览器去访问。比如,在下面的列表中:

    1. $ tsuru app-list
    2. +-------------+-------------------------+---------------------+
    3. | Application | Units State Summary | Address |
    4. +-------------+-------------------------+---------------------+
    5. | blog | 1 of 1 units in-service | blog.cloud.tsuru.io |
    6. +-------------+-------------------------+---------------------+

    使用服务

    php已经在运行,可以用过浏览器访问应用,但是会遇到一个数据库连接错误:"Error establishing a database connection"。它的意思是应用无法连接到MySQL。这是因为我们不应该在本地连接MySQL,而是应该使用服务。服务的工作流分为下面两步:

    . 创建一个服务的实例. 将服务的实例绑定到应用

    但是如何知道哪些服务是可用的呢?这很简单,运行service-list命令:

    1. $ tsuru service-list
    2. +----------------+-----------+
    3. | Services | Instances |
    4. +----------------+-----------+
    5. | elastic-search | |
    6. | mysql | |
    7. +----------------+-----------+

    上面service-list的输出说明有两个可用的服务:"elastic-search"和"mysql",并且没有实例。通过service-add命令可以创建MySQL实例:

    1. $ tsuru service-add mysql blogsql
    2. Service successfully added.

    现在,如果再次运行service-list命令,可以从输出中看到新的服务实例:

    1. $ tsuru service-list
    2. +----------------+-----------+
    3. | Services | Instances |
    4. +----------------+-----------+
    5. | elastic-search | |
    6. | mysql | blogsql |
    7. +----------------+-----------+

    使用service-bind命令将服务实例绑定到应用:

    1. $ tsuru service-bind mysql blogsql
    2. Instance blogsql is now bound to the app blog.
    3. The following environment variables are now available for use in your app:
    4. - MYSQL_PORT
    5. - MYSQL_PASSWORD
    6. - MYSQL_USER
    7. - MYSQL_HOST
    8. - MYSQL_DATABASE_NAME
    9. For more details, please check the documentation for the service, using service-doc command.

    从绑定的输出中我们看出,可以通过环境变量来连接MySQL服务器。下一步就是更新wp-config.php,使用这些环境变量去连接数据库:

    1. $ grep getenv wp-config.php
    2. define('DB_NAME', getenv('MYSQL_DATABASE_NAME'));
    3. define('DB_USER', getenv('MYSQL_USER'));
    4. define('DB_PASSWORD', getenv('MYSQL_PASSWORD'));
    5. define('DB_HOST', getenv('MYSQL_HOST'));

    可以通过在代码库中安装插件来扩展wordress应用。下面的例子中,我们为wordpress添加了Amazon S3的功能,只需要安装两个插件:Amazon S3 and CloudfrontAmazon Web Services。这是在tsuru保存内容的正确方式。

    1. $ cd wp-content/plugins/
    2. $ wget http://downloads.wordpress.org/plugin/amazon-web-services.0.1.zip
    3. $ wget http://downloads.wordpress.org/plugin/amazon-s3-and-cloudfront.0.6.1.zip
    4. $ unzip amazon-web-services.0.1.zip
    5. $ unzip amazon-s3-and-cloudfront.0.6.1.zip
    6. $ rm -f amazon-web-services.0.1.zip amazon-s3-and-cloudfront.0.6.1.zip
    7. $ git add amazon-web-services/ amazon-s3-and-cloudfront/

    现在需要将AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY两个amazon需要的环境变量添加到wp-config.php文件中。可以像下面一样将这些环境变量放在WP_DEBUG后面:

    1. $ grep -A2 define.*WP_DEBUG wp-config.php
    2. define('WP_DEBUG', false);
    3. define('AWS_ACCESS_KEY_ID', getenv('AWS_ACCESS_KEY_ID'));
    4. define('AWS_SECRET_ACCESS_KEY', getenv('AWS_SECRET_ACCESS_KEY'));
    5. $ git add wp-config.php
    6. $ git commit -m 'adding plugins for S3'
    7. $ git push tsuru master

    然后,像下面一样通过tsuru env-set给这些环境变量设置正确的值:

    1. $ tsuru env-set AWS_ACCESS_KEY_ID="xxx" AWS_SECRET_ACCESS_KEY="xxxxx" -a blog

    完成!现在我们有了一个部署在tsuru上,同时使用MySQL服务以及S3支持的PHP项目。

    定制平台

    PHP平台支持对前端和解释器的定制。要了解更多细节,请查看平台的介绍文档.

    进一步探索

    更多信息,可以查看tsuru文档,或者阅读tsuru命令完全使用指南。

    原文: http://doc.oschina.net/tsuru-paas?t=52824