Start ruby rake task on server boot - ruby-on-rails

I have a couple of rails rake tasks that I need to start on server bootup. I have been looking to make them run as traditional services using systemd. The service file is created under /etc/system/systemd but unfortunately it looks like systemd did not find the file:
#systemctl start screens.service
Failed to issue method call: Unit screens.service failed to load: No such file or directory. See system logs and 'systemctl status screens.service' for details.
#systemctl status screens.service
screens.service
Loaded: error
Active: inactive (dead)
I am currently using Fedora 15
How can I make my systemd service work? Is there another way I could make my rake tasks run at system boot.
Update: screens.service file content
[Unit]
Description=Send Reminders
[Service]
Type=simple
User=myuser
WorkingDirectory=/path/to/rails/app
ExecStart=/usr/local/rvm/gems/ruby-1.9.3-p194/bin/rake reminders:send
I know that I need to set dependencies when I need it to work on bootup, but currently I am trying to start my rake using systemctl command and worry about it dependencies later.

First, instead of calling rake directly, I would call /path/to/ruby/bin/bundle exec rake my:raketask.
Second, I think you should really take a look at the foreman gem, as it's designed to handle this situation, though you might have to adapt it work with systemd.
One way would be to call foreman from systemd init file, passing it options to specify the Procfile (foreman config file) in your app's directory.
Foreman can already export its config to several formats, but I don't think yours is among them. But,
you could create a custom exporter that exports the foreman configuration to systemd format. See https://github.com/ddollar/foreman/wiki/Custom-exporters for more information. If you go this route, consider contributing your exporter back to the foreman project.

To make systemd take notice of the newly added services I had to insert the following command:
systemctl daemon-reload

Normally if you need to start something in the application initializer, you could put the .rb file to
config/initializers/ folder
Would you elaborate your requirement, because there might be some other way of doing the same? :)

Related

How to get systemd to restart Rails App with Puma

I've been struggling with this a week now and really can't seem to find an answer. I've deployed my Rails App with Capistrano. I use Puma as a server.
When I deploy, everything works ok. The problem is to get Puma to start at reboot and/or when it crashes.
To get the deployment setup, I've used this tutorial. I'm also using RVM. The problem I seem to get is to get the service to start Puma. Here's what I've used (service file):
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
Type=simple
#User=my-user
WorkingDirectory=/home/my-user/apps/MyApp/current
ExecStart=/home/my-user/apps/MyApp/current/sbin/puma -C /home/my-user/apps/MyApp/shared/puma.rb
Restart=always
[Install]
WantedBy=multi-user.target
That doesn't work. I was starting to think the problem was Ruby not being installed for all users, so I've installed RVM for all users and still get the same problem. My server has only root and my-user.
Looking at how Capistrano deploys, the command it runs is: cd /home/my-user/apps/MyApp/current && ( RACK_ENV=production /home/my-user/.rvm/bin/rvm default do bundle exec puma -C /home/my-user/apps/MyApp/shared/puma.rb --daemon ). If I use the aforementioned command, I get an error from Systmd complaining about missing parameters. So I've written a script with it and got the service file to call this script to start the app.
That doesn't work either. Note that if I call the script from anywhere on the server the script does start the App, so its an issue on configuring Systemd, but I can't figure out what's wrong and I'm not sure how to debug it. I've seen the debug page on System's website, but it didn't help me. If I run systemctl status puma.service all it tells me is that the service is in failed state, but it doesn't tell me how or why.
Also worth noting: If I run bundle exec puma -C /home/my-user/apps/MyApp/shared/puma.rb from my App folder it works ok, so how I could duplicate this command with Systemd service?
At the end the problem was twofold: 1) rvm wasn't installed properly for all users, which meant the deployer user didn't have ruby/bundle/etc available and secondarily the script was also wrong. For reference below is the revised script that worked for me:
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
Type=simple
User=deployer
WorkingDirectory=/var/www/apps/MRCbe/current
ExecStart=/bin/bash -lc 'bundle exec puma -C /var/www/apps/MRCbe/shared/puma.rb'
Restart=always
[Install]
WantedBy=multi-user.target
Have you looked into Foreman ?
Foreman makes it easy to start and stop your application if it has multiple processes.
Incidentally it also provides an export function that can generate some systemd or upstart scripts for you to (re)start and stop your application.
As you are already using capistrano you can use capistrano-foreman to integrate all this nicely with capistrano.
I hope you find some use in these resources

Booting up Sidekiq with Upstart

