Use Foreman to Start Rack App Located in Different Directory - ruby

I have a Procfile setup that is running a number of processes successfully:
# /Procfile
redis: bundle exec redis-server
sidekiq: bundle exec sidekiq -v -C ./config.yml
forward: forward 4567 mock-api
I need to add one more process - a Sinatra app that lives in a different directory on my machine. If I cd to the directory, I can start it from the Terminal with:
$ rackup -p 4567
And I can start it from a different directory using the Terminal with:
$ sh -c 'cd /Path/to/project/ && exec rackup -p 4567'
But how should I do this using foreman. I have tried adding the following, but it fails silently:
mock-api: sh -c 'cd /Path/to/project/ && exec rackup -p 4567'
Is this even possible? And if so, how?

Of all the stupid things ...
It was failing because of the hyphen in the process name.

Related

Bash script not navigating to folder, only accepting input when "exit" is typed manually

I have the following bash script I am trying to use so I can speed up updates to my code. For some reason it gets stuck at cd /var/www/myapp/code and only prompts input when I type exit to return to the root user.
#!/bin/bash
# Pulls from remote repo and implements changes
su - rails
cd /var/www/myapp/code
git pull
expect "sername for 'https://bitbucket.org':"
send "myusername"
interact
expect "assword for 'https://username#bitbucket.org':"
send "mypassword"
interact
exit
cd /var/www/myapp/code
RAILS_ENV=production bundle exec rake assets:clobber
RAILS_ENV=production bundle exec rake assets:precompile
nginx -t && sudo nginx -s reload
I tried manually entering cd /var/www/myapp/code but it's still not executing until I type exit.
Well, it's a bit of re-factoring, but a solution is to wrap everything in a single su - (user) -c "bla" call, which will automatically exit the subshell as (user) once the commands are all done.
Syntax:
su - (user) -c "command"
Here's how I'd do it:
Note that we have to break commands up with ';', and escape double-quotes with a '\'.
#!/bin/bash
# Pulls from remote repo and implements changes
su - rails -c "cd /var/www/myapp/code;
git pull;
expect \"sername for 'https://bitbucket.org':\";
send \"myusername\";
interact;
expect \"assword for 'https://bitbucket.org':\";
send \"mypassword\";
interact" # Now that the final command's ran,
# we'll auto - exit the subshell
cd /var/www/myapp/code
RAILS_ENV=production bundle exec rake assets:clobber
RAILS_ENV=production bundle exec rake assets:precompile
nginx -t && sudo nginx -s reload

Executing a shell script within docker with RUN command

