Tips from the Team

Traps to Avoid When Setting Up PHP for Heroku

Start Free Trial

Fully Functional for 14 Days

PHP powers millions of applications. This massive success is due to PHP’s simplicity, clear documentation, and tons of free resources. The PHP community provides an incredible ecosystem of libraries and tools, enabling anyone to develop production-grade apps rapidly. What’s even more exciting is PHP projects are cheap to host and widely supported by many platform providers such as Heroku.

Heroku started as a primarily Ruby PaaS solution. It now has great support for PHP, including all the supporting software you need: NGINX, Apache, MySQL, PostgreSQL, Redis, etc. Provisioning a PHP server is as simple as adding a Procfile and composer.json to your project and then going to sleep—Heroku handles the rest.

Heroku Deployment Pitfalls and How to Avoid Them

While Heroku handles server provisioning for you, making your app run well is up to you. To have a hassle-free deployment, keep these few things in mind if you want your app to run well in Heroku.

Don’t Forget Composer.json File

With PHP projects, you can reuse external libraries written by you or someone else. PHP has a tool for dependency management known as Composer, which allows you to import libraries written by someone else. Heroku uses this composer tool for dependency management for PHP projects, so you must define composer.json at the root directory of your project.

But wait! What if my app doesn’t use external dependencies?

Your project may not have used external dependencies, but you still need to define an empty composer.json file at the root folder of your project whose content is an empty curly brace: {}.

If you’re using a version control tool like GitHub, you should ensure you commit composer.json and composer.lock to version control.

Don’t Forget to Configure Session Support

When you walk into your office, your colleagues quickly know who you are. Some might even address you by your name—this is pretty much what a session is. Sessions contain data that allows servers to remember you. Sessions are necessary to preserve certain information we call state.

The HTTP protocol has one problem: it doesn’t keep state. In other words, it doesn’t have a place to store your information to recognize you the next time you stop by. 

You can address this limitation of  HTTP by using sessions, often stored as cookies on the client side or in some storage on the server side.

The second challenge comes when your back-end code runs on multiple servers. Where you store session details becomes an issue. If you store session details on a local file in one server, the next request may be handled by another server where the session details don’t exist. If you run your code on multiple Heroku dynos receiving traffic randomly from a load balancer, you should configure PHP’s session to not use file-based sessions. Use distributed datastores such as Memcache or Redis instead.

Don’t Use Sticky Sessions

When I was working on my thesis, I was assigned to a supervisor who oversaw and monitored my project. Any requests or questions I had were handled by that supervisor. Sticky sessions are similar. 

A load balancer with sticky-session support can assign a single server to a user based on the user’s HTTP session. The load balancer remembers the designated server, thus ensuring all future requests for the same session are routed to the assigned server.

This can make your application unreliable and introduce performance and scalability issues under load or if the back-end server has an outage.

Generally, you should avoid using sticky sessions.

Don’t Forget to Define Config Vars

I look at Heroku config vars as environment variables. Environment variables allow you to decouple your application configuration from your application code securely. Heroku allows you to declare config vars, which is exposed as environment variable at runtime.

With config vars, you can externalize configurations such as keys, usernames, and passwords without exposing them to version control tools. One of the common mistakes people make while deploying to Heroku is forgetting to declare environment variables in config vars. Do this beforehand—you won’t regret it.

Don’t Forget Error Pages

In Heroku, HTTP 503 errors will display an unstyled error page. These pages will show your users a very terse message with the HTTP status code 503 (service unavailable). Your users will encounter these pages when there’s a system-level error or when your app is in maintenance mode.

Why should you care?

These terse error messages pose two concerns:

  • It reveals the technology underneath your application. The exposure can help hackers narrow down their attack mechanism to the specific technology you use.
  • It’s never what your end users want to see.

In Heroku, you can customize what pages to display to your users in case of errors. This capability allows you to maintain consistency in your error messages.

To customize your error messages, create a folder named “error-pages” in the root folder of your application containing the following HTML pages you’ve customized to match your site’s style.

  • application-error.html
  • no-such-app.html
  • maintenance-mode.html
  • ssl-cert-error.html

You can reference images or CSS from the HTML as long as you use relative paths (for example, <img src= “error.png”>), and you upload the other assets into the same place as the HTML.

For obvious reasons, you should host these pages outside of Heroku. A frequent choice is uploading the pages up to Amazon S3. If you use S3, don’t forget to set the HTML and all assets to be publicly readable.

Don’t Forget to Define the Procfile

You just finished writing a new app; it works locally on your machine. You deploy it on Heroku successfully and get a URL for the app. Everything seems okay until you access the application URL. Voila! You’re greeted with errors. Don’t worry. You’re not alone; it happened to me when I first deployed my app on Heroku.

The issue is you likely forgot to define the procfile, a text file specifying the commands executed by your app on startup. Heroku didn’t know how to start up your app. This is a common mistake for new Heroku users. Like projects written in JavaScript, Go, and Java, PHP needs you to define how Heroku should start your project in procfile.

A procfile is a text file without the .txt extension. Each process type is defined on individual lines. For example:

web: vendor/bin/heroku-php-apache2

If you’re deploying a Laravel app, your procfile would look like this:

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

Don’t Forget to Set Up Logging and Send Logs to a Log Management System

For a PHP project like yours, there are many logging tools you can use, but the most popular is Monolog. If Laravel is your framework, Monolog is already integrated; otherwise, you can install it with Composer.

However, Heroku natively provides a way you can view your logs in the terminal through the use of the heroku logs –tail command. For a production app, you probably want to have your logs centralized with a dashboard to visualize them. This is even more important when you’re running multiple apps on Heroku. You should consider using a logging solution that can both integrate into Heroku but also allow you to search and tail all your Heroku app logs, including PHP. SolarWinds® Papertrail is a great option. You can install it into your Heroku environment here.

Conclusion

Heroku is an excellent choice for PHP applications. It integrates well with PHP and streamlines the development, deployment, tuning, and managing PHP apps.

If you want to learn more about PHP on Heroku, there are great PHP resources on the Heroku Dev Center. There are also great Heroku and PHP resources on the Papertrail site, including:

If you’re running multiple PHP apps both on and off Heroku and are looking for a single view of all your apps and systems, you should look at Papertrail. Papertrail aggregates logs, including PHP, and allows you to search and tail logs from multiple sources in real time. Sign up for a free trial if you want to see it for yourself.

This post was written by Samuel James. Samuel is an AWS solutions architect, offering five years of experience building large applications with a focus on PHP, Node.js, and AWS. He works well with Serverless, Docker, Git, Laravel, Symfony, Lumen, and Vue.js.

Aggregate, organize, and manage your logs

Papertrail
  • Collect real-time log data from your applications, servers, cloud services, and more
  • Search log messages to analyze and troubleshoot incidents, identify trends, and set alerts
  • Create comprehensive per-user access control policies, automated backups, and archives of up to a year of historical data
Start free trial Fully Functional for 30 Days

Let's talk it over

Contact our team, anytime.
Toll Free: +1 (855) 679-0752
Phone: +1 (512) 498-6011
papertrailapp@solarwinds.com