Setting up Piwik on Heroku

I’m new to the land of Piwik, but I want to test this out and part of that is for me to set this up on Heroku. Piwik wasn’t made to be used like this and I would really like the core team to take notice of this and make this easier to work with on platforms like Heroku.

To get this working you’ll need a few things.

  • Create a script that generates a config/config.ini.php file
  • Add a Procfile and a custom nginx config file
# nginx.conf
location / {
    try_files $uri /index.php;
location ~* ^/(?:index|piwik)\.php$ {
    try_files @heroku-fcgi @heroku-fcgi;
location ~* ^.+\.php$ {
    return 404;
location ~* ^/(?:README|LICENSE[^.]*|LEGALNOTICE)(?:\.txt)*$ {
    return 404;

The nginx.conf file is used to only allow index.php and piwik.php files to run. Any other PHP file will return a 404 Error. This is the same with some of the other TXT files.

Next is your Procfile

web: vendor/bin/heroku-php-nginx -C nginx.conf

We are just telling nginx to use our config file.

Now would be a good time to setup a database. Piwik ONLY supports MySQL at this time. It would be nice if there could be some love for Postgres soon, but it doesn’t look like it.

I’m currently using JawsDB Maria so to set this up just use the command

heroku addons:create jawsdb-maria:kitefin

The first tier is free and at the time this article was written, the max database size is 5mb. It’s a bit of a joke, but if you are just wanting to test Piwik out, it’s fine. You’ll just need to upgrade later.

The last thing we need to do is for us to create a script that generates config/config.ini.php because even though this is a php file, it’s not. Piwik parses this file as an ini file and it cause all kinds of issues when you toss PHP code in there.

// config/generate.config.ini.php
$content = file_get_contents(__DIR__.'/config.ini.php.tmpl');
$content = ob_get_contents();
file_put_contents(__DIR__.'/config.ini.php', $content);

A few things you will notice is that I am opening up a config.ini.php.tmpl file and doing an eval on it. Now I’m not an expert in eval which is why this thing is wrapped in ob_start and ob_get_contents. This script works by opening up a template file, evaling it and saving the content to config.ini.php in the format we want.

Here’s what the config/config.ini.php.tmpl file looks like.

$db = parse_url(getenv('JAWSDB_MARIA_URL'));
host = "<?php echo @$db['host']; ?>"
username = "<?php echo @$db['user']; ?>"
password = "<?php echo @$db['pass']; ?>"
dbname = "<?php echo trim(@$db['path'], '/'); ?>"
port = <?php echo @$db['port'].PHP_EOL; ?>
session_save_handler = dbtables
assume_secure_protocol = 1
proxy_client_headers[] = HTTP_CF_CONNECTING_IP
proxy_client_headers[] = HTTP_CLIENT_IP
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_host_headers[] = HTTP_X_FORWARDED_HOST
transport = smtp
port = 25
host = <?php echo getenv('MAIL_HOST').PHP_EOL; ?>
type = Login
username = <?php echo getenv('MAIL_USERNAME').PHP_EOL; ?>
password = <?php echo getenv('MAIL_PASSWORD').PHP_EOL; ?>
encryption = tls

You’ll notice this is setup for a database as well as for Piwik to send emails using some environment variables as well.

The last file we need to edit is composer.json which we will tell Heroku to install some of the dependencies and to run the config/generate.config.ini.php file during deployment.

Your composer.json file will get some additions

  "require": {
    "ext-mbstring": "*",
    "ext-gd": "*",
  "scripts": [
    "compile": [
      "php ./config/generate.config.ini.php"

NOTE: You also need to remove xhprof for the dev requirements.

That’s it, once you deploy, you’ll need to run through the Piwik installation and you will be good to start using this.