Build your PHP application
        on Heroku
   Ronny Wang @ PIXNET
PaaS

Platform-as-a-Service




                        1
Deploy… And Run!




                   2
Install…Config…

Linux? FreeBSD? Debian? Ubuntu?
RPM? Ports? Package? Apt? yum?
         Apache? Nginx?
  PHP-cgi? FastCGI? PHP-Fpm?


                                  3
Heroku

her-OH-koo




             4
2007 ~




         5
Amazon Web Service US-east-1

       ~200ms latency




                               6
Lots of Addons




                 7
Easy scale




             8
PostgreSQL




             9
Free!!!

On a small scale…




                    10
What’s Stack?

Aspen, Bamboo, Cedar




                       11
Stack Cedar

Clojure Facebook Java Spring
  or Play Node.js Python or
 Django Ruby or Rails Scala


                               12
No PHP?




          13
Facebook and Heroku

http://blog.heroku.com/archives/2011/9/15/facebook/




                                                      14
What’s Dyno?




               15
Web, worker, cron, run process

          All are dynos




                                 16
0.05US$/hour/dyno

= 1000NT$/month/dyno




                       17
750hours free!




                 18
Heroku toolbelt

https://toolbelt.heroku.com
Heroku Client, Foreman, Git



                              19
First: heroku login




                      20
heroku create

# heroku create
Creating evening-earth-7959... done, stack is cedar
http://evening-earth-7959.herokuapp.com/ |
git@heroku.com:evening-earth-7959.git
Git remote heroku added




                                                      21
Add index.php

<?php
echo 'Hello World';



                        22
git commit index.php –m ‘add Hello World’




                                            23
git push
Counting objects: 3, done.
Writing objects: 100% (3/3), 250bytes, done.
Total 3 (delta 0), reused 0(delta 0)
-----> Heroku receiving push
-----> PHP app detected
-----> Bundling Apache 2.2.12
-----> Bundling PHP 5.3.10
-----> Discovering process types
Procfile declares types -> (none)
Default types for PHP -> web
-----> Compiled slug size in 21.5MB
-----> Launching... done, v3
http://evening-earth-7959.herokuapp.com deployed to
Heroku                                                24
25
heroku logs
2012-08-16T10:59:15+00:00 app[web.1]: [Thu Aug 16 10:59:15 2012] [notice]
Apache/2.2.22 (Unix) PHP/5.3.10 configured -- resuming normal operations
2012-08-16T10:59:16+00:00 app[web.1]: [Thu Aug 16 10:59:16 2012] [error]
server reached MaxClients setting, consider raising the MaxClients setting
2012-08-16T11:03:16+00:00 app[web.1]: 10.189.119.194 - -
[16/Aug/2012:11:03:15 +0000] "GET / HTTP/1.1" 200 14
2012-08-16T11:03:16+00:00 app[web.1]: 10.217.59.175 - -
[16/Aug/2012:11:03:15 +0000] "GET /favicon.ico HTTP/1.1" 200 1025




                                                                             26
Database: PostgreSQL

https://postgres.heroku.com/




                               27
Starter databases

DevPlan Free 10K rows
BasicPlan $9/month 10M rows



                              28
Production databases


        Size: up to 1TB
 Crane 400MB Cache $50/month
Kappa 800MB Cache $100/month
              :     :
Baku 34GB Cache $3200/month
Mecha 68GB Cache $6400/month

                               29
heroku config

> heroku config
DATABASE_URL:       postgres://foofoofoo:barbarbar@ec2-123-123-123-
123.compute-1.amazonaws.com/foofoofoo
SHARED_DATABASE_URL: postgres://foofoofoo:barbarbar@ec2-123-123-
123-123.compute-1.amazonaws.com/foofoofoo




                                                                      30
