This guide will show you how to install an ImageRack server on an Heroku free dynamo to resize and serve images from an Amazon S3 bucket. ImageRack is an easy to setup on the fly image manipulation server written that I wrote to simplify handling user media uploads.
The companion code for this guide is available on BitBucket: bitbucket.org/diarmuidie/imagerack-heroku.
Before we begin there are a few prerequisites:
- An Heroku account.
- Heroku toolbelt installed and working.
- An AWS S3 bucket and its corresponding key and secret.
- PHP and Composer installed on your local/dev machine.
Step 1 - Setting up ImageRack
To start let’s get a copy of the ImageRack server on our local machine:
$ composer create-project diarmuidie/imagerack heroku-imagerack
This will download and install the ImageRack server and its dependencies in the heroku-imagerack
folder. We also need to install the Flysystem S3 adapter because we will be storing our source images there:
$ composer require league/flysystem-aws-s3-v3
Now that everything is downloaded we can begin to configure the server.
Copy the bootstrap/dependencies.s3.sample.php
file and save it as bootstrap/dependencies.php
. This file is setup to use S3 as the source and cache locations but we only want to use S3 as the source. Cached images will be stored locally on the Heroku dynamo.
You will have to edit the cache dependency line to change it from:
$dependencies['cache'] = new Filesystem(new AwsS3Adapter($s3Client, 'test-image-rack-cache'));
To:
$dependencies['cache'] = new Filesystem(
new League\Flysystem\Adapter\Local(__DIR__.'/../storage/cache')
);
And that’s it! There are more config option in ImageRack that you can tweak but the defaults will work just fine.
Step 2 - Preparing ImageRack to Run on Heroku
There are a few steps to getting our PHP to run on Heroku.
First we need to update the S3 connection settings (in bootstrap/dependencies.php
) to use the Heroku config vars (we will set these later):
Edit the S3Client Factory credentials to use getenv()
like below:
$s3Client = S3Client::factory([
'credentials' => [
'key' => getenv('S3_KEY'),
'secret' => getenv('S3_SECRET'),
],
'region' => 'us-east-1',
'version' => 'latest',
]);
Don’t forget the edit the region
option to correspond to the region that your bucket is in.
We also need to create a Procfile
to tell Heroku what kind of server this is and where the document root folder is. Save the file to the project root as Procfile
with the following content:
web: vendor/bin/heroku-php-apache2 public/
Finally we can edit the composer.json
require
section to make sure Heroku installs the correct versions of PHP and GD:
"require": {
"php": ">=5.4",
"ext-gd" : "*"
// ...
}
After editing the composer.json
file you need to run an update to keep the lock file in sync:
$ composer update
Step 3 - Deploying to Heroku
To be able to deploy to Heroku our files must be in a git repo. Initialise a git repo and add all the files to it:
$ git init
$ git add .
$ git commit -m 'Initial commit'
Now we can finally create a Heroku app:
$ heroku create
If that all went OK Heroku will output a URL for your new project (something like: http://sharp-rain-871.herokuapp.com/).
In order for ImageRack to connect to S3 you need to setup the config vars in Heroku:
$ heroku config:set S3_KEY=<put your S3 key here>, S3_SECRET=<put your S3 secret here>
Now we can push the whole project to Heroku:
$ git push heroku master
Once that completes you should be able to access the Heroku ImageRack server using:
$ heroku open
The first time the app loads it will take a few seconds as the Dynamo wakes up. Once you have uploaded some images to your S3 bucket you can access them at http://<heroku-app-name>.herokuapp.com/<template>/path/to/image.jpg
. Where template
is a template you create or the default included template (small
) and path/to/image.jpg
is the path to the image file on your S3 bucket.
If you get stuck along the way have a look at the sample repo I created bitbucket.org/diarmuidie/imagerack-heroku and the Heroku help docs devcenter.heroku.com/articles/getting-started-with-php.