Moving from Heroku to Vultr

This guide will show you how you can easily move away from Heroku and on to Vultr. Vultr has 15 datacenters around the globe bringing their cloud close to major city centers around the world. The Vultr 100% Intel CPU and 100% SSD platform allows you to easily implement a cloud infrastructure with the click of a button. Vultr has made it our priority to offer a standardized highly reliable high performance cloud compute environment.

If you're interested in learning all the complexities of provisioning, configuring, and managing a production infrastructure this guide probably isn't for you. The idea here is to make migrating from Heroku to Vultr as simple and painless as possible. Since you're already using Heroku, I'm betting you're not really interested in all the nitty gritty details. You just want a way to get all of the great things Heroku has to offer, without Heroku. Nanobox is a powerful Heroku alternative that gives you the same great workflow you're used to with Heroku with all the flexibility and control of Vultr.

Getting Started

If you haven't already, you'll need to create a free Nanobox account and download Nanobox Desktop.

Configure Your App

Every web application has an underlying infrastructure. This infrastructure is typically made up of web servers, databases, and workers. The purpose of Nanobox is to provision, configure, and deploy your application's infrastructure so you don't have to.

Similar to Heroku's Procfile, Nanobox reads a config file called a boxfile.yml which describes your application's infrastructure. This file lives at the root of your project and tells Nanobox everything your application needs so Nanobox can build and configure your infrastructure for you.

Procfile to boxfile.yml Example

Translating a Procfile to a boxfile.yml is very simple. A typical Procfile might look like this:

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq

The matching boxfile.yml would look like this:

run.config:
  engine: ruby

web.site:
  start: bundle exec puma -C config/puma.rb

worker.sidekiq:
  start: bundle exec sidekiq

data.db:
  image: nanobox/postgresql:9.6

Understanding the boxfile.yml

There are a few obvious differences between the Procfile and the boxfile.yml. The following section explains each node individually to give you a better understanding of what everything means. If you aren't interested in the details, feel free to skip ahead.

The engine

An engine is comparable to a Heroku buildpack. It's a set of scripts that build and configure your app's environment and runtime. These scripts retrieve dependencies, compile your application code, and more.

Every boxfile.yml must have an engine specified:

run.config:
  engine: ruby

Here, the ruby engine tells Nanobox to build an environment that includes Ruby, Gem, and Bundler. The ruby engine also tells Nanobox to run bundle install for you during the build process.

Nanobox has engines available for many different languages:

nanobox-guides

Components

A Nanobox component is essentially the same thing as a Heroku process type. Nanobox has three component types available:

  • web: Receives HTTP, TCP, and UDP requests from your app’s router.
  • worker: Background process inaccessible from your app’s router.
  • data: Components designed for handling data of any kind – databases, caches, job queues, etc.
Web & Worker Components

Web and worker components only require a start command, although other config options are available. The start command would be the same command you pass with your process in a Procfile:

# Procfile
web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq
# boxfile.yml
web.site:
  start: bundle exec puma -C config/puma.rb

worker.sidekiq:
  start: bundle exec sidekiq

Note: Each component in your boxfile.yml has a component ID that follows the pattern: type.name. For example, web.site or worker.sidekiq. The types are one of the three from above, but the name is completely arbitrary. Any additional component settings are nested under each ID.

Data Components

nanobox-data-components

Until recently, Heroku didn’t offer any internally managed database options, but instead integrated with external service providers through "Add-Ons". With Nanobox, databases are internally-managed as a part of your app’s private network and come with monitoring and scaling options.

Note: Nanobox's still allows for you to use externally hosted/managed data services such as S3 or RDS if you prefer.

If you choose to manage your data components with Nanobox, simply include them in your boxfile.yml. The only required option for a data component is the image, referencing the Docker image used to provision the component:

data.postgres:
  image: nanobox/postgresql:9.6

Note: You're free to use your own Docker images, however Nanobox provides official images that include functionality specific to Nanobox (recommended).

Additional Configuration

If you're already running on Heroku, there aren't many changes you'll need to make to your app, but there are some important things to note:

Listen on 0.0.0.0:8080

With Nanobox, in order for your app to receive requests from the public network, it must listen on 0.0.0.0:8080. This is generally configured in the app itself, as part of the web server config, when the app is started, or with Nginx.

If you want to use a custom port, you'll need to setup a proxy that forwards from 8080 down to your custom port. We actually recommend this method. However you still need to listen on 0.0.0.0 rather than localhost.

For an example of an Nginx proxy with Rails, check out the Configure Rails for Production guide. Examples for other frameworks are also provided in the Nanobox guides.

Database Management

Nanobox's flexibility allows you to easily connect to externally hosted/managed data services such as S3 or RDS. Or you can choose to use officially supported data components and have them managed through your Nanobox platform.

