Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Visit the Heroku Blog

    Find news and updates from Heroku in the blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Node.js Behavior in Heroku
      • Working with Node.js
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • Working with PHP
      • PHP Behavior in Heroku
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Heroku Inference
      • AI Models
      • Inference Essentials
      • Inference API
      • Quick Start Guides
    • Working with AI
    • Vector Database
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Language Support
  • PHP
  • Working with PHP
  • Deploying PHP Apps on Heroku

Deploying PHP Apps on Heroku

English — 日本語に切り替える

Last updated December 02, 2024

Table of Contents

  • Prerequisites
  • Overview
  • Manage dependencies
  • How to keep build artifacts out of Git
  • Specify runtimes and extensions
  • The Procfile
  • Deploy your application to Heroku
  • One-off dynos
  • Logging
  • Next steps

This article describes how to take an existing PHP app and deploy it to Heroku.

If you are new to Heroku, you might want to start with the Getting Started with PHP on Heroku tutorial.

Prerequisites

The best practices in this article assume that you have:

  • an existing PHP app that uses Composer for dependency management.
  • PHP installed
  • Composer installed
  • a free Heroku account
  • the Heroku CLI

Overview

The details of Heroku’s PHP Support are described in the Heroku PHP Support article.

Heroku PHP Support will be applied to applications only when the application has a file named composer.json in the root directory. Even if an application has no Composer dependencies, it must include an empty composer.json in order to be recognized as a PHP application.

Manage dependencies

Heroku uses Composer for dependency management in PHP projects. If your app has any dependencies, the composer.json file should specify them. It will look something like this:

{
  "require": {
    "monolog/monolog": "^3.0",
  }
}

Your PHP app can then make use of the dependencies that Composer installed. Dependencies are usually installed to the vendor/ directory after including the autoloader generated by Composer, typically like this:

require('vendor/autoload.php');

Vendor libraries are usually installed to vendor/ by Composer, but some projects re-define the name of this directory. Run composer config vendor-dir to find the right path name.

Whenever you add or change dependencies in composer.json, you must regenerate the lock file. This lock file is important to ensure reproducible behavior for your dependencies across multiple environments. It also helps ensure dev/prod parity. To generate your composer.lock file, make sure you have Composer installed and then type:

$ composer update

After updating your dependencies and re-generating the lock file, don’t forget to add and commit the changes to your Git repository:

$ git add composer.json composer.lock
$ git commit

Whenever an app gets deployed, Heroku reads the composer.lock file and installs the appropriate production dependencies into the vendor directory by running composer install --no-dev during the build. For more information, see PHP build behavior.

Each developer on your team will run composer install to install the same dependencies as everyone else, because composer.lock has “remembered” them.

How to keep build artifacts out of Git

Prevent build artifacts from going into revision control by creating a .gitignore file. The Composer vendor directory should be included in your .gitignore file. This keeps repository sizes small, simplifies dependency updates, and allows Composer to reliably install an application’s dependencies based on composer.lock

Here’s a typical .gitignore file:

vendor/
.env

Specify runtimes and extensions

Optionally, you can specify which engine (PHP or HHVM) and version to use at runtime. For more information, see the selecting a runtime article.

Any PHP extensions that are not enabled by default can be enabled via composer.json. The extensions article has a detailed list of available extensions and instructions about how to activate them.

The Procfile

A Procfile is a text file in the root directory of your application that defines process types and explicitly declares what command should be executed to start your app. Your Procfile will look something like this:

web: heroku-php-apache2

This declares a single process type, web, and the command needed to run it. The name, web, is important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed.

Selecting a web server

Depending on the runtime (PHP or HHVM) and web server (Apache2 or Nginx) you would like to use to run your application, the command for the web process type in your Procfile will be different. The possible options are documented in the web servers article. For example, to use Nginx as the web server instead, the Procfile would contain:

web: heroku-php-nginx

These boot scripts (heroku-php-apache2 or heroku-php-nginx) accept different options and arguments for fine-tuning the configuration of your application. Please refer to Customizing web server and runtime settings for PHP for more information.

Configuring the document root

Optionally, you can use a document root for your application that’s not the root directory of your app. To do this, modify your Procfile to add an argument at the end of the bootscript. The argument will be the name of the directory that should be used as the document root, relative to your application’s root directory.

For example, if you have a folder named public that contains your JavaScript, CSS, images and index.php file, your Procfile would define the Apache web server with that directory used as document root as follows:

web: heroku-php-apache2 public/

Deploy your application to Heroku

After you commit your changes to git, you can deploy your app to Heroku.

$ git add .
$ git commit -m "Added a Procfile."
$ heroku login
Enter your Heroku credentials.
...
$ heroku create
Creating arcane-lowlands-8408... done, stack is cedar
http://arcane-lowlands-8408.herokuapp.com/ | git@heroku.com:arcane-lowlands-8408.git
Git remote heroku added
$ git push heroku master
...
-----> PHP app detected
...
-----> Launching... done
       http://arcane-lowlands-8408.herokuapp.com deployed to Heroku

To open the app in your browser, type heroku open.

One-off dynos

Heroku allows you to run commands in a one-off dyno by using the heroku run command. Use this for scripts and applications that only need to be executed when needed, such as maintenance tasks, loading fixtures into a database, or database migrations during application updates.

For example, you can use heroku run to do a database migration for your application using Doctrine by doing something similar to this:

$ heroku run "php app/console doctrine:migrations:migrate"
Running `php app/console doctrine:migrations:migrate` attached to terminal... up, run.4062
Migrating up to 20100416130452 from 0

  >> migrating 20100416130452

     -> CREATE TABLE users (username VARCHAR(255) NOT NULL,
        password VARCHAR(255) NOT NULL) ENGINE = InnoDB

  >> migrated

For debugging purposes, such as to examine the state of your application after a deploy, you can use heroku run bash for a full shell into a one-off dyno. But remember that this will not connect you to one of the web dynos that may be running at the same time.

$ heroku run bash
Running `bash` attached to terminal... up, run.5662
$ cat Procfile
web: heroku-php-apache2
$ exit

Logging

Heroku treats logs as streams and expects them to be written to STDOUT and STDERR and not to its ephemeral filesystem.

The most basic way of sending logging information is to write to the php://stderr stream in your code like this:

file_put_contents("php://stderr", "something happened!");

Refer to the logging documentation for more general information about logging on Heroku.

Next steps

  • Read the Heroku PHP Support documentation to learn about available versions, extensions, features and behaviors.
  • Learn how to customize web server and runtime settings for PHP, in particular how to set the document root for your application.
  • Use a custom GitHub OAuth token for Composer.
  • Explore the PHP category on Dev Center.

Keep reading

  • Working with PHP

Feedback

Log in to submit feedback.

Uploading Files to S3 in PHP Deploying Symfony 3 Apps on Heroku

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices