Create your own Heroku clone for $5 a month with Dokku

Create your own Heroku clone for $5 a month with Dokku

If you’ve ever worked on or thought about creating your own web app using Ruby on Rails, then you’ve probably heard of Heroku.

A child of the famed Y Combinator accelerator program, Heroku provides services that make it dead simple to get a Rails app up and running within minutes in a professional server environment.

There’s a good reason why it’s so popular – they offer a free tier that just works!

While lots of developers feels comfortable with their own code, the thought of fiddling with a server configuration which serves up their magical creations to the hundreds (thousands? bazillions?) of visitors that discovered their site makes their head spin. Heroku fixes this by removing the Ops out of DevOps.

But, what happens when your site needs secure SSL?
+$20/month.

How about error logging and reporting?
+$15/month.

Backups?
More memory?
Additional worker processes?

Needless to say, your bill can grow very quickly. As a small business, it’s important that I keep my costs down, especially when I’m just trying to spin apps out before I know if they are ever going to go anywhere.

I wondered to myself. How could I get the ease and features offered by Heroku, but in a package that was more friendly towards my budget?

So I did some searching, and found an even better answer that allows me to host my own Heroku clone on my own server for a measly $5 a month using a DigitalOcean droplet, saving me money and the frustration of receiving an overpriced bill for an app that I’m still working on.

That’s more like it.

Now, in this tutorial, I’ll show you how you can set up your own, too.

Requirements:

  • 30 minutes of time
  • A credit card and billing address
  • A sense of courage

Introducing Dokku

Dokku is a Docker powered mini-Heroku in around 200 lines of Bash that lets you set up your own Platform-as-a-Service infrastructure at a fraction of the cost. This makes it possible for you to host your own apps with all of the features offered by an actual provider like Heroku.

Let’s get going on setting this puppy up.


Hosting on Digital Ocean

For the purposes of this tutorial, we are going to set up the Dokku software on a $5 VPS over at Digital Ocean. It’s a great alternative to traditional shared hosting because it is built on super fast solid state drives and it is very friendly on the wallet.

If you’re new to Digital Ocean, you can sign up through this link and receive a free $10 credit, good for two free months of Sendy hosting.

After you’ve created and logged in to your Digital Ocean account, it’s time to start setting up the server.

Create a New Droplet

DigitalOcean calls its virtual private servers droplets; each droplet that you spin up is a new VPS for your personal use. The setup is very easy – let’s create one now.

Start by clicking the green Create Droplet button at the top of the navigation menu.

  • Choose an Image: Click on the One-Click Apps tab, and choose Dokku v0.6.5 on 14.04
  • Choose a Size: $5/month
  • Add block storage: None
  • Choose a Datacenter Region: New York 3
  • Select additional options: None
  • Add your SSH Keys: (Optional) None
  • Finalize and Create: 1 droplet, with a hostname of Dokku

Once you’ve selected the options above, click the big green Create button at the bottom of the page.

After about a minute, you should receive an email that contains information related to the new droplet that you just created, including your server’s IP Address and root password. Keep this email handy – in fact, I’d recommend saving that data somewhere in a safe and secure place for future referencing.


Configuring Dokku

Now that your droplet is up and running, you need to make a few configuration changes to our new Dokku install.

Using your web browser, visit the IP address that you received in the email from DigitalOcean. You should see a page load up that looks similar to this:

Dokku Setup

The important setting here is the Public Key box. If you opted not to add an SSH key during the droplet creation process, you’ll need to copy your SSH public key and paste it here so that Dokku knows to trust your computer every time that you want to connect and deploy to your Dokku installation

If you’re not sure what an SSH key is, I’d recommend following GitHub’s excellent tutorial on creating an SSH key.

Once you have generated your SSH key, make sure to paste it in the Public Key box on your Dokku setup screen.

When you’re ready, click the blue Finish Setup button.

