Procfile support is one of our compatibility layers that makes Scalingo compatible with Heroku.
About the Procfile
The Procfile is a simple text file specifying how the platform should start your application’s container(s).
More precisely, it allows to declare the commands executed in the container(s) on startup.
Each of these commands is associated to a process type, which is basically a name that uniquely identifies the type of process.
When the platform starts a container for your application, it uses the process type to know what command to execute in it, and it also marks the freshly booted container as being of the specified process type, thereby creating a kind of link between the container and its process type.
- a container belongs to exactly one process type.
- a process type can reference zero, one or multiple containers, depending on the scale factor.
Since process types are referencing containers, they are also used to manage the resources consumed by your application:
- they allow to add or remove container(s) of the specified process type.
- they allow to set different plans for the containers, depending on the workload they have to handle.
You can define as many process types as you need for your application, from the same code base.
Some common use cases for process types:
- define a process type called
webto start a process handling HTTP requests.
- define a process type called
workerto handle some asynchronous computation.
- define a
clockprocess type to schedule some recurring jobs.
Let’s say your application has a web frontend that handles HTTP requests and a worker that does some heavy computing. They both share the same code base, but they don’t start the same way and they don’t have the same computing power requirements. In such a case, you’d have to instruct the platform to start two process types, which must be defined in your project’s Procfile:
- one called
web, to instruct the platform how to start your web server (the frontend).
- another one, called
worker, to instruct the platform how to start your… worker.
web process type could be set to use an
L plan (which means the
platform will run the corresponding command in an
L container), whereas
worker process type could be set to use a
Now, let’s say that your single
worker container is a bit under pressure.
Using the process type, you can instruct the platform to boot up a few more
containers to handle the load (in the command below, we tell the platform that
we want three
2XL containers for the
worker process type):
scalingo --app my-app scale worker:3:2XL
Special Process Types
postdeploy process types have a special meaning and are
thus reserved for specific use cases described below. The platform will only
use them for what they are designed for.
web Process Type
web process type defines how to start and run the container(s) handling
It’s the only process type that can receive external HTTP requests from
Consequently, if your application has a web server, it MUST have a
process type bound to
$PORT to be publicly reachable.
web process type is often the only one required.
tcp Process Type
tcp process type defines how to start the
TCP Gateway addon.
postdeploy Process Type
postdeploy process type defines how to start the
Working With the Procfile
Procfile Naming Convention
The Procfile is a plain text file that MUST be named
Procfile. Even if it
uses the YAML syntax, there is no extension: no
The file MUST live in your application’s root directory or in
if your application code lies in a subdirectory of your repository.
Defining a Process Type
Each process type of the application is defined on its own, individual line, with the following format:
<process_type>designates the name of the process type. It can only contain alphanumerics (
[A-Za-z0-9]+). Except this rule, you are free to name your process type how you want:
trex… These are all examples of valid process type names.
<command>designates the command to run when a container of the specified type is booted up. It can be any Bash command. Using environment variables in the command is allowed, and even encouraged.
Here is an example of a valid Procfile defining two process types:
- one called
web, defining how to start a Rails web server.
- another one called
worker, defining how to start a container running Sidekiq.
Notice the use of the environment variables:
web: bundle exec rails server -p $PORT -e $RAILS_ENV -b 0.0.0.0 worker: bundle exec sidekiq -e $RAILS_ENV
Defining a Complex Process Type
When you have more complex commands to run, don’t hesitate to write a short
start script, for instance in
#!/bin/bash if [ "$SOME_ENV" = "SOME_VALUE" ] ; then exec run_this_command -p $PORT else exec run_that_other_command fi
Then, in your
Procfile, call this script directly:
web: bash bin/start.sh
Starting and Stopping a Process Type
When starting or stopping a process type, you concretly instruct the platform to create (and start) or stop (and destroy) all the container(s) referenced by this process type. In fact, these operations are the same and consist in scaling the process type, which can be done via the dashbord or via the CLI.
All new process types are considered to be scaled to 0:M by default and,
hence, must be scaled to a value greater than 0 to be started by the platform.
The only exception is the
web process type, which is scaled to 1:M by
default. Don’t forget to scale your process type to at least 1 to start it!
Conversely, to stop a specific process type, scale it to 0. All existing container(s) in charge of this specific type of process will be stopped and destroyed by the platform.
Removing a Process Type
Removing a process type from an application is done in 3 steps:
- First scale the process type to be removed to 0. You can do this with the CLI or via the dashboard.
- Edit your Procfile and remove the corresponding line. For example, if you
want to remove the
schedulerprocess type, locate the line starting with
schedulerand remove it entirely.
- Commit your changes and trigger a new deployment.
If you don’t start by scaling down the process type you don’t want anymore, you will encounter the following error message in your application logs:
2022-01-26 10:46:17.855295004 +0000 UTC [worker-1] Task 'worker' has not been found in your 'Procfile'
Developing With a Procfile
To reduce the gap between the development and the production environments, it is important to execute the same processes in both environments.
Several tools exist to fulfill this need:
foreman is a Ruby
gem executing and displaying the output of all the
processes defined in your Procfile. You can install it with the following
gem install foreman
And use it like this:
└> cat Procfile web: bin/project worker: bin/project -worker └> foreman start 17:52:56 web.1 | started with pid 10663 17:52:56 worker.1 | started with pid 10664 17:52:56 web.1 | 2014/12/01 17:52:56 Listen HTTP requests on :5000 17:52:56 worker.1 | 2014/12/01 17:52:56 Starting Asynchronous worker
As you can see,
foreman started a container for each process type defined in
the project’s Procfile (one for the
web process type and another one for the
worker process type).