15 Feb'15

Deploying sample Silex app to Heroku

For the last couple of weeks I met quite a few people who were praising PHP and I had an idea to have a brief look at it once again after more than 4-year break.

I decided to push a sample application to Heroku by following their tutorial but that turned out to be nontrivial on my Ubuntu 14.04LTS. Below I’ll give a brief list of commands that I needed in addition to those provided by Heroku to get the app running locally before pushing it to Heroku.

Initially, we start by naviagiting to the repository and following its first block of commands:

git clone git@github.com:heroku/php-getting-started.git # or clone your own fork
cd php-getting-started
composer update
foreman start web

There is a couple of catches here:

  • composer is installed locally by default
  • vendor/bin/heroku-php-apache2 script requires PHP 5.5.11 or newer as well as Apache 2.4.10 or newer. As you might imagine, Ubuntu 14.04 has PHP 5.5 and Apache 2.4 but not as new as those.
  • it also accesses those binaries through php-fpm and httpd while Ubuntu only provides php5-fpm and apache2.

Composer installation

Use these commands for the global installation:

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

PHP & Apache fight

I decided to use the PPA by Ondřej Surý which at the time of writing provides PHP 5.6.5 and Apache 2.4.11. I followed the instructions on DigitalOcean community forum:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php5-5.6
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install php5

You also need to run the following commands:

sudo apt-get install php5-fpm apache2
ln -s /usr/sbin/php5-fpm /usr/sbin/php-fpm
sudo ln -s /usr/sbin/apache2 /usr/sbin/httpd

After that I ran into a problem with undefined Apache variables:

$ foreman start web
22:28:44 web.1  | started with pid 7574
22:28:44 web.1  | [Sun Feb 15 22:28:44.931421 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_LOCK_DIR} is not defined
22:28:44 web.1  | [Sun Feb 15 22:28:44.931469 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_PID_FILE} is not defined
22:28:44 web.1  | [Sun Feb 15 22:28:44.931481 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_RUN_USER} is not defined
22:28:44 web.1  | [Sun Feb 15 22:28:44.931487 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_RUN_GROUP} is not defined
22:28:44 web.1  | [Sun Feb 15 22:28:44.931495 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
22:28:44 web.1  | [Sun Feb 15 22:28:44.936673 2015] [core:warn] [pid 7594] AH00111: Config variable ${APACHE_LOG_DIR} is not defined
22:28:44 web.1  | AH00526: Syntax error on line 75 of /etc/apache2/apache2.conf:
22:28:44 web.1  | Invalid Mutex directory in argument file:${APACHE_LOCK_DIR}

This is another error in that script that has to be fixed, but for now I used the answer from the ServerFault:

$ source /etc/apache2/envvars

However, after that I hit the same error about Apache. This time, however, I was attentive enough to notice that the error message also mentioned that two modules are needed. Let’s see what I have:

$ apache2ctl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 watchdog_module (static)
 http_module (static)
 log_config_module (static)
 logio_module (static)
 version_module (static)
 unixd_module (static)
 access_compat_module (shared)
 alias_module (shared)
 auth_basic_module (shared)
 authn_core_module (shared)
 authn_file_module (shared)
 authz_core_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 filter_module (shared)
 mime_module (shared)
 mpm_prefork_module (shared)
 negotiation_module (shared)
 php5_module (shared)
 setenvif_module (shared)
 status_module (shared)

Sure thing, both mod_proxy and mod_proxy_fcgi are missing from this list. Let’s enable them:

sudo a2enmod proxy_fcgi

After that, I also had to enable rewrite module as well as get my hands dirty with root-hell:

$ sudo -s
# . /etc/apache2/envvars
# export HOME=/root

And finally, I was able to start the server:

# foreman start web 
02:10:22 web.1  | started with pid 13567
02:10:22 web.1  | DOCUMENT_ROOT changed to 'web/'
02:10:22 web.1  | 4 processes at 128MB memory limit.
02:10:22 web.1  | Starting php-fpm...
02:10:24 web.1  | Starting httpd...
02:10:24 web.1  | Application ready for connections on port 5000.

However, any access attempts resulted in errors:

02:10:29 web.1  | [Mon Feb 16 02:10:29.622321 2015] [proxy:error] [pid 13678] (13)Permission denied: AH02454: FCGI: attempt to connect to Unix domain socket /tmp/heroku.fcgi.5000.sock (heroku-fcgi) failed
02:10:29 web.1  | [Mon Feb 16 02:10:29.622399 2015] [proxy:error] [pid 13678] AH00959: ap_proxy_connect_backend disabling worker for (heroku-fcgi) for 60s

… until I opened another terminal in parallel and executed sudo chmod 0667 /tmp/heroku.fcgi.5000.sock (inspired by this).

P.S. There is an issue opened supposedly by the owner of the script itself that somehow acknowledges planned effort on supporting ‘debianisms’ but it doesn’t make the situation any better.