You’ll immediately be forwarded to the Dokku Application Deployment guide, but you can now safely close your browser window, since we’ll be using the CLI to finish setting up and deploying your Rails app.

Getting comfy with your CLI

Note: if you are comfortable accessing servers via shell, you can skip down to the Controlling Dokku from your Computer section below.

Forewarning: remember how I asked you earlier if you were feeling courageous?

This is going to be the part that scares most people away. But you are ready. You can do this. We’re in this together, and with the power of two we can do anything! Besides, all you really need is to be good at following linear instructions.

We’re going to use Terminal or Command Prompt to log in to your Digital Ocean server via Secure Shell.

These programs offer a command-line interface (CLI), which is a means of interacting with your droplet where you’ll issue commands to the droplet in the form of successive lines of text. That’s right baby, no menus or shiny icons here. You’re a real hacker now.

It’s time. Let’s open your CLI and get rockin.

  • OSX: Terminal is located in the Applications/Utilities folder. Alternatively, you can use Spotlight to search for and open it.
  • Windows: Command Prompt is found in different locations based on the Windows version you have. Here are instructions for Windows 8, Windows 7, Windows Vista, and Windows XP

You’ll know you’re ready to go when that big, scary, empty black box pops up. For the remainder of this tutorial, we’ll call this box the CLI.


Controlling Dokku from your Computer

A quick note: the sections below using a convention of highlighting text to show what you must enter into your CLI. If you see text that looks like this, it means that you should literally type like this into your CLI and press enter.

One of the nice things about Heroku is its integration with the Heroku Toolbelt – a set of CLI tools which allow you to issue commands to manage your Heroku install via your CLI without having to manually log in to the server every time.

To replicate this behavior with Dokku, you’ll want to install the dokku-cli gem on to your computer, which will provide your computer with some Dokku controls and superpowers that it doesn’t ship with by default.

Note: if you’re using Windows, you may need to first install Ruby to get this to work. Here’s a detailed description on the steps you should take to get Ruby set up

Open up your CLI and enter the following command to install it:

gem install dokku-cli

Your CLI will show you some cool information to prove to you that it is up for the challenge of installing our new gem. Once it finishes yelling at you, you can verify that the dokku-cli app installed correctly by typing the following command into your CLI:

dokku

Do you see a bunch of dokku-cli commands listed (such as dokku certs:add CRT KEY and dokku events) and no errors? SWEET!!! Let’s move on.


Getting Railsy wit it

Okay, so we have Dokku set up, just waiting in the bleachers to catch a home run ball (or, your Rails app.) We’re just about ready to send your Rails app up to the Dokku server.

What’s that? You don’t have a Rails app ready to go? Well, you can use a sample one for now, I guess. Heroku actually provides one on their GitHub account for demonstration purposes. You can download it to your local system with the following command:

cd ~ && git clone git@github.com:heroku/ruby-rails-sample.git

Note: not sure what Git is, or, don’t have it installed? Check out this article from GitHub which provides and overview of Git and a walkthrough on getting it installed on your computer.

This will create a new folder called ruby-rails-sample in your user’s home directory, which contains a demo Rails app that you can use for the remainder of this tutorial.

Initializing your Dokku app

Now it’s time to introduce our new friend Dokku to our old friend Rails app. Let’s use the CLI to connect to our droplet with the following command, replacing your.droplet.ip.address with your actual DigitalOcean droplet IP address:

ssh root@your.droplet.ip.address

This will start a new SSH session on your Droplet, which provides you with full control over the Dokku install. Once you’re logged in, you’re essentially using the Droplet’s CLI at this point, so let’s tell the Droplet’s Dokku install to create a new app called ruby-rails-sample (or, whatever else you want to call your app):

dokku apps:create ruby-rails-sample

You did it! …didn’t you?

Installing Postgres

One of the main benefits of using Rails to create your web apps is ActiveRecord, a super easy-to-use abstraction layer which allows you to write code that talks to your database and fetches or writes the data that you’re looking for.

