PHP
Article

How to Install Custom PHP Extensions on Heroku

By Thien Tran Duy

In this tutorial, we’ll learn how to install custom extensions on Heroku. Specifically, we’ll be installing Phalcon.

Sign-up and Set up

In order to use Heroku, you must sign up for a Heroku account. Heroku generally works with a command-line interface. To use that interface, you need to install the Heroku toolbelt package for your operating system. If you are using Linux, open up terminal and type the following command.

wget -qO- https://toolbelt.heroku.com/install.sh | sh

After installing the toolbelt, you’ll have access to the heroku command from your command shell. Authenticate using the email address and password you used when creating your Heroku account:

heroku login


Enter your Heroku credentials.
Email: fcopensuse@gmail.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /home/duythien/.ssh/id_rsa.pub

Press enter at the prompt to upload your existing ssh key or create a new one, used for pushing code later on.

Phalcon is a third party extension, and thus not bundled with PHP. Phalcon requires the following components:

mbstring
mcrypt
openssl
PDO
PDO/Mysql
PDO/Postgresql
PDO/Sqlite
PDO/Oracle

mbstring and mcrypt are the main ones – mbstring is used by the templating engine (Volt), as well as some validators, the escaper and the filter, while mcrypt is used in the security component (generating secure hashes etc.)

In order to install the elements above, we will use the PHP buildpack tool. Let’s explain what that means.

According to the official Heroku documentation, buildpacks provide the magic and flexibility that make running your apps on Heroku so easy. When you push your code, the buildpack is the component that handles the setting up of your environment so that your application can run. The buildpack can install dependencies, customize software, manipulate assets, and do anything else required to run your application. Heroku didn’t always have buildpacks, they are a new component that came with the Cedar stack.

You can get more information on these three steps and more through the buildpack documentation.

To get started, we fork this code on github. Click the “Fork” button in the repository. To be able to work on the project, you will need to clone it to your local machine.

Run the following code:

git clone https://github.com/duythien/heroku-buildpack-php.git buildpack-php
cd buildpack-php

Create the phalcon.sh file in your $HOME/buildpack-php/bin directory with the following content:

#!/bin/bash
# Build Path: /app/.heroku/php/
dep_url=git://github.com/phalcon/cphalcon.git
phalcon_dir=cphalcon
echo "-----> Building Phalcon..."

### Phalcon
echo "[LOG] Downloading PhalconPHP"
git clone $dep_url -q
if [ ! -d "$phalcon_dir" ]; then
  echo "[ERROR] Failed to find phalconphp directory $phalcon_dir"
  exit
fi
cd $phalcon_dir/build

# /app/php/bin/phpize
# ./configure --enable-phalcon --with-php-config=$PHP_ROOT/bin/php-config
# make
# make install
BUILD_DIR=$1
ln -s $BUILD_DIR/.heroku /app/.heroku
export PATH=/app/.heroku/php/bin:$PATH
bash ./install
cd
echo "important extension phalcon into php.ini"
echo "extension=phalcon.so" >> /app/.heroku/php/etc/php/php.ini

This file will install Phalcon, but Heroku must be instructed to execute it. To do that, you will have to edit the bin/compile file and add the following line somewhere in there:

[...]
source $BP_DIR/bin/phalcon
[...]

In addition, you need to add the text extension=phalcon.so to the file “conf/php/php.ini“:

[....]
extension=phalcon.so
; Local Variables:
; tab-width: 4
; End:

Now we can push our new buildpack up:

git add -A
git commit -m "edit php.ini and create phalcon file"
git push origin master

Create a new application on Heroku

Create a directory for your app and change to it:

mkdir phalcon-dev
cd phalcon-dev

In addition, you need to give Heroku an indication that this application is a PHP application. To do this, create an empty file called composer.json. On a Unix system, you can create this file like so:

touch composer.json

Then, execute the following to initalize the repo for our app:

git init
git add -A
git commit -m" first commit"

To create a new Heroku application that you can push to, use the CLI’s create command:

heroku create phalcon-dev

Creating phalcon-dev... done, stack is cedar
http://phalcon-dev.herokuapp.com/ | git@heroku.com:phalcon-dev.git
Git remote heroku added

This creates the application on Heroku ready and waiting for our code, and also attaches a git remote to our local codebase. You are now ready to deploy the application, but there is no code yet. Follow the next section to add some content to your application.

Your composer.json file should be made to look like this:

{
  "require": {
    "php": "5.5.12"
  }
}

It will automatically install extensions such as mcrypt, mbstring, etc on Heroku. If you need mongodb, memcached, etc, modify the file further:

{
  "require": {
    "php": "5.5.12",
    "ext-memcached": "*",
    "ext-mongo": "*"
  }
}

