3

I am using foreman to start a bunch of services, and have the following line in the Procfile.

web:    bundle exec rails server -p ${PORT:-3000}

yet when the server starts it starts on the default Foreman port of 5000, so it looks like the syntax for injecting 3000 as the default port is wrong.

I went looking (someone else gave me the line above so I'd like to fix it) and could not actually find any specific documentation on how to inject a default value.

Looking at the source you see

def expanded_command(custom_env={})
  env = @options[:env].merge(custom_env)
  expanded_command = command.dup
  env.each do |key, val|
    expanded_command.gsub!("$#{key}", val)
  end
  expanded_command
end

so it's clear that the ${PORT:-3000} syntax is wrong.

What is the correct way to set a default port?

Dave Sag
  • 13,266
  • 14
  • 86
  • 134

4 Answers4

4

Change the Procfile definition to point to a custom script file:

bundle exec ./script/server

Then, create the script/server file and configure the defaults

#!/usr/bin/env bash
cd "$(dirname "$0")/.."
[ $PORT ] || PORT=3000

cmd="bundle exec rails server -p $PORT"
exec $cmd

Otherwise, simply run Foreman passing the port

$ foreman start -p 3000
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • thankyou, that almost worked except that Foreman appears to set `PORT` to `5000` before that script is invoked, so `PORT=3000` was never being invoked. I've opted for modifying the `setup` rake task to provide the default port. – Dave Sag Jan 26 '16 at 00:10
2

You can create .env file with the following content: PORT=3000, then in your Procfile use web: bundle exec rails s -p $PORT

More info here: https://ddollar.github.io/foreman/#ENVIRONMENT

Konstantine Kalbazov
  • 2,643
  • 26
  • 29
  • also correct — thanks, alas SP only lets me count one answer as correct, and @simone-carletti got in first. – Dave Sag Jan 26 '16 at 00:23
2

I can't comment on @PJSCopeland answer so I'm adding this as another answer. Foreman isn't Bash but command is written correctly (at the end foreman executes Process.spawn with specified command). The problem here is that foreman sets variable PORT internally so default PORT value 3000 isn't used as it is already defined.

I think that @Kote answer is the best but another way to accomplish this task is to change PORT variable name, e.g. to SERVER_PORT

web:    bundle exec rails server -p ${SERVER_PORT:-3000}

Then to change default SERVER_PORT execute:

SERVER_PORT=3100 foreman start
jkurdel
  • 61
  • 5
0

Foreman isn't Bash; you can't interpolate expressions like that.

You could do it like this:

export PORT=3000 # only once; this is persistent
foreman run

or like this:

PORT=3000 foreman run # $PORT is not persistent this way

You could extend the former to put the export command into an .*rc file (such as .rvmrc) that loads automatically when you switch to this directory.

Or, you could save the latter as a script and run that instead (as Simone Carletti suggests). This is my preferred option.

(I also add ./bin and ~/bin to my PATH, and put a default script such as rails s into the latter under the same name. Then I don't have to remember the "start server" command for each project.)

Community
  • 1
  • 1
PJSCopeland
  • 2,818
  • 1
  • 26
  • 40