Obviously, in order to use ActiveRecord to access our database, we need to first create a database. I know, I’m a genius.

In order to create our database, we’ll install a plugin for Dokku which allows us to use Postgres as the database software. Any time we install a plugin in Dokku, we need root/admin privileges, so we’ll prefix the following command with a call to sudo:

sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git

Note: any command that begins with sudo may ask you to enter your root password after issuing the command. This password can be found in the email that you received from Digital Ocean.

You might not see the traditional ****** or ••••••• characters when you type or paste your password into your CLI, but it is still being pasted successfully.

Dokku will do its thing and spew out a lot of information while it downloads and installs the Postgres plugin. Once it’s done, let’s create a new Postgres service with the name rails-database (or, you can also call this whatever you want)

dokku postgres:create rails-database

Finally, we’ll link our new Postgres service that we just created to our ruby-rails-sample app that we created in the previous step. This will also automatically set the POSTGRES_URL environment variable on your dokku host, so that dokku knows how to connect to the database when your Rails app tells it to.

dokku postgres:link rails-database ruby-rails-sample

BAM! Our Postgres database is ready to rock and base our data.

Note: If you’re using a custom Rails app instead of the example app provided by Heroku, you’ll need to make sure that your database configuration is set to use Postgres in production instead of the default SQLite. Heroku has an excellent tutorial article which walks you through making this change.

Add a swap file

How are you feeling? Ready to take over the world with your CLI skills? Maybe hack a matrix or two? Good. Let’s move on.

Rails apps require a decent amount of memory to run efficiently, but our $5 DigitalOcean droplet only comes with 512MB – not nearly enough to support our app’s deployment, processing, and traffic.

To get around this, we can create a file on the server’s hard drive called a swap file which will write some of the contents of the server’s memory to a file instead of storing it in RAM. Let’s not get too technical; here’s how to create your swap file:

First, allocate a new 2GB file with the following command:

sudo fallocate -l 2G /swapfile

You won’t see any output after this command; that’s good. It means that it worked. Now, let’s modify the permissions of the new file so that it can be used by your server with this command:

sudo chmod 600 /swapfile

Again, no output this time. Excellent. Next, let’s prepare the swap file for… swapping. Enter this:

sudo mkswap /swapfile

You should see some output that resembles the following:

Now, we need to enable swap on the swap file. You read that right. Enter this command:

sudo swapon /swapfile

Lastly, let’s make sure the swap file is always used, even after we restart the server. We’re going to do this with a program called nano (cute, right?), which is a virtual text editor that will take over your CLI screen and transform it to a working application.

Let’s open the configuration file in nano by issuing this command.

sudo nano /etc/fstab

Although this window looks a little different from a traditional text editor like Microsoft Word, it actually behaves very similarly. You can use the arrow keys on your keyboard to move the cursor around in the text file and make changes.

Finally, use your down arrow key to move the cursor to the bottom of the screen and add the following line:

/swapfile none swap sw 0 0

Phew, we’re done here! Press CTRL+X to save the configuration file, press Y to confirm your changes, and then Return to return to your Digital Ocean droplet.

At this point, we’re all done with our droplet, so it’s time to disconnect with this command:

exit


Setting up Git and Dokku

We’re in the home stretch. Can you taste it? Victory is upon us.

At this point, dokku-cli doesn’t know anything about the Droplet that you created on DigitalOcean. Let’s introduce the two to each other so they can form a lifelong relationship and maybe go on a dinner date.

First, make sure you are inside of the root directory of your app by changing to it with the following command, replacing ruby-rails-sample with the name of your actual Rails app name.

cd ~/ruby-rails-sample

dokku-cli will look at the initialized Git repository that exists inside of your Rails root directory and reference the remote named dokku for the correct connection information to your droplet.

Since your repository doesn’t currently have a dokku remote, create it with the following command, replacing the IP address with your DigitalOcean droplet IP that you received after creating your droplet.

