0

I need an additional process to be run in development called Proxylocal (this allows external web services to hit http endpoints on my local machine).

In order to do this reliably though I would like to add the process into my Procfile. Since the process should not be run in production I am using this technique to do the switching.

My Procfile looks like this:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
redis: redis-server
worker: bundle exec sidekiq
proxylocal: bin/proxylocal

and bin/proxylocal looks like this:

#!/bin/bash
if [ "$RACK_ENV" == "development" ] 
  then
    proxylocal 5000 --host mypersonalmachine
fi

(I've never done any bash scripting so have no idea whether this is the correct syntax - I just copied it).

However each time I run foreman start it immediately exits with only the following error:

10:57:25 proxylocal.1 | started with pid 14935
10:57:25 proxylocal.1 | exited with code 0
10:57:25 system       | sending SIGTERM to all processes

Update1

If I remove the if statement and change bin/proxylocal to simply:

proxylocal 5000 --host mypersonalmachine

Then that does work successfully. Why then does the if statement make everything baulk?

Update 2

The following code does work as long as $RACK_ENV is equal to "development". I had to remove the double quotes around $RACK_ENV and to change the == to a single =.

if [  $RACK_ENV = "development" ]; then
    proxylocal 5000 --host brojure
fi

However... it only works as long as $RACK_ENV does equate to 'development'. When it doesn't it chokes.

Is it because Procfile needs a process ID?

A friend suggested that the issue may be that the Procfile is expecting a process ID to be returned from the script. So in the instance when we're not on development it's got nothing to process.

Is there a way in which I could spin up a zero-overhead process just to be able to return an ID. It's ugly but probably not too costly...

Peter Nixey
  • 16,187
  • 14
  • 79
  • 133
  • The bash script seems ok, the problem must lie in your `proxylocal` invocation or configuration. Have you ever succeeded in calling `proxylocal` in a terminal with your settings ? – Aserre Aug 04 '14 at 10:15
  • @Ploutox I have and in fact if I remove the `if` statement then it all runs ok too. Something about the presence of the `if` statement is causing it to baulk... – Peter Nixey Aug 04 '14 at 10:17
  • I have tested your if test and it works just fine. are you sure about the value of `$RACK_ENV` ? Try to echo it right before your test to see if you get the correct state – Aserre Aug 04 '14 at 12:22
  • change '==' to '='. check Bash Faq: http://mywiki.wooledge.org/BashFAQ/031 – lihao Aug 04 '14 at 13:25
  • 1
    @lihao It doesn't matter, shebang is `#!/bin/bash`. Bash allows stuff like this to happen. – karolba Aug 04 '14 at 14:48
  • thanks chaps. The logic works ok and I've got an idea about what the problem is but I'm not sure how to solve it. I think the issue is that the Procfile is expecting a process ID to be returned and when it isn't (i.e. when we're not in dev) then it chokes. Is there any way I can spin up a zero-overhead process and just pass that back instead (I'm way out of my depth here as you can tell)? – Peter Nixey Aug 04 '14 at 15:25

2 Answers2

0

The problem is that when RACK_ENV is not "development" there is no process run so Foreman assumes that the script has crashed once it exits.

The right thing to do here is to create a "web" wrapper script that runs the proxy in development. Something like this:

#!/usr/bin/env bash

cleanup() {
  kill $proxy_pid
}

if [ "$RACK_ENV" == "development" ]; then
  proxylocal 5000 --host $PROXY_HOST &
  proxy_pid=$(cat thepidfile)
  trap cleanup EXIT
fi

bundle exec unicorn -p $PORT -c ./config/unicorn.rb
David Dollar
  • 2,409
  • 17
  • 18
  • Thanks David (and thanks for the help on twitter too). – Peter Nixey Aug 05 '14 at 10:20
  • As I mentioned on Github I still had problems getting this to run though - I couldn't get that if statement to evaluate successfully. I actually ended up with a different solution (which may well be very flawed but it did work). I've put my solution as a different answer but marked yours as correct since you wrote Foreman and I'm way out of my depth here :) – Peter Nixey Aug 05 '14 at 10:22
0

Please note that the answer from David Dollar should be the correct one as he wrote Foreman. However I still had problems getting it to work and so (for better or worse) this was what did eventually work for me:

# Procfile:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
redis: redis-server
worker: bundle exec sidekiq
proxylocal: bin/proxylocal_local

# bin/proxylocal_local

#!/usr/bin/env bash

if [ $RACK_ENV = "development" ]; then
  proxylocal 5000 --host $PROXYLOCAL_HOST 
else
  cat
fi

# .env

PROXYLOCAL_HOST=hostname_you_want_to_use

Also note that you'll need to chmod the proxylocal_local file so that it is executable.

Peter Nixey
  • 16,187
  • 14
  • 79
  • 133