We're using Foreman to start our node.js app in development. We've encountered a recurring problem: Developers accidentally check in changes they made to the Procfile
for development purposes, which results in the wrong processes starting in Heroku.
Specifically, our devs would like to start their MongoDB and Redis processes with the rest of the app when developing, so they modify the Procfile. If they're in a hurry or forgetful, the Procfile
changes end up in production.
To work around this issue, I've implemented a number of bin/
scripts as suggested by this comment to conditionally start processes only if $NODE_ENV=development
. This does help protect the Procfile
from accidental changes, and it does help us keep the right things running in production, but our production Heroku app dashboard now has "memento" of a Redis and MongoDB process that were started then immediately exited.
I've asked the Heroku team if they could try to start their Celadon Cedar stack with something other than the default Procfile
. For example, if they could try to start with Procfile-heroku
first, and then fall back to Procfile
if that file is not found. They suggested that I file this as an issue with Foreman. I don't understand how changing Foreman will help with this issue, however, I'm writing it up here and perhaps someone can give me some insight.
I use Procfile
for production (heroku), and Procfile-dev
for local development.
I just start it like:
foreman start -f Procfile-dev
@ambethia In my experience, humans sometimes forget things. Sometimes they're lazy. Sometimes they just don't know the "right" way to do something.
As I proposed to the Heroku devs, having the startup script use a non-default Procfile for production will help in those situations when developers forget, are lazy, or just don't understand.
There are a few advantages to having a non-default Procfile used for Heroku:
Procfile
will be clearly labeled, i.e. Procfile-heroku
, instead of just Procfile
Procfile
can be put into .gitignore
to prevent accidental checkins by developers.foreman start
. The startup script can use the long form foreman start -f Procfile-heroku
You're right in that using multiple Procfiles can easily lead to confusion. There are two reasons I don't want to do this:
I use binscripts to solve this problem. For example, I want to run nodemon
, an auto-reloading web-server in development, but not in production. You can see an example of this in another of my projects, anvil:
You can see that bin/web has some conditional logic based on whether or not NODE_ENV
is set to production
. I believe that this is a cleaner and easier approach to this problem.
@ddollar It sounds like you're recommending that we remove our Redis and MongoDb process startups from Foreman, since in production we don't host these on Heroku, and therefore they will never be part of the Heroku startup process. Is this correct?
That would be up to personal preference. I don't personally put stuff like that in my Procfile, but I know that others do. I generally just have machine-wide Couch, Mongo, Redis, etc that I use locally.
The way I do this is to use a separate Procfile-local that runs all services that are local-only, like my static files server, and also invokes foreman (recursively) to execute the regular Procfile. All your logs will have an extra level of nesting, but other than that, it works fine.
@ddollar Just came across this. Another thing you can do is to have the separate Procfile (as mentioned above) and then setup bash aliases to start foreman locally using the local file, i.e.:
# in .bash_profile or similar
alias fman='foreman start -f Procfile.local'
^ very nice. for some reason using the foreman -f command this way doesn't work for me
I used copied the contents of my Procfile.local to Procfile and running
foreman start
works
but using
foreman start -f Procfile.local
I get some sort of rails exception just trying to run rails s as the server.
foreman start --procfile=Procfile.local
19:15:29 server.1 | started with pid 71750
19:15:31 server.1 | syck has been removed, psych is used instead
19:15:31 server.1 | Error: Command not recognized
19:15:31 server.1 | Usage: rails COMMAND [ARGS]
19:15:31 server.1 |
19:15:31 server.1 | The most common rails commands are:
19:15:31 server.1 | generate Generate new code (short-cut alias: "g")
19:15:31 server.1 | console Start the Rails console (short-cut alias: "c")
19:15:31 server.1 | server Start the Rails server (short-cut alias: "s")
19:15:31 server.1 | dbconsole Start a console for the database specified in config/database.yml
19:15:31 server.1 | (short-cut alias: "db")
19:15:31 server.1 | new Create a new Rails application. "rails new my_app" creates a
19:15:31 server.1 | new application called MyApp in "./my_app"
19:15:31 server.1 |
19:15:31 server.1 | In addition to those, there are:
19:15:31 server.1 | application Generate the Rails application code
19:15:31 server.1 | destroy Undo code generated with "generate" (short-cut alias: "d")
19:15:31 server.1 | benchmarker See how fast a piece of code runs
19:15:31 server.1 | profiler Get profile information from a piece of code
19:15:31 server.1 | plugin Install a plugin
19:15:31 server.1 | runner Run a piece of code in the application environment (short-cut alias: "r")
19:15:31 server.1 |
19:15:31 server.1 | All commands can be run with -h (or --help) for more information.
19:15:31 server.1 | process terminated
19:15:31 system | sending SIGTERM to all processes
I wish this could be revisited—the fact that both Heroku and Foreman use a file called Procfile
that I need to have different things in is really annoying. I use Foreman to start all the service dependencies for an app—like Redis and the Resque dashboard—in development, but do not want processes for many of them in production on Heroku.
Did Procfile
originate with Foreman in the first place or was it a pre-existing standard for listing processes from an earlier tool? In an ideal world for me, Procfile
would actually be a Yaml file with top-level keys for environments just like the Rails config/database.yml
database configuration file, because then you could do things like this:
production: &production
rails: bundle exec rails server
resque: bundle exec rails resque:work QUEUE=*
development: &development
<<: *production
redis: redis-server
resque_dashboard: bundle exec resque-web --foreground --no-launch
test: *development
Most helpful comment
I wish this could be revisited—the fact that both Heroku and Foreman use a file called
Procfile
that I need to have different things in is really annoying. I use Foreman to start all the service dependencies for an app—like Redis and the Resque dashboard—in development, but do not want processes for many of them in production on Heroku.Did
Procfile
originate with Foreman in the first place or was it a pre-existing standard for listing processes from an earlier tool? In an ideal world for me,Procfile
would actually be a Yaml file with top-level keys for environments just like the Railsconfig/database.yml
database configuration file, because then you could do things like this: