{"id":73,"date":"2013-12-15T05:10:59","date_gmt":"2013-12-15T05:10:59","guid":{"rendered":"http:\/\/www.infosynergetics.com\/?p=73"},"modified":"2015-12-11T11:28:53","modified_gmt":"2015-12-11T19:28:53","slug":"deploying-a-rails-app-to-a-linux-server","status":"publish","type":"post","link":"https:\/\/www.infosynergetics.com\/?p=73","title":{"rendered":"Deploying a Rails App to a Linux Server"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" style=\"float: left;\" title=\"Rubymine.png\" src=\"http:\/\/lh5.ggpht.com\/--YnJho3nyqE\/Uq6vI6SnAEI\/AAAAAAAAAQI\/V_C3aw7U_iw\/Rubymine.png?imgmax=800\" alt=\"Rubymine\" width=\"300\" height=\"171\" border=\"0\" \/><\/p>\n<h2>Why?<\/h2>\n<p>Recently, I\u2019ve deployed different Rails apps to three different Linux servers from scratch. \u00a0All three were virtual servers. \u00a0Two were Ubuntu 12.04 servers using Apache. \u00a0The most recent is a Debian server (version 6) running Nginx. \u00a0Each server took progressively less time to launch, but with each one, I found myself grabbing bits and pieces from Stackoverflow.com, and other destinations in order to successfully complete my effort. \u00a0So, I\u2019ve decided to take the notes I made on this most recent deploy and post them here so that perhaps others will be able to benefit from my trials.<\/p>\n<h2>The Host<\/h2>\n<p>For all of my basic websites and e-mail, as well as a couple of old Rails applications, I\u2019ve used Dreamhost shared servers. \u00a0For websites, this has worked out well, being a very cost effective means of managing websites. \u00a0There has also been little downtime and few overall issues. \u00a0However, with Rails, there is a major issue. \u00a0While I understand the desire to avoid being on the bleeding edge with technology, Dreamhost has remained rather rooted in the distant past. \u00a0I have long since ceased doing updates to my first application, the one I use to manage our parish bookstore, simply because I can\u2019t move to any current gems or technologies.<\/p>\n<p>However, Dreamhost has a relatively low cost Virtual Private Server option, where you get a virtual server running Debian. \u00a0There are various levels of configuration for the server, from situations where Dreamhost manages most of the major configuration options (web server, users, etc.) to where you manage it all. \u00a0In the few days there are only two negatives with Dreamhost, and neither of them represent, in my judgement, much of a problem. \u00a0The first is that you have to use Debian &#8211; there is no other option. \u00a0The only other company I have to compare this to is Rackspace, where you have a wide variety of Linux flavors (and Windows for an appropriately larger fee). \u00a0With Rackspace, however, there is a bit of an increased cost that comes with the flexibility. \u00a0The other issue is around the chat support. \u00a0With Rackspace, I tend to have a very capable technical person in the chat app in under a minute. \u00a0With Dreamhost it has been 10 -15 minutes, and I\u2019ll admit the quality of the technician isn\u2019t as high. \u00a0Nothing dramatic, but there is a level of you get what you pay for.<\/p>\n<p>While discussing hosts, I should mention my choice of code repository. \u00a0I have opted to use bitbucket.org, an Atlassian product. Why? \u00a0Well, free is the good part, but I also get to have the repository remain private. \u00a0The only limitation I have is that I can\u2019t move past 5 users. \u00a0Well, since these are apps that I\u2019m building myself, I doubt this will be an issue. \u00a0You can, of course, use Github, but you have to pay to be private. \u00a0I\u2019m a huge Open Source fan, but I don\u2019t necessarily want everything that I\u2019m working on to simply be out there. \u00a0At some point in the future, I may take some of these apps and make them publicly available, but I like being able to start with them privately.<\/p>\n<h2>Okay, Let\u2019s Get Down to Work<\/h2>\n<p>So, I provisioned the Dreamhost VPS and since I get a week free, I opted to max out the memory available for the server. \u00a0This proves to be beneficial as some of the software installation processes get very memory intensive. \u00a0Installing the Pasenger-nginx module will complain if you have less than 1024 Mb of RAM, and if your server doesn\u2019t have that much, it will reboot in the middle of the installation process. \u00a0I opted to deselect every \u201cDreamhost Managed\u201d option, perhaps even when I didn\u2019t need to, but I figured it would be safest to be able to do my own installations. \u00a0This included selecting no web server to begin with.<\/p>\n<p>For most of the installation process, I followed the instructions at <a href=\"https:\/\/www.digitalocean.com\/community\/articles\/how-to-install-rails-and-nginx-with-passenger-on-ubuntu\">Digital Ocean<\/a>. \u00a0Yes, these instructions are for Ubuntu, but that is a Debian variant after all, so I didn\u2019t run into any trouble. \u00a0The only thing I did differently to begin with was to run aptitude update and aptitude dist-upgrade in order to ensure that everything I needed was available. \u00a0I also opted to follow the RVM installation instructions from the RVM <a href=\"https:\/\/rvm.io\/rvm\/install\">website<\/a> for multiuser. \u00a0I have, over time, found various sets of instructions on RVM installation, and have always found it best to simply go with the authors.<\/p>\n<p>Everything else installed as indicated (I did opt for Ruby version 2 instead of 1.9.3).<\/p>\n<h2>Nginx<\/h2>\n<p>I opted for Nginx in all of this for a couple of reasons. \u00a0The first is that I really didn\u2019t need all of the capabilities of Apache to run just Rails applications. \u00a0Down the road, I do expect to use Solr, but I believe that the installation will build its own version of Apache. \u00a0Nginx is also supposed to keep a relatively small memory footprint, which is important as I\u2019m paying for memory, and it is supposed to be faster. \u00a0I haven\u2019t run my application on it long enough to decide, but time will tell.<\/p>\n<p>When you are done running the above instructions, it is likely that Nginx won\u2019t work. \u00a0\ud83d\ude42 Surprise.<\/p>\n<p>I believe that the problem was I had residual Dreamhost Nginx pieces on my server, most notably the nginx init script from the \/etc\/init.d directory. \u00a0For those who are very adept at fixing Linux scripts, fixing the one that is present isn\u2019t probably very difficult. \u00a0For my part, though, I just grabbed the script present on <a href=\"http:\/\/foz.github.io\/debian-rails-setup.html\">this<\/a> page about setting up Debian and Rails. \u00a0The script is not entirely robust, as I find myself needing to manually kill the nginx processes if I need to restart them, but that isn\u2019t much trouble and I\u2019ll likely fix this later. \u00a0Outside of making the script executable and ensuring that it runs at startup, I mostly ignored this page. \u00a0A lot of it is because the default Debian install from Dreamhost has much of it taken care of. \u00a0The other issue has to do with RVM. \u00a0I\u2019ve long since learned the advantage of using RVM, so manually installing Ruby seems like a bad idea. \u00a0There are some other interesting looking parts on that page, so I suspect it is more useful in general than I took advantage of.<\/p>\n<p>After making these changes, Nginx just\u2026 didn\u2019t work. \u00a0The problem was with the log files for Nginx which were all owned by root. \u00a0Seems like a bad idea. \u00a0I modified \/opt\/nginx\/conf\/nginx.conf to run as www-data then changed the log file ownership appropriately. \u00a0This is user is very much unprivileged in the system, and so seems like a good choice to run nginx as (Apache defaults to this to, so it should seem familiar to people who have worked with Apache).<\/p>\n<h2>MySQL<\/h2>\n<p>MySql installation was amazingly painless. I\u2019ve had problems with it before, but I followed the instructions from <a href=\"http:\/\/www.cyberciti.biz\/faq\/howto-debian-mysql-install-apt-get-commands\/\">cyberciti.biz<\/a>, and all was happy.<\/p>\n<h2>Deployment and Rails Tidbits<\/h2>\n<p>A lot of what I\u2019m going to say here will likely result in a bunch of face palming by more talented developers than I, but since I\u2019ve not done a lot of new deploys in the past, I still trip over amazingly trivial things, so I figure (hope) I\u2019m not alone in this.<\/p>\n<p>The first bit is to remember to generate keys on both your development machine and on the server and provide the public keys to bitbucket, so you can download the source code during the deploy process. \u00a0BTW, I use Capistrano for deploying my rails apps, as I find it easier for doing updates. \u00a0Frankly for an initial install, I don\u2019t think it helps too much, but down the road you\u2019ll be happy if you use it.<\/p>\n<p>When you create the keys on your server, make sure you do not use a pass phrase. \u00a0Although the server will ask for your passphrase during the deployment process, Capistrano doesn\u2019t seem to actually transmit it, so your deploy will fail.<\/p>\n<p>Also, don\u2019t forget to run cap (stage) deploy:setup. \u00a0I always forget to do that on first install, then watch it fail as the target directories don\u2019t exist. \u00a0<del>Before you do the deploy, however, you should change the \/var\/www directory to be owned (chown www-data:www-data) and writable (chmod g+w) by the www-data group. \u00a0I should have mentioned that my deployment server user is a member of www-data. \u00a0This makes it easier to make changes during the installation process. \u00a0\u00a0<\/del>Turns out that giving global www-data too many privileges is not wise. \u00a0Plan on running the rails application under a dedicated service account and give that account permissions to the appropriate folders for running the application (typically you just need public, tmp and log directories and their subs, as well as any custom directories you need to write to). \u00a0The installation can run using your user account.<\/p>\n<p>Two other issues I ran into had to do with bundler and with a javascript runtime. \u00a0I ran deploy and received an error that there was no bundler. \u00a0I performed a gem install bundler on the server, but that didn\u2019t help. \u00a0I then discovered that I was missing a require \u2018rvm\/capistrano\u2019 at the top of my deploy file, which is necessary for doing capistrano deploys in an rvm environment.<\/p>\n<p>The javascript runtime is best dealt with by installing node.js which you can do by following the instructions <a href=\"https:\/\/github.com\/joyent\/node\/wiki\/Installing-Node.js-via-package-manager\">here<\/a>. \u00a0You can go get a cup of coffee and a doughnut while this installer is running. \u00a0It takes a while.<\/p>\n<p>Another problem was with using Zurb foundation. \u00a0Since the foundation css file doesn\u2019t actually exist, the application will not run when you access it from your web browser. \u00a0So, it is necessary to run a bundle exec rake assets:precompile at the end of your installation. \u00a0Apparently you will also need the compass gem in your gem file ahead of the foundation gem.<\/p>\n<p>Finally, if you are running multiple stages on your server (I have a staging, um, stage, for testing new stuff out with users) you want to make sure the RAILS_ENV variable is properly set. \u00a0You can follow the instructions at the <a href=\"http:\/\/www.modrails.com\/documentation\/Users%20guide%20Nginx.html#RailsEnv\">mod rails<\/a> site for doing this.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why? Recently, I\u2019ve deployed different Rails apps to three different Linux servers from scratch. \u00a0All three were virtual servers. \u00a0Two were Ubuntu 12.04 servers using Apache. \u00a0The most recent is a Debian server (version 6) running Nginx. \u00a0Each server took progressively less time to launch, but with each one, I found myself grabbing bits and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-73","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/posts\/73","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=73"}],"version-history":[{"count":4,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/posts\/73\/revisions"}],"predecessor-version":[{"id":197,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=\/wp\/v2\/posts\/73\/revisions\/197"}],"wp:attachment":[{"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=73"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=73"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.infosynergetics.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=73"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}