New to dockers, so please bear with me.
My Dockerfile contains an ENTRYPOINT:
ENV MONGOD_START "mongod --fork --logpath /var/log/mongodb.log --logappend --smallfiles"
ENTRYPOINT ["/bin/sh", "-c", "$MONGOD_START"]
I have a shell script add an entry to database through python script, and starts the server.
The script startApp.sh
chmod +x /addAddress.py
python /addAddress.py $1
cd /myapp/webapp
grunt serve --force
Now, all the below RUN commands are unsuccessful in executing this script.
sudo docker run -it --privileged myApp -C /bin/bash && /myApp/webapp/startApp.sh loc
sudo docker run -it --privileged myApp /myApp/webapp/startApp.sh loc
The docker log of container is
"about to fork child process, waiting until server is ready for connections. forked process: 7 child process started successfully, parent exiting "
Also, the startApp.sh executes fine when I open a bash prompt in docker and run it.
I am unable to figure out what wrong I am doing, help please.
I would suggest you to create an entrypoint.sh file:
#!/bin/sh
# Initialize start DB command
# Pick from env variable MONGOD_START if it exists
# else use the default value provided in quotes
START_DB=${MONGOD_START:-"mongod --fork --logpath /var/log/mongodb.log --logappend --smallfiles"}
# This will start your DB in background
${START_DB} &
# Go to startApp directory and execute commands
`chmod +x /addAddress.py;python /addAddress.py $1; \
cd /myapp/webapp ;grunt serve --force`
Then modify your Dockerfile by removing the last line and replacing it with following 3 lines:
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Then rebuild your container image using
docker build -t NAME:TAG .
Now you run following command to verify if ENTRYPOINT is /entrypoint.sh
docker inspect NAME:TAG | less
I guess (and I might be wrong, since I'm neither a MongoDB nor a Docker expert) that your combination of mongod --fork and /bin/sh -c is the culprit.
What you're essentially executing is this:
/bin/sh -c mongod --fork ...
which
executes a shell
this shell executes a single command and waits for it to finish
this command launches MongoDB in daemon mode
MongoDB forks and immediately exits
The easiest fix is probably to just use
CMD ["mongod"]
like the official MongoDB Docker does.

Ubuntu start up Rails on boot up

I want to start my Rails server with the following command on boot up:
cd /home/ubuntu/app && bundle exec rails server -p 8080 -e production
I placed it inside the /etc/rc.local, but it never starts up the server. If I remove bundle exec then shell complains about not finding the rails command.
Both variants, with and without bundle exec, work if I log in, and execute it manually.
I am totally lost. Any suggestions?
Try to change a user
su ubuntu && cd /home/ubuntu/app && bundle exec rails server -p 8080 -e production
Running your script as root is not a good idea, so you want to change user before starting your code.
su is indeed the command you want to use, but you need to realise that all arguments are passed to the login shell. So the following won't work (assuming fofox is your username):
su fofox pwd
as you're effectively saying
/bin/bash /bin/pwd
but /bin/pwd does not contain a list of shell commands, so both will give an error message:
/bin/pwd: /bin/pwd: cannot execute binary file
Thus you need to add something to the shell saying you're passing a list of commands, like this:
/bin/bash -c /bin/pwd
The last wrinkle is that you want to pass a number of arguments to the su command but protect them from the shell, as
su fofox -c id && id
will show you that the first bit is executed as fofox and the second part as root again. Single quotes are used to prevent the root shell to see the && characters.
So the final command becomes:
su fofox -c 'cd /home/ubuntu/app && bundle exec rails server -p 8080 -e production'

How to set RUBY_GC_MALLOC_LIMIT with capistrano 3 on thin restart?

I use capistrano 3, rvm und bundler for my deployment.
The thin server are restarted like this:
within release_path do
execute :bundle, :exec, "thin restart -O -C config/thin/staging.yml"
end
This work fine and generate this command:
cd /var/www/foo/releases/20140320154611 && ~/.rvm/bin/rvm ruby-2.0.0-p353#foo do bundle exec thin restart -O -C config/thin/staging.yml
Now I need to restart the thin's with this setting RUBY_GC_MALLOC_LIMIT=90000000 and I dont know how to set this up in the execute command?
The script has to setup rvm for knowing bundle, and RUBY_GC_MALLOC_LIMIT for thin
Not working:
Because rvm is not set (execute :bundle # set a rvm hook)
execute "RUBY_GC_MALLOC_LIMIT=90000000", :bundle, :exec, "thin restart -O -C config/thin/staging.yml"
2.same here
execute "RUBY_GC_MALLOC_LIMIT=90000000 bundle exec thin restart -O -C config/thin/staging.yml"
I have found a solution....
execute :bundle, :exec, "'RUBY_GC_MALLOC_LIMIT=90000000 thin restart -O -C config/thin/staging.yml'"

Problem deploying Ruby+RVM and daemontools

I am using daemontools in production to keep the services alive and want to run a Ruby server, not Rails, and without RVM it works well but with RVM I have some issues.
My goal is to start a process by root, make it drop root rights to get another user rights and then spawn a Ruby process with RVM and a specified Ruby version.
Here is the run script I was using until now:
#!/bin/sh
exec 2>&1
cd /app/src
. /usr/local/rvm/scripts/rvm
rvm use 1.9.1-p378
exec setuidgid app_user ruby main.rb
This script works but setuidgid has a major problem: the application will be run by user <x> and group <x> and only this group. If the user is in other groups the process will not have their rights.
So it led me to another approach:
#!/bin/sh
exec 2>&1
cd /app
exec sudo -u app_user rvm 1.9.1-p378 exec ruby main.rb
This one works fine except it is the RVM process which is spawned by daemontools and it does not react when it receives a SIGTERM which is not really nice. Basically it means the service cannot be restarted by hand, which is not good.
I found the answer but looking at the rvmsudo script installed with rvm, here is a working run script:
#!/bin/sh
# redirect stderr to stdout
exec 2>&1
cd /app
# load rvm
. /usr/local/rvm/scripts/rvm
# select ruby version for this application
rvm use 1.9.1
# # depending on your configuration you may need to provide the absolute path to rvm, like that:
# /usr/local/bin/rvm use 1.9.1
# build the exec command line preserving the rvm environment
command="exec sudo -u app_user /usr/bin/env PATH='$PATH'"
[[ -n "${GEM_HOME:-}" ]] && command="${command} GEM_HOME='$GEM_HOME' "
[[ -n "${GEM_PATH:-}" ]] && command="${command} GEM_PATH='$GEM_PATH' "
# this is where your real command line goes
command="${command} ruby main.rb"
# run the application
eval "${command}"

Resources