My goal is to have sidekiq start when the server boots up (I'm using EC2 with an auto-scaling group). I know there are a few other posts regarding getting sidekiq to start with upstart on boot, but I don't believe mine has been addressed specifically.
I'm using this wiki - https://github.com/mperham/sidekiq/tree/master/examples/upstart/manage-many and have placed the scripts inside /etc/init/sidekiq.conf and /etc/init/sidekiq-manager.conf.
I've made a couple small modifications as directed in /etc/init/sidekiq.conf, changing:
# setuid apps
# setgid apps -> replaced apps with ubuntu in both lines, which is the deployment user.
export HOME=/home/apps to export HOME=/home/ubuntu
I also have a /etc/sidekiq.conf that includes the following line:
/home/ubuntu/app_dir, 2
Otherwise, these scripts are identical to those included in the referenced repo. I'm getting the following errors in my logs (/var/log/upstart)
/bin/bash: line 19: cd: 2: No such file or directory
Could not locate Gemfile
It appears as if it's attempting to change directory somewhere other than /home/ubuntu/app_dir, at which point it's in the wrong directory and cannot find my Gemfile.
Is there somewhere else I need to specify a correct path to my app directory?
Thanks!
You can run sidekiq as an upstart job. Making a sidekiq.conf file in /etc/init/ directory and put the upstart code to run sidekiq.
Here is the complete script and the guide to make sidekiq upstart job.
After making this job, sidekiq start/stop/restart would be easy with sudo service command.

Start sidekiq from an exploded war

Our current production deployment uses jenkins to deploy a warble generated war file to Tomcat. The whole thing works like a charm. The problem I'm running into however is how to kick start up sidekiq's workers on this machine via "bundle exec sidekiq [options]". Ideally I'd love to avoid setting up a whole seperate ruby environment on this machine just to do this, but either way to run properly, sidekiq needs access to the exploded/installed apps environment etc.
Is there an accepted way to do something like this? Is there a better way to startup sidekiq in instances like this beyond bundle?
This project may be of help. It allows you to package anything that can be a rake task into a jar file. Their documentation has some specific notes about warbler use. Have a look!
For notes on how to run Sidekiq from outside of the command line run something like this from your project root:
cat $(bundle show sidekiq)/bin/sidekiq
You should see some lines:
cli = Sidekiq::CLI.instance
cli.parse
cli.run
If you read into the CLI class, you'll notice that parse takes either ARGV as the default argument, but you can override it with your own arguments:
cli.parse "-q myqueue -e production".split(' ')

How to autostart Rails delayed jobs?

I'm using delayed job to create job queues such as 'mailer'
For this to work I have to run this:
$ RAILS_ENV=development QUEUE=mailer rake jobs:work
But if the server crashes and is restarted, I need the worker to start running again automatically.
What would be the recommended way to deal with this?
You need to use a third-party service like monit/bluepill/god/upstart to watch the process and restart it. I recommend using the combination of foreman and upstart. See here: http://blog.daviddollar.org/2011/05/06/introducing-foreman.html
Some time ago I wrote a patch for the DelayedJob to reload the classes for every job in development mode. Same patch should work for your requirement also.
betamatt's approach is definitely one way to do it if you have such a monitoring tool in place.
Another way to do it would simply be to add a script to your OS's startup which runs the RAILS_ENV=development QUEUE=mailer rake jobs:work command under a user who has the necessary permissions.
Here's an example of how to do it on Ubuntu using Upstart, but if you lookup similar init.d methods, or whatever is the relevant for your server OS, you'll find other ways. What you're looking for, basically, is "How to run a script on startup [your OS name]", and then wrap your command in an executable script.
I had the same issue with my application am working with. So i wrote a rake task which runs every minute(as a cron job). When delayed job starts it will create a .pid file in the temp folder. I used this to check the existence of a delayed job process. If the file doesn't exist i ran the console command through code.
delayed_job_status = File.file?("./tmp/pids/delayed_job.pid")
This will check the existence of process. If nil response go to next statement
./bundle exec script/delayed_job start production
This will start delayed job
My solution was creating the bash script in user's home "delayed_job_startup.sh"
which contain
#!/bin/bash
cd /home/deploy/project/current/
RAILS_ENV=production bin/delayed_job start
and in file /etc/rc.local I run this script from my user
su -s /bin/bash - deploy /home/deploy/delayed_job_startup.sh

Daemon Start at the application bootup

I have a daemon that should run behind my rails app doing db modifications.I implemented that daemon using ruby daemons gem. I want to start that daemon at the start of my app. Whenever my app starts, I need to start that daemon.
How can I do this..?
If you must start it during Rails initialization:
Create a ruby file that will start the daemon. Say invoke_daemon.rb
Put this file in config/initializers/invoke_daemon.rb
However if it isn't mandatory, I would suggest creating a binary executable or a rake task and manually starting it through command line. This way it runs as a separate process. You can simply add it to your deployment scripts for production boxes and on development box run it manually. A few examples would be searchd, the search daemon for sphinx and thinking_sphinx:delayed_delta rake task from thinking_sphinx.
For your knowledge you have to take look of
Rails Life cycle
I have just implemented this thing. I have implemented on Windows7.
I have created one batch file let's say my_batch.bat, which contains ruby command i.e. ruby my_daemon.rb file.
In addition, to execute this file when my app starts , I have just added one statement in environment.rb file which executes that batch file. i.e. system ("my_batch.bat").
But I am not sure that this is a good way to implement this task.

Resources