Now Heroku will enable the corresponding PHP extensions and put them into the support/build/extensions/no-debug-non-zts-20121212 folder. Next, create a test.php file with the following content:

<?php phpinfo() ; ?>

Finally, let’s deploy the Phalcon installation:

heroku config:set BUILDPACK_URL=https://github.com/duythien/heroku-buildpack-php
git add -A
git commit -am "installl phalcon"
git push heroku master

The first command means override the Heroku default buildpack by specifying a custom buildpack in the BUILDPACK_URL config var. After a few minutes, the results are as follows:

Build complete.
Don't forget to run 'make test'.

Installing shared extensions:     /app/.heroku/php/lib/php/extensions/no-debug-non-zts-20121212/

Thanks for compiling Phalcon!
Build succeed: Please restart your web server to complete the installation
important extension phalcon into php.ini
-----> Discovering process types
       Procfile declares types -> (none)
       Default types for PHP   -> web

-----> Compressing... done, 124.0MB
-----> Launching... done, v8
       http://phalcon-dev.herokuapp.com/ deployed to Heroku

To git@heroku.com:phalcon-dev1.git
   4f1d993..e0936a5  master -> master

This has taken our code, pushed it to Heroku, identified it, and run a build process against it, making it ready for deployment. Now our application is live on the Internet! To verify this, open it now:

heroku open test.php

If everything goes fine, you should see the following screen in your browser:

phpinfo

Configure the web root and deploy the sample site

Now comes the tricky part that is specifying the web root. Specifying the web root needs a little bit more work and background information. The Phalcon website application’s root in the git tree is /app/phalcon-website/public. For Heroku, by default, the web root is the root of the git-tree. That directory is internally mapped to /app. To change this, we need to create a so called Procfile that starts a sh-script each time the Heroku app web-node starts. That script then modifies the server configuration and includes your own config which is setting the web root to /app/phalcon-website/public. Create a Procfile file with the following content (if you’re using Apache):

web: vendor/bin/heroku-php-apache2 phalcon-website/public

Clone the Phalcon website into the repo folder, and when it’s done, the git push command sends all of the commits on your local master to the central repository.

cd && cd phalcon-dev
git clone --depth=1 http://github.com/phalcon/website phalcon-website
git add Procfile phalcon-websiste/
git commit -am " test phalcon website"
git push heroku master

Visit the app’s public URL and voila, you have a running Phalconphp.com clone on Heroku here.

Phalcon website

In conclusion

Installing Phalcon (or any other PHP extension) on Heroku is obviously neither easy nor simple but if you use buildpacks, it becomes much more approachable.

Leave your feedback in the comments below and, as always, please share this article if you liked it!

  • http://philipp-rieber.net/ Philipp Rieber

    Great article, thanks!

    Is it possible to use a package manager like apt in the custom buildpack to install package dependencies of an application or do we need to compile everything from source?

    • http://www.bitfalls.com/ Bruno Skvorc

      I think you can run aptitude, yes, since Heroku dynos run Ubuntu. Haven’t tried it, though – you might also want to take a look at this, for what it’s worth: https://github.com/gabrielfalcao/heroku-buildpack-aptitude

      • http://philipp-rieber.net/ Philipp Rieber

        Thanks Bruno; hard to find an example or something in the docs about it or which user runs the buildpack process. Seems not to be a usual demand ;-)

        • http://www.bitfalls.com/ Bruno Skvorc

          Indeed! I’ll make a note and we’ll try to look at this aspect soon-ish.

  • angelxmoreno

    This did not work for me. I like how there is a “Testing phase” for a few bundle steps. only the last one did not work. My logs say “DOCUMENT_ROOT ‘phalcon-website/public’ does not exist”. I will investigate

  • http://zizhujy.com Jeff Tian

    How to install Zend loader on heroku???

  • webdev

    Good tutorial you have there, but just a question. I’m having an issue with the mod_rewrite coz it’s not enabled? How can I enable this?

  • Jonathan Montgomery

    This did not work for me:

    remote: Compressing source files… done.
    remote: Building source:
    remote:
    remote: —–> Fetching custom git buildpack… done
    remote: —–> PHP app detected
    remote: —–> Building Phalcon…
    remote: [LOG] Downloading PhalconPHP
    remote: ./install: line 64: phpize: command not found
    remote:
    remote: ! Push rejected, failed to compile PHP app
    remote:
    remote: Verifying deploy…
    remote:
    remote: ! Push rejected to phalcon-dev3.
    remote:

    Does anyone know how to edit this buildfile to install php-devel so that heroku will recognize phpize?

  • Pablo

    I’m getting:
    Mod-Rewrite not enabled
    Please enable rewrite urls on your web server to continue

  • Ashwin Devarajan

    What about http extension in php?

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in PHP, once a week, for free.