Externally Managed Database

If you choose to use an externally managed databases or services, you don't need to update your connection credentials unless those credentials are changing. Chances are that you're populating those with environment variables. If that's the case, just be sure to add those variables to your environments.

Nanobox Data Component

When using officially supported data services, Nanobox will auto-generate environment variables for each required credential, using the component's ID.

For example, with the following data components in a boxfile.yml:

data.postgres
  image: nanobox/postgresql:9.5

data.redis
  image: nanobox/redis:3.0

...the following environment variables will be generated:

# Postgres Connection Variables
DATA_POSTGRES_HOST
DATA_POSTGRES_USER
DATA_POSTGRES_PASS

# Redis Connection Variable
DATA_REDIS_HOST

Note: For data services that require a database name, we create a default gonano database, but you can also create your own. Also, the port will always be the service's default port.

Update Database Connections

Using environment variables for service connections ensures your app's portable across environments. You'll need to update your applications database config to connect using the Nanobox environment variables.

In Rails, for example, you might update your config/database.yml to something similar to this:

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  host: <%= ENV['DATA_DB_HOST'] %>
  username: <%= ENV['DATA_DB_USER'] %>
  password: <%= ENV['DATA_DB_PASS'] %>

Persistent Storage

Heroku's recommended method for storing files that need to persist between deploys is using Amazon S3. You can do the same with Nanobox, but you also have another option with Nanobox storage components.

If you're going to stick with S3, just be sure to add the required auth credentials, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and S3_BUCKET_NAME as environment variables.

Setup Your Vultr Account

If you haven't already, create a Vultr account. In your Vultr admin, select "Account" in the left-nav and open the "API" section. By default, Vultr API access is disabled. When you enable it, they will provide you with an API key.

Vultr Access Token

Vultr lets you whitelist subnets that can access the Vultr API using the generated key. To use the Nanobox Vultr integration, go ahead and click "Allow All IPv4".

Vultr IP Whitelist

Note: If you're uncomfortable whitelisting all IPv4 addresses, you can whitelist 138.197.215.155/32. This is the subnet on which the Nanobox Vultr adapter is hosted, but this subnet is subject to change. If/when it changes, you will need to manually update your Vultr account with the new subnet.

Add a New Provider to Your Nanobox Account

Add New Provider Account

Select Vultr and click "Proceed."

Select Vultr

Nanobox needs your Vultr access token to authenticate with your Vultr account. Paste in your token and click "Verify & Proceed."

Enter your Vultr access token

Name your provider and choose a default region. The name is arbitrary and only meant to help you identify it in your list of provider accounts.

Name your provider and select a default region

Launch a New App

Go to the home page of your Nanobox dashboard and click the "Launch New App" button. Select your Vultr provider from the dropdown and choose the region in which you'd like to deploy your app.

Select your Vultr provider

Confirm and click "Let's Go!" Nanobox will order a VC2 instance under your Vultr account. When the instance is up, Nanobox will provision platform components necessary for your app to run:

  • Load-Balancer: The public endpoint for your application. Routes and load-balances requests to web nodes.
  • Monitor: Monitors the health of your server(s) and application components.
  • Logger: Streams and stores your app's aggregated log stream.
  • Message Bus: Sends app information to the Nanobox dashboard.
  • Warehouse: Storage used for deploy packages, backups, etc.

Once all the platform components are provisioned and running, you're ready to deploy your app.

Stage Your App Locally

Nanobox provides "dry-run" functionality that simulates a full production deploy on your local machine. This step is optional, but recommended. If the app deploys successfully in a dry-run environment, it will work when deployed to your live environment.

nanobox deploy dry-run

More information about dry-run environments is available in the Dry-Run documentation.

Deploy

Add Your New App as a Remote

From the root of your project directory, add your newly created app as a remote.

nanobox remote add app-name

This connects your local codebase to your live app. More information about the remote command is available in the Nanobox Documentation.

Deploy to Your Live App

With your app added as a remote, you're ready to deploy.

nanobox deploy

Nanobox will compile and package your application code, send it up to your live app, provision all your app's components inside your live VC2 instance, network everything together, and BOOM! Your app will be live on Vultr.

Manage & Scale

Once your app is deployed, Nanobox makes it easy to manage and scale your production infrastructure. In your Nanobox dashboard you'll find health metrics for all your app's instances/containers. Your application logs are streamed in your dashboard and can be streamed using the Nanobox CLI.

Although every app starts out on a single VC2 instance with containerized components, you can break components out into individual servers and/or scalable clusters through the Nanobox dashboard. Nanobox handles the deep DevOps stuff so you don't have to. Enjoy!

Moving can be a daunting task. Hopefully this guide has given you a good place to start. If you have any questions, please reach out!

Get in Touch

Posted in Heroku, Vultr, Deployment, Migrating