The Procfile Explained — Examples and Tips
Ah, the glorious Procfile. The starting point for any app running on Heroku and other cloud platforms.
At it simplest, the Procfile is where you declare the one or more processes to be run for your app to function. Heroku’s docs do a great job of explaining the Procfile format, so this post will focus on a bit more advanced usage.
Using Your Procfile for Local Development
One of the benefits of a Procfile is that it further allows for dev/prod parity when we run our local environment from our Procfile. Using a tool like heroku local (built in to the Heroku CLI) makes that a cinch. Given a Procfile such as:
We can simply run
heroku local to spin up all of our app’s processes concurrently under a single umbrella:
Pro tip: If you’re a
tmux user and want to take this to the next level, overmind is an awesome alternative.
Use Dev-Specific Processes in Your Procfile
Dev/prod parity is a worthy goal, but there are often processes you only want to run in development. We can actually throw those into our Procfiles:
We simply don’t allocate resources (dynos/containers) to those processes in our cloud environments — effectively ignored there:
Alternate-tip: you can also use a separate Procfile (often named
Procfile.dev) to house dev-only commands, though you lose some of the dev/prod parity.
Inline Environment Variables
Config vars (a.k.a. environment variables) are generally shared amongst all process for your Heroku app, but in your Procfile you can specify per-process configs with shell variable substitution:
This allows you to specify more clever config variable values that can be different per process type. You can even use config variables to skip processes altogether:
Remember that you’re not limited to just one web and worker process! You can add as many processes to your Procfile as you want. This is especially helpful when considering background job processing systems. If you run multiple queues in your background job system, don’t be afraid to split each queue out to its own process type.
Besides the benefit of giving each queue its own dedicated engine, you also gain the benefit of isolating each queue from the next without having to get into the nitty-gritty of queue priority weighting. Additionally, you’ll be preparing your app to work seamlessly with automatic dyno scaling based on the job queue’s metrics (which is exactly why we made Judoscale). Each queue’s dynos will be scaled totally independent of one another to keep each queue running smoothly 24/7.