start unicorn app server when the ubuntu server starts - ruby-on-rails

I am running my rails application using ruby enterprise edition with unicorn as app server. I run this command
bundle exec unicorn -D -c /home/ubuntu/apps/st/config/unicorn.rb
I need to run this command soon after the system reboots or starts. I am running the app on ubuntu 10.04 LTS EC2 instance. I tried couple of examples which are mentioned on this site as well as this site but it’s not working for me. Any heads up

Try it as an Upstart. To do so, you need to create a myapp.conf file into the directory /etc/init/ with the contents below:
description "myapp server"
start on runlevel [23]
stop on shutdown
exec sudo -u myuser sh -c "cd /path/to/my/app && bundle exec unicorn -D -c /home/ubuntu/apps/st/config/unicorn.rb"
respawn
After that, you should be able to start/stop/restart your app with the commands below:
start myapp
stop myapp
restart myapp
Use ps -aux | grep myapp to check if your app is running.

You can use this file as a template, set appropriate paths mentioned in this file, make it executable and symlink into /etc/init.d/my_unicorn_server. Now you can start the server using:
sudo service my_unicorn_server start
Then you can do:
sudo update-rc.d my_unicorn_server defaults
To startup the unicorn server on system reboot automatically.

In my case, I just wanted it quick so I place the startup command in /etc/rc.local like below. Note that i'm using RVM.
# By default this script does nothing.
cd <your project dir>
/usr/local/rvm/gems/ruby-2.2.1/wrappers/bundle exec unicorn -c <your project dir>/config/unicorn.conf -D
test -e /etc/ssh/ssh_host_dsa_key || dpkg-reconfigure openssh-server
exit 0
Make sure your startup command is above the exit 0. After you reboot, check whether it is running or not by directly hitting the url of your application or use ps -aux | grep unicorn command.
Note* Previously I use Phusion Passenger but I'm having trouble to see its error log, so I move back to unicorn. I also tried #warantesbr without success, which I guess it fails because my whole environment where setup using root access.

If you are using unicorn_init script
You can configure a cron job to start the unicorn server on reboot
crontab -e
and add
#reboot /bin/bash -l -c 'service unicorn_<your service name> start >> /<path to log file>/cron.log 2>&1'

Related

reboot script to start rails server

My rails server is running under a deployer user and I normally start it like this
#restart.sh
#!/bin/bash
sudo -u deployer -H bash -l
cd /var/www/html/cms/
./server -e staging start
So when I login over SSH i run ./restart.sh and that works great.
I'm trying to do this automatically after a reboot so I've added a reboot_site.service in
/etc/systemd/system/reboot_site.service
# /etc/systemd/system/reboot_site.service
[Unit]
Description=reboot_site
After=syslog.target network.target
[Service]
Type=simple
WorkingDirectory=/var/www/html/cms
# If you use rbenv:
# ExecStart=/bin/bash -lc '/home/deploy/.rbenv/shims/bundle exec sidekiq -e production'
# If you use the system's ruby:
ExecStart=/home/ec2-user/restart.sh
[Install]
WantedBy=multi-user.target
The service is enabled using sudo systemctl enable reboot_site.service
However when I now reboot the server the script stops execution after the following line
sudo -u deployer -H bash -l
Server is an AWS EC2 AIM instance
What's wrong with my configuration to make this work and how can I fix this?
It stops on sudo -u deployer -H bash -l because your script just changes user and will not continue until you logout as this user. So the remaining commands in your script are not executed.
I would suggest the following version which uses runuser:
#!/bin/bash
runuser -l deployer -c 'cd /var/www/html/cms/ && ./server -e staging start'
if you just need to run a script on startup you can configure a crontab for this
#crontab -e
#reboot /home/ec2-user/restart.sh

Shell into a Docker container running on a Heroku dyno. How?