if (!getenv('DATABASE_URL')) {
    die('Need DATABASE_URL');
}
if (!preg_match(‘#postgres://([^:]*):([^@]*)@([^/:]*)(:d+)?/(.*)#’,
strval(getenv('DATABASE_URL')), $matches)) {
    die('Unknown DATABASE_URL');
}
$user = $matches[1];
$pass = $matches[2];
$host = $matches[3];
$port = ltrim($matches[4], ':') ?: 1486;
$dbname = $matches[5];
$dbconn = pg_connect("host={$host} port={$port} dbname={$dbname}
user={$user} password=${pass} sslmode=require options='--
client_encoding=UTF8'") or die('Could not connect: ' . pg_last_error());

pg_execute($dbconn, "SELECT * FROM table");


#https://github.com/pixnet/pixframework-heroku/blob/master/init.inc.php

                                                                           31
heroku run

Start a dyno and run command




                               32
heroku config:set LD_LIBRARY_PATH=/app/php/ext:/app/apache/lib




                                                                 33
heroku run "~/bin/php ~/www/script.php"




                                          34
Heroku Scheduler

 Schedule your task




                      35
Daily, hourly, 10 minutes




                            36
37
$ ~/bin/php ~/www/cron.php




                             38
Heroku worker




                39
File: Procfile

worker: ~/bin/php ~/www/worker.php




                                     40
heroku ps:scale worker=N




                           41
heroku ps
# heroku ps
=== web: `sh boot.sh`
web.1: starting for 4s

=== worker: `~/bin/php ~/www/test.php`
worker.1: up for 25s
#

                                         42
heroku logs –p worker -t
# heroku logs –p worker –t
2012-08-14T08:21:29+00:00 heroku[worker.1]: State changed from up to down
2012-08-14T08:21:31+00:00 heroku[worker.1]: Stopping all processes with
SIGTERM
2012-08-14T08:21:33+00:00 heroku[worker.1]: Process exited with status 143
2012-08-16T10:58:48+00:00 heroku[worker.1]: Starting process with command
`while true; do ~/bin/php ~/www/test.php; sleep 1; done`
2012-08-16T10:58:49+00:00 heroku[worker.1]: State changed from starting to
up




                                                                             43
• Procfile
worker: while true; do ~/bin/php ~/www/worker.php
sleep 1; done




https://github.com/pixnet/pixframework-
heroku/blob/master/Procfile
                                                    44
Addons – Custom domain

   xxxxx.herokuapp.com




                         45
$ heroku domains:add www.example.com




                                       46
Addons - Memcache




                    47
Memcache with SASL




                     48
49
heroku config
> heroku config
MEMCACHE_PASSWORD => *********
MEMCACHE_SERVERS => mc6.ec2.northscale.net
MEMCACHE_USERNAME => app******%40heroku.com




                                              50
https://github.com/ronnywang/PHPMemcacheSASL


include('MemcacheSASL.php');

$m = new MemcacheSASL;
$m->addServer(getenv('MEMCACHE_SERVERS'), '11211');
$m->setSaslAuthData(getenv('MEMCACHE_USERNAME'),
getenv('MEMCACHE_PASSWORD'));
var_dump($m->add('test', '123'));
$m->delete('test');




                                                      51
Pix Framework on Heroku

   http://framework.pixnet.net/
http://github.com/pixnet/pixframewrok



                                        52
http://github.com/pixnet/pixframework-heroku

• Core
   –   /init.inc.php
   –   /.gitignore
   –   /libs/pixframework/
   –   /models/
• Web
   –   /.htaccess
   –   /index.php
   –   /controllers/
   –   /views/
• Worker/Cron/Script
   –   /prompt.php
   –   /cron.php
   –   /worker.php
   –   /Procfile


                                                  53
Create table
# heroku run “~/bin/php ~/www/prompt”
Running `~/bin/php ~/www/prompt.php` attached to terminal... up, run.1
>> User::createTable()

>> exit
#




                                                                         54
Q&A

  We are hiring!
techjob@pixnet.tw



                    55

2012 coscup - Build your PHP application on Heroku