I have a sinatra app with a page that shows some information about the application. Some of which is generated by running commands on page load. Everything works fine on my MacBook when running in unicorn and everything works fine on the production server when running in unicorn but swap to Apache/Passenger and suddenly the commands start returning nil.
For example to get a list of committers I use:
comitters = `cd /path/to/app && git shortlog -s -n`
This works perfectly until run in the apache/passenger setup.
Is there some option within passenger that disables system commands?
The problem lies in your $PATH environment variable, which the system uses to look for commands. You run Unicorn from the shell don't you? So Unicorn inherit $PATH from your shell. But app processes started from Phusion Passenger are started from Apache/Nginx, which in turn are usually started from some system init service, which have completely different environment variables than your shell. Read http://blog.phusion.nl/2008/12/16/passing-environment-variables-to-ruby-from-phusion-passenger/ for a solution.
Related
I'm currently working on a build pipeline that uses Jenkins and GitLab to trigger builds for the project. Basically, the build is triggered when someone pushes to the repository. Also, some Ruby scripts are executed as part of the build process. These scripts run some checks on the projects and perform some fixes, like synchronizing an Xcode project with added and deleted files from the source directory - in this case they are not the same.
I'm using several tools to configure the pipeline. The builds run on a machine that is physically located on the build slave. Jenkins is deployed to an AWS machine. For this reason, I used pritunl to connect the two on a virtual network. I can use local IPs to communicate between the machines and SSH is working fine both ways.
When I push to the remote the build starts correctly on the slave, but it fails to complete. However, if I manually access using SSH through the terminal, the build performs fine. This is the output I get from Jenkins:
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- xcodeproj (LoadError)
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/jenkins/workspace/Core/platform/ios/scripts/pbxsync.rb:58:in `<main>'
As you can see, it fails to require Xcodeproj, causing the build to fail. Still, this only happens if the build is triggered by Jenkins, not manually.
This makes me think that Jenkins is using some different installation of Ruby, or at least a different environment. Basically what I need is to install gems for the same Ruby environment that Jenkins is using, but I don't know which one that is. Any ideas?
Jenkins has a console that runs Groovy scripts on the remote slave. I've been playing with it a bit, but not many conclusions so far. Maybe that helps.
This may be important; this is the shebang I'm using for the Ruby scripts: #!/usr/bin/env ruby
On the terminal, I'm using the same user as Jenkins is to access the slave machine. It's called "jenkins".
One thing I forgot to mention is that the output is telling me the right version: /Users/jenkins/.rvm/rubies/ruby-2.4.0. At least that's the path it's indicating it's trying to load the gem from. So I tried the following:
: /Users/jenkins/.rvm/rubies/ruby-2.4.0/bin/ruby
require 'xcodeproj'
Then I press ctrl+D and get no output - that installation of ruby is finding the gem properly.
If you are using Jenkins Slave plugin to communicate between Jenkins Master and Jenkins Slave, every command that u specify will be run in non-interactive shell. That means that Jenkins will only have access to system ruby in your case.
So if you want to install something that needs to be installed you have to do it in system ruby. You are using rvm so: rvm use system and you can install gem to system ruby.
If you want to use different Ruby version than system ruby you need to add RVM to $PATH for non-interactive shell. Here is basic setup that should help: https://rvm.io/rvm/basics
I finally managed it. As #Cosaquee indicated in another response, it's important to distinguish between interactive and non-interactive shells. The main reason for this is because, depending on how you call SSH, it makes a difference. As the man page indicates:
If command is specified, it is executed on the remote host instead of
a login shell.
This is meaningful, because the Launch Command for the node I have set for Jenkins is this one:
ssh jenkins#x.x.x.x java -jar ~/bin/slave.jar
In the meanwhile, I was logging in with the standard ssh jenkins#x.x.x.x from the terminal, which starts a login shell. It makes sense that I was getting different results because the two shells load different initial scripts. Basically, if you use ssh jenkins#x.x.x.x to login into the machine ~/.bash_profile is loaded, while if you specify a command, such as ssh jenkins#x.x.x.x whatever, then ~/.bashrc is loaded instead. As such, I added this line to ~/.bashrc:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
Without it I got:
RVM is not a function, selecting rubies with 'rvm use ...' will not
work.
The advantage was that I could now use RVM from the same environment Jenkins was using. The rest is easy:
ssh jenkins#x.x.x.x rvm --default use 2.3
And:
ssh jenkins#x.x.x.x
rvm --default use 2.3
And both are now using the same version of ruby.
I use the built-in options to distribute my Ruby on Rails app.
Meaning I start the server with
rails s -e production -p 80 -d
But as soon as I append the daemon flag -d to this command I can no longer execute shell commands...
I tried a wide spectrum of possibilities to execute commands e.g.:
system(cmd)
%x[ #{cmd} ]
`#{cmd}`
Process.detach(spawn(cmd))
Process.fork do
p = spawn(cmd)
Process.detach(p)
end
And I have no idea what else I can do...
Would be very grateful for a hint/solution...
Some informations to the running system:
OS: Ubuntu 14.04 LTS
Rail Version: 4.0.2
I log via ssh onto the computer and start the rails server
I've tested all commands listed above, they all work without the daemon flag but will not work with it...
Thanks in advance.
Greetings Alex
Failure found.
There is not connection between Server as daemon and no processes/shell commands.
I was just stupid enough to look in the wrong dirs...
Note:
If you execute the rails server as daemon it is no longer a process of the user but of the root. Just check the next time if all paths are bullet proof.
In my old Ruby 1.9.2 Sinatra apps running on Bamboo stack, heroku console provided a shell that not only initialized Active Record but also logged to a history file in my .heroku directory.
After moving to Heroku Cedar stack and using Ruby 1.9.3, I found heroku run console did not load any of my Active Record models. I fixed that by writing a small ruby script to initialize Active Record and load my models.
I execute this using the awkward heroku run 'bundle exec irb -r ./console'
This IRB console fires up fine and gives me access to my model data, but no history is logged.
1) Why is heroku run console so neutered?
2) How can I get my console sessions to log to history?
Please?
Thanks
Add the following line to your Procfile:
console: bundle exec irb -r ./console
Keeping the history is not easily possible, as it will spin up a dyno for every new invocation (cedar stack doesn't keep the history for Rails console, either). You could try using rlwrap to keep your history on the local machine.
From the docs:
You can use heroku console as a stand-in for Rails’s script runner, to
run one-time commands directly from the command line
and
Without an argument, heroku console launches an interactive console
similar to irb or the Rails script/console command
run console is aimed at running the Rails console, or irb.
Ok, I'm making my first ruby app. Who know moving everything over to 'production' is so fugging complicated. So far I've struggled my way through configuring passenger, getting it to run on startup, then getting redis to run on startup.
My last task is on startup to add 1 worker. Right now, I have to ssh in and run my rake command rake workers:start. Obviously this is no good when I want to close ssh.. so I just dont really know how or what the next step is.
I tried copying resque default config to config.ru and it just blows up Passenger with errors. I also looked into resque-pool which some people mentioned but that is over my head.
all i have to do is add 1 worker on bootup. This isnt that serious of an app so simpler would be best at this point.
I don't use the god gem because (1) I've seen a project that was very thrashed by the complexity of setup it introduced, and (2) I'm personally really comfortable with the standard Linux (Ubuntu) tools that handle this kind of thing.
To start the Resque workers on bootup
I have this code in my /etc/rc.local file. I have a deploy user on the system:
# Start Resque
su -l deploy -c "/home/deploy/start-resque-workers"
su -l deploy -c "/home/deploy/start-resque-webui"
Then, in those scripts I set up the ruby environment and run the rake task:
# Load RVM into a shell session *as a function*
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
# First try to load from a user install
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
# Then try to load from a root install
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
fi
# Use rvm to switch to the default ruby.
rvm use default
# Now launch the app
cd /home/deploy/app-name-here/current
nohup rake QUEUE=* RAILS_ENV=production environment resque:work &
I've been using this kind of set up for years, and it's solid. The servers don't crash. I don't yet need the overhead of installing another system (like the god gem) to watch over these other servers.
Additionally, I use a capistrano gem to handle restarting the workers on deploy.
In production you should be using god to watch your processes. Even if this project is a small one, I strongly recommend investing your time and setting it up.
Another big a must is Capistrano.
So, if you were using god, here's a config file that would help you.
You could also try scheduling rake resque:work at system startup, using a proper script in /etc/init.d/ or /etc/init/ or another (depends on what system you use). I tried this some time ago and I gave up (don't remember why).
I understand that this my answer isn't exactly what you're looking for right now. But imagine this: if everything is set up, then deploying next version is as easy as running rake deploy on your development machine. And it will take care of pulling your code from repository, running migrations, restarting workers and webservers and what not.
I am trying to set up a small web server on my old mac mini G4 at home using the technologies mentioned in the title. I have learned that to serve anything on port 80, the server has to be started with sudo. Since I am using RVM to manage my Ruby Gems, I use rvmsudo to start the server.
I have created a user for running the server, and I can start the server by logging in via SSH and typing 'rvmsudo unicorn -p 80'. But of course when I close the connection the process is terminated, so this is obviously not the way to go.
What is the 'right' way to set up a server on Mac OS Leopard? Keeping in mind that I would like to keep using RVM to manage my gems. I would also like the server to start running automatically when the computer is booted.
you could use the tool GNU screen
http://www.gnu.org/software/screen/
and detach the screen, so the processes will continue running.
alternatively, you could try if this command does the trick:
rvmsudo unicorn -p 80