Given a dyno in which a container is running, what's the Heroku equivalent of docker exec -it blarg /bin/bash? That is, how can one open a shell into the already-running container?
Example Dockerfile:
FROM heroku/heroku:16
CMD while true; do sleep 1; done
Example run:
$ heroku container:push my_app
<wait a minute>
$ heroku ps
=== my_app (Free): /bin/sh -c while\ true\;\ do\ sleep\ 1\;\ done (1)
my_app.1: up 2017/10/09 12:13:07 -0600 (~ 4m ago)
So far so good.
But now...
$ heroku ps:exec --dyno=my_app.1
Establishing credentials... error
▸ Could not connect to dyno!
▸ Check if the dyno is running with `heroku ps'
For good measure I check heroku ps at this point and it shows that the dyno is still running.
Yes, I've done all the things Heroku suggests to enable Docker support. Per the documentation, I have tried using a base image of my choice while ensuring that bash, curl, openssh, and python are present. I have also tried using the Heroku-16 base image, as shown in the above example.
(The linked documentation also references steps required for Private Spaces. Since I'm not using Private Spaces I have not applied those steps.)
EDIT CIRCA 2022 This was the accepted answer in 2017. I'm not so sure anymore, so I'm unaccepting my answer here to avoid misleading anyone. I'm not fiddling with Heroku + Docker these days, so I'm not in a good position to accept an answer.
TL;DR Ensure that bash is installed in the image and add this to your Dockerfile:
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
Explanation
Contrary to what the documentation would lead one to believe, Heroku does not, out of the box, support heroku ps:exec into a Docker container already running in a dyno.
Quoting from responses I have received from the Heroku team:
Our ps:exec feature ... works ... by injecting a bash file into dynos,
opening an additional port in the background, and allowing you to
connect to it.
[T]he default
shell used by Docker is /bin/sh, which is not compatible with the
Heroku Exec script (it's requires /bin/bash).
There is a workaround you can use though. Put the following in your
Dockerfile:
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
This is definitely a gap in
our product, and we'll work to make this better.
If bash is installed, run heroku run bash. This will get you into the shell from your command line.
You can also use the GUI and go to "More" -> "Run Console" on your heroku app, and input "bash" to bring it up there.
Edited:
In order to run heroku ps:exec on apps with Docker and deployed via the Container Registry you have to enable runtime-heroku-exec.
You can do heroku features:enable runtime-heroku-exec to enable it
Here you can see the documentation of exec with the instructions to enable docker support
in my situation, to get this working with Ubuntu 20.04 (focal), i had to additionally install the python-is-python3 package into the docker image, to get heroku-exec working.
here is a working example (october 2020) of an ubuntu-based dockerfile, that works with heroku-exec:
FROM ubuntu:focal
# install required packages
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y python3 curl python-is-python3 openssh-server iproute2 nginx && apt-get clean
# simplfy nginx config to enable ENV variable substitution
RUN echo 'server { listen PORT_NUMBER; }' > /etc/nginx/sites-enabled/default
# add config required for HEROKU_EXEC
# ENV HEROKU_EXEC_DEBUG=1
RUN rm /bin/sh \
&& ln -s /bin/bash /bin/sh \
&& mkdir -p /app/.profile.d/ \
&& printf '#!/usr/bin/env bash\n\nset +o posix\n\n[ -z "$SSH_CLIENT" ] && source <(curl --fail --retry 7 -sSL "$HEROKU_EXEC_URL")\n' > /app/.profile.d/heroku-exec.sh \
&& chmod +x /app/.profile.d/heroku-exec.sh
# configure NGINX to listen on dynamic $PORT env variable supplied by Heroku.
CMD sed -i 's/PORT_NUMBER/'"$PORT"'/g' /etc/nginx/sites-enabled/default; nginx -g 'daemon off;'
then connect with this command:
heroku ps:exec -a name-of-app-12345
Both heroku run /bin/bash and heroku ps:exec won't work in my situation. The former opens a new container which is different from the real one running! The latter just doesn't work in my container of alpine3, though heroku features:enable runtime-heroku-exec can succeed. My solution is to bring up a shell server and a traffic forwarder in the container. Then on the client connect to the shell server with tunnel created by traffic forwarder.
traffic flow:
localhost:2023 -> chisel client -> ...tunnel... -> chisel server -> localhost:8182
In conainer, start up a shell server with socat and a tunnel server with chisel:
nohup socat tcp-l:8182,reuseaddr,fork exec:/bin/bash,pty,setsid,setpgid,stderr,ctty > /tmp/socat.log 2>&1 &
nohup ./chisel server --port $PORT --proxy http://httpbin.org > /tmp/chisel.log 2>&1 &
On client side, start a chisel client to forward traffic from localhost:8182 to the socat on the server
chisel client http://yourapp.herokuapp.com/ 0.0.0.0:2023:localhost:8182
on client side, open another terminal window:
socat -,raw,echo=0 tcp:127.0.0.1:2023
How to get the chisel on server? Download it or just compile from source in Dockerfile
download chisel
One probably root cause is the docker not running in detached mode on Heroku.
https://docs.docker.com/language/nodejs/run-containers/#run-in-detached-mode
Have someone do know how to activate -d option when the container is being executed by Heroku?

start unicorn on startup

I'm using Rails 4 + Nginx + Unicorn and I want that when my raspberry pi is rebooted it should run Rails application on startup.
Issue: The Nginx is running but unicorn is not running.
I've put in /etc/rc.local file the following command
cd /opt/www/RAILSAPP/current && bundle exec unicorn -E production -c config/unicorn.rb -D
but its not up when I'm rebooting. when I'm accessing the pi via ssh and run the command its working.
How can I start unicorn on startup in order to serve the rails app?

Starting god as deploy user

I have an init.d script to start up god on my server after a reboot.
I've run sudo chmod +x /etc/init.d/god and sudo update-rc.d -f god defaults and when I run /etc/init.d/god start as the deploy user I have no issues and god starts.
However, when I reboot the server god doesn't start.
When I try and start god manually as root I get this error:
Your Ruby version is 1.9.3, but your Gemfile specified 2.3.0
I believe the issue is something to do with root not having rvm or ruby 2.3.0. Is there a way to run the init.d script as deploy?
I'm on Ubuntu 14.04, ruby 2.3.0 and god 0.13.7
You can run any command (or execute a script) as any user with the sudo command; just use the -u flag to specify the user. Example:
sudo -u deploy /etc/init.d/god
See more here: http://www.sudo.ws/man/1.8.15/sudo.man.html

master failed to start, check stderr log for details

I'm trying to start unicorn and I keep getting this error constantly.
My unicorn.rb (https://gist.github.com/anonymous/d1f3d9bcdd1a6c4d8435)
Command that I'm using to start unicorn:
/home/app/adsgold/# unicorn_rails master -c config/unicorn.rb -D -E production
Commands that I've already tried:
/home/app/adsgold/# unicorn_rails -c config/unicorn.rb -D -E production
/home/app/adsgold/# unicorn_rails master -c config/unicorn.rb -D -E production -p 3000
/home/app/adsgold/# bundle exec master unicorn -c unicorn.cnf -E production -D
Complete error beeing shown: https://gist.github.com/anonymous/828d9677f928fa671762
It looks you have RVM and Ruby installed system-wide. Generally it may cause lots of issues. Even RVM documentation warns about that. Try to install RVM and Ruby as user, which owns app directory. In that case you will get consistent system.
By the way, do you have this directory /home/deploy/apps/shared on your environment? Is it writable for your App? According Unicorn config following things depend on it:
pid "/home/deploy/apps/shared/pids/unicorn.pid"
stderr_path "/home/deploy/apps/shared/log/unicorn.stderr.log"
stdout_path "/home/deploy/apps/shared/log/unicorn.stdout.log"
If you do have all this stuff, content of /home/deploy/apps/shared/log/unicorn.stderr.log also would be helpful.
Are the necessary permissions in place? (I notice the read error comes from a globally-installed gem, so I'm wondering what all is where.)

Resources