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

    Heroku Blog

    Find out what's new with Heroku on our 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
      • Working with Node.js
      • Troubleshooting Node.js Apps
      • Node.js Behavior in Heroku
    • 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
      • PHP Behavior in Heroku
      • Working with PHP
    • 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
    • Model Context Protocol
    • Vector Database
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Working with AI
  • 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
  • Managing PHP Web Servers

Managing PHP Web Servers

Last updated April 10, 2025

Table of Contents

  • Apache
  • Nginx
  • PHP Built-in Web server

Heroku supports Apache HTTPD 2.4 and Nginx as dedicated web servers. For testing purposes, users can also use PHP’s built-in web server, although it’s not recommended. To see available web server versions, see Heroku PHP Support Reference.

In the absence of a Procfile entry for the “web” dyno type, the Apache Web server will be used together with the PHP runtime.

Apache

Apache interfaces with PHP-FPM via FastCGI using mod_proxy_fcgi.

To start Apache together with PHP-FPM and correct settings, use the heroku-php-apache2 script:

web: heroku-php-apache2

By default, the root folder of your project will be used as the document root. To use a subdirectory, you can pass the name of a subfolder as the argument to the boot script, for example “public_html”:

web: heroku-php-apache2 public_html/

You can use regular .htaccess files to customize Apache’s behavior, for example for URL rewriting. For additional details on this and other options to customize settings for Apache, refer to the corresponding Dev Center article.

Nginx

Nginx interfaces with PHP-FPM via FastCGI.

To start Nginx together with PHP-FPM and correct settings, use the heroku-php-nginx script:

web: heroku-php-nginx

By default, the root folder of your project will be used as the document root. To use a subdirectory, you can pass the name of a subfolder as the argument to the boot script, for example “public_html”:

web: heroku-php-nginx public_html/

For additional details on different ways of customizing settings for Nginx, refer to the corresponding Dev Center article.

PHP Built-in Web server

For testing purposes, you can start PHP’s built-in Web server using the php -S command. This command requires an argument that specifies what interface and port to bind to for handling requests.

The interface to use depends on the generation of your app. The port is dynamic, and available in an environment variable named $PORT, which can be referenced in the command string.

It’s important to bind to all IP interfaces, and not e.g. localhost, otherwise Heroku’s routing won’t be able to forward requests to the web server!

 

You can pass an alternative document root using the -t option, or specify a a router script to process requests as an argument. For details, refer to the PHP project’s documentation for the built-in Web server.

Cedar

The Cedar generation of the Heroku platform uses IPv4. A web process must bind to “any” interface using the IPv4 address “0.0.0.0”.

Use the following Procfile entry for the built-in PHP web server on a Cedar app:

web: php -S "0.0.0.0:${PORT}"

To use a subdirectory of your app as the document root, for example public_html, specify it using the -t option:

web: php -S "0.0.0.0:${PORT}" -t public_html/

Fir

The Fir generation of the Heroku platform uses IPv6. A web process must bind to “any” interface using the IPv6 shorthand address “::”.

IPv6 addresses use colons (“:”) as the group separator. Colons are also used, for example, to separate the host and port parts in URLs, or anywhere an address:port notation is used, such as in the -S option of php. In these cases, IPv6 addresses are wrapped in square brackets.

Many command shells treat square brackets as special characters, so such an address must be wrapped in quotation marks.

Since the port number a Heroku app must bind to is available in the $PORT environment variable, double quotation marks are used to allow the variable to expand.

Use the following Procfile entry for the built-in PHP web server on a Cedar app:

web: php -S "[::]:${PORT}"

To use a subdirectory of your app as the document root, for example public_html, specify it using the -t option:

web: php -S "[::]:${PORT}" -t public_html/

Keep reading

  • Working with PHP

Feedback

Log in to submit feedback.

Uploading Files to S3 in PHP PHP Session Handling 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