git remote add dokku dokku@your.droplet.ip.address:ruby-rails-sample

Upload your Rails app to your Droplet

We’re at the last command, but it’s arguably the most important. Your Rails app needs to be uploaded to your droplet so that you can access it from anywhere in the world!

Deploying your app is as simple as pushing it up to GitHub. Dokku has some receive hooks set up that are listening for any connections through Git and will know how to handle those requests, so all we have to do is push our master branch to the dokku remote. Easy enough with this command:

git push dokku master

You should start to see some output that looks similar to this:

Wait… that’s it? Pretty amazing, huh?

Try holding the command key and double-clicking the droplet url that Dokku reports back in the CLI after a successful deployment. You should see your app running – congrats! You’ve successfully deployed to a Dokku server in 30 minutes or less!


Touchdown!

YES! We are all done here. I knew you could do it, champ. Close down that CLI and revel in your success.

Questions or comments? Use the comments below or hit me up on Twitter, @davekiss


Making it even better

What’s this? You’re still reading, even after you’ve scored the game winning goalsportshomerun? Well, together, we can make your app and deployment process even better with a few more tweaks. Read on, if you so choose.

Configuring Pre-Flight Checks

Any time you deploy your Rails application to your DigitalOcean droplet, Dokku will restart your server to ensure that what is being delivered to your users is all up to date with the latest version.

However, this can become problematic; while Dokku checks to make sure your application container is up and running correctly, by default, it doesn’t actually check to see if your Rails server has been launched safely. What this means is that while Dokku may report in as successfully restarting your container, your users may see temporary errors indicating otherwise while your Rails app continues to boot.

Let’s resolve this by creating a file named CHECKS in our Rails root and add some instructions for Dokku to follow to verify the Rails server has finished loading after deployment:

Now, we need to create a custom route in our config/routes.rb file that handles requests to the /check.txt endpoint. Add the following route, which will return the it_works text that our CHECKS file is expecting:

get '/check.txt', to: proc {[200, {}, ['it_works']]}

Let’s break this all down:

  • We set the WAIT value to 10 to wait 10 seconds before checking since the app takes a little while to boot.

  • If after 6 ATTEMPTS the Dokku check continues to fail, Dokku will revert back to the previous app version and consider the deployment as failed.

  • Dokku will hit the /check.txt route, and if it received it_works as the response, the deploy will be considered successful.

Add and commit your changes to Git, then push it up to Dokku. You’ll see some output similar to the following:

Nice work! Your app now implements zero-downtime deployments.

Automatic Database Migrations

By default, any changes that you make to your Rails app database require that you manually run rake db:migrate to process your migration files and apply your changes to your database.

We can ensure that Dokku does this automatically for you when you deploy by creating an app.json file in your Rails app root, which Dokku will look to for instructions on what it should do when you deploy your App.

Let’s create a file named app.json in the root of your Rails app and add the following instructions:

This is telling dokku that after your deploy is successful, run bundle exec rake db:migrate automatically to handle any changes you made to your database between app versions. Noice!

Setting up your domain name

Now that you have your droplet and app ready to go, chances are likely that you want to hook up a real domain name to visit instead of just an IP address.

To do this, you’ll need to make some DNS changes on your domain registrar’s site and on DigitalOcean. This might be GoDaddy, HostGator, Hover, NameCheap, BlueHost, or even somewhere else.

Check out the following article for detailed instructions on how to set up your domain name to point to your new Rails app running on Dokku

1 comment

Leave a comment
  1. Thomas

    September 7, 2017 at 5:54 pm

    Great Article. Well written. Easy to follow for well advised as for beginners. Could go even further with some more examples… nodejs, mongo eventually and some more things we can do with Dokku configuration or Docker. But Enough for a good start! Thanks a ton. Rarely seen an article so well written. Always appreciable.

Leave a Comment