Customer Success at Heroku / Salesforce. Former full-time traveler. Current homesteader. He/Him. ENFP. 7w6. Huge fan of @emccartie.
Digital Ocean: Ubuntu, Nginx, Unicorn, Rails
I ran this setup from August 2014 to December 2014. It served me pretty well. However, I’ve since moved it back to Heroku.
Honestly, the setup was fun and I certainly enjoyed the smaller bill, but keeping up with security patches, the cost of server monitoring, worrying about firewalls, etc. just got to be a pain.
That being said, if you’re into the Ops side of things, I hope this post serves you well.
I recently decided to move SproutMark off to a VPS. I’d heard great things about Digital Ocean, so decided to make the switch. Although there are a handful of tutorials out there (this one was VERY helpful) on how to setup the Nginx/Unicorn/Rails stack, none had everything I needed. So here are my learnings and experience on how I got set up on Digital Ocean.
Choose your size. A typical Rails app can run about 150-200mb per process. Multiply that by how many Unicorn processes you want to run to figure out how much RAM you need. For my little app, I’m running 2 unicorns + Sidekiq and am hovering around 800mb so the 1GB plan works fine for me.
Under “Select Image”, choose “Ubuntu 14.04 x64”
Click “Create Droplet”
That’s it? Yes. Well, yeah, so far.
Set Up A User For Deployments
It’s usually not good practice to use your root user to handle deployments, so let’s first start by adding a “deployer” user.
Stop using that root password. Setup and upload an SSH key.
Digital Ocean has a fine document on creating a SSH key and getting it installed. The only part I’d never seen before was ssh-copy-id. It’s quite handy and easy to install with Homebrew.
We all have fond memories of RVM. Well, I have some fond memories, but mostly memories or RVM acting crazy and putting crap all over my system. “Is there a better way?”, you ask. Yes. Yes, there is. Please use Rbenv. Let’s get it installed for your deployer user.
First, some dependencies:
Now, we’ll install rbenv into your home directory and add some commands to your .bashrc for completution and shims.
Now, let’s restart the shell and make sure Rbenv is install:
Time to install Ruby!
This part may take awhile. Go grab an apple.
Let’s make sure all is well…
If it’s not working, you’ll probably see this:
^ That’s not good. Re-visit the instructions above and don’t proceed until you get Ubuntu figuring out where Ruby is.
One last step that always trips people up: install Bundler real quick.
You’ll thank me later…
Use MySQL if you must, but I ain’t helping you there. Let’s set up PostgreSQL.
Don’t try and get fancy with other DB users. Just use the built-in ‘postgres’ user.
Create your database:
Memcache, and Redis
These two are a piece of cake. Thanks, ‘apt-get’
And Redis (for Sidekiq and other fun stuff)
Boot ‘er up and make sure you can get to the Redis console:
If you’re just using Redis for Sidekiq, you’re done. However, Redis is a pretty powerful datastore. For more, check out Redis in Action.
Here’s the part where I started getting scared. I don’t know Nginx well. There. I said it. I’m not ashamed. I got a big head start using Esther Hazzard-Strong’s post, but still had some problems. Here’s the config I ended up with:
You should now be able to view Nginx’s welcome page by visiting your Droplet’s IP in your browser.
You can also check to make sure Nginx is running:
Now we can get Nginx set up to point to our (upcoming) Rails install. Let’s open up the nginx.conf file:
Here are my settings:
So that’s the overall Nginx setup. Now let’s set up the conf file for our Rails site. The cheater way to do this is place a file directly into /etc/nginx/sites-enabled. The better way is to place the file into sites-available and then symlink into sites-enabled.
But I’m a cheater…
Here’s my setup. I’m running SSL, so there are two server blocks. The “listen 80” block takes any non-http request and redirects to the other server block. The second block is for “listen 443” (SSL). If you don’t want/need SSL, you can remove the first server block and swap out 443 to 80 in the second block. You’ll want to remove the ssl_certificate lines, too.
I probably spent more time on that one file above anything. Thank you, internet, for providing tons of random tutorials on setting that up.
Ok, so Nginx is set up. Time to get into the fun stuff.
This was another one that took me awhile, so I’m excited to share this setup with someone. I’m going to assume you know what Unicorn is and why you should use it. Here’s my unicorn.rb Rails initializer (config/unicorn.rb)
If you’ve ever struggled with the Capistrano DSL, then you’ll be quite happy when you see Mina. It’s quite lovely. And VERY fast.
Add it to your Gemfile.
Let’s also add two other gems that will help us manage Unicorn and Sidekiq
Create the necessary “deploy.rb”:
Make sure to add your project’s folder inside ‘/home/deployer’. For instance, ‘/home/deployer/YOUR_APP’.
Let’s tweak that deploy.rb file. Here’s my setup:
I absolutely love how easy it is to read that file!
Ok, let’s run that setup task to create the necessary folders and files on your Droplet. If one doesn’t get created that you need, no worries. Just SSH back in there and create the folder yourself.
Set Up database.yml and secrets.yml
Let’s get back on your Droplet and set up your database.yml and secrets.yml files:
Tweak that file:
…and your secrets.yml…
And finally, deploy!
That’s it! If you have any questions, leave them in the comments. I want to make this document better for the next guy, so let me know if there’s anything I can improve.