I’ve done it again… Needed to setup an Ubuntu machine to run a simple CRUD web app I maintain for a small ministry group. The app is built on Rails 3.2.8, Bootstrap 2 UI, Ruby 1.9.3, and uses SqlLite for a local single-file database. I began writing the app in April 2012, with small tweaks here and there each year since. It was my first real Rails app, and it still runs fine today as a contact management system for the 5-person distributed team who use it to track their ministry contacts and record various interactions they each have with their members.
I needed to move the app off of my own network which has plenty of internet and power outages throughout the year, so I decided to go with a cloud hosted option and chose Digital Ocean and one of their small “droplet” containers running a ready-to-use Ubuntu 14.04 system. I am able to get by with 1GB RAM AND 20gb storage, so the cost is $10 per month. Once the droplet is created using their very simple web portal, you get nothing more than a Linux box that you can access via SSH, VNC, or a terminal client like Putty (I installed Putty on my Windows machine using Chocolatey). It’s all terminal windows from there; no GUI at all.
So, to install Ruby and Rails, I logged into my droplet via a Putty terminal session and I followed one of the Digital Ocean help docs on how to install Ruby. It has you install RVM, and from that you can install the Ruby version that your app needs (in my case ruby-1.9.3-p392).
Here’s the RVM setup link from Digital Ocean: https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-on-ubuntu-14-04-using-rvm
Then I installed git so I could clone the source code repo of my app from my BitBucket account:
1 |
apt-get install git |
Then I had to install the Bundler gem so I could install all the other gems my apps needs to run:
1 |
gem install bundler |
To install the other gems in my app’s bundle list:
1 |
bundle install |
One snag… While all the gems were installing during “bundle install”, I got some error with the “nokogiri” gem, complaining that “libxml2 is missing“. I found a post on StackOverflow that showed my how to fix this problem:
http://stackoverflow.com/questions/6277456/nokogiri-installation-fails-libxml2-is-missing
1 |
sudo apt-get install libxslt-dev libxml2-dev |
Next, I ran “bundle install” again, and this time all gems installed fine.
So, now I tried to run my app using the built in Rails server:
1 |
rails s -p 3002 |
and I got an error that something in the app “Could not find a Javascript runtime“, so, back to StockOverflow from a google, and I learned how to fix this issue:
http://stackoverflow.com/questions/16846088/rails-server-does-not-start-could-not-find-a-javascript-runtime
1 |
apt-get -y install nodejs |
So, finally after all this hacking around in the terminal window, the app ran fine using the built in Rails “WEBrick” server, which is all I need to host my app for about 5 users.
UPDATE: How to keep the WEBrick web server process running after I shut down the Putty console session I used to remote in and start up the app
I had used the Putty terminal app to remote into the VM droplet and start up the app using the rails command listed above, but when I closed the terminal session, the app process was killed and no one could access it from their web browsers. So, I found a StackExchange post that explained how to run a process in the background and tell it to ignore the shutting down of the terminal session so it would stay alive even after the terminal session ended. Here’e the link: http://unix.stackexchange.com/questions/479/keep-ssh-sessions-running-after-disconnection
This “nohup” command starts a process and tells it to “ignore the hang up command when the terminal session is ended“, and we can also add the the “&” command line flag which means “run the process in the background“. With this we can now exit the terminal session and the process will continue running to server web requests.
Command:
1 |
nohup rails s -p 3002 & |
As long as you are in the same terminal session as you started the process under, you can use the “jobs -l” command to see the running background process that you just started and see the process id. (Important: You’ll need the process id whenever you need to stop the Rail/WEBrick web server. Keep reading below…)
1 |
jobs -l |
Here’s the output:
1 |
[1]+ 3583 Running nohup rails s -p 3002 & |
Now you can quit the terminal session, but the app will still keep running, so users can access the web app from their browser.
If you close this terminal session and log in later with a new terminal session later, it’s a little harder to find the process id of the Ruby/WEBrick session that you started in the original terminal session. However, we can find the process id using this command (notice we are running the output from “ps” through grep and filtering with “ruby” so that we will see only the ruby processes. You could also filter on “rails” just as well:
1 |
ps aux | grep ruby |
Stopping the process
Now, when you need to end (kill) the process to stop it, you have to know the process_id and use a special flag on the kill command, because the NOHUP command used to start the process will cause it to ignore the kill command. The command is: kill -9 [proceess_id]. (See notes above on how to learn the correct process_id.)
See this link for more info on this matter: http://stackoverflow.com/questions/8007380/how-to-kill-a-nohup-process
So:
1 |
kill -9 3583 |
Another update…FTP access
A few days later I wanted to FTP upload some files to my Droplet on Digital Ocean. So, I found this really simple help post on the Digital Ocean community forum. It explains how you can use FileZilla and the SFTP secure protocol to easily connect to your Droplet from a FileZilla client session running on your local machine. There’s no configuration required in your droplet; it was built-in and ready to use on my Ubuntu 14.04 droplet that I based my VM on). Here’s the link: https://www.digitalocean.com/community/questions/how-i-get-ftp-login-with-filezilla
Yee-haw!!!
Now, let me get back to my .Net/C#/Sql server/Entity Framework/MVC etc…