Migrating Apps from Heroku to Nanobox

Heroku hosts millions of apps – everything from hobby apps and prototypes to highly available, multi-node production apps – all of which are a good fit for Nanobox. There are a lot of similarities between Heroku and Nanobox and migrating is fairly simple.

Migrating from Heroku to Nanobox

Procfile to boxfile.yml

Heroku uses the Procfile to define the processes to include with your app and how to run them. Nanobox uses the boxfile.yml to define your app's runtime, configuration, and supporting services. Just as with the Procfile for Heroku, your Nanobox boxfile.yml needs to be included in the root of your project.

You can translate your Procfile to a boxfile.yml in just a few minutes, but if you have questions, we’re on hand to help in the Nanobox Slack Channel. Here are some things to know:

Define Your Engine

Engines are simple sets of scripts that build and configure your apps runtime. An engine is required in every boxfile.yml. The ruby engine, for example, provides a Ruby environment and will install all your gems during the build process.

run.config:  
  engine: ruby

There are many languages and engines available, each covered in the Nanobox Guides:

nanobox-guides

Specify Your Components

A Nanobox “component” is essentially the same thing as an Heroku “process type”. There are three types available with Nanobox:

  • 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

Webs and workers only require a start command, although other config options are available. The start command should be the same command you passed with your process in your Procfile.

Each component in your boxfile.yml needs a component ID that follows the pattern: type.arbitrary-name. For example, web.site or worker.sidekiq. Component settings are nested under each ID.

Procfile to boxfile.yml Example
# 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: If using absolute paths, your app’s root is the same on Nanobox as it is on Heroku – /app.

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. However you’re welcome to still use externally hosted/managed data services.

If you’d like to launch and scale your data components with Nanobox, 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. Nanobox provides official images that include functionality specific to Nanobox.

data.postgres:  
  image: nanobox/postgresql:9.4

Configure Your App

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

In order for your app to receive requests from the public network with Nanobox, it must listen on 0.0.0.0:8080.

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 a Nginx proxy with Rails, check out the Configure Rails for Production guide. Examples for other frameworks are also provided in the Nanobox guides.

Update Connection Credentials

If you're sticking with 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.

Auto-Generated Environment Variables

If you're rolling with official Nanobox data services defined in your boxfile.yml, Nanobox will auto-generate environment variables for each required credential using the component's ID.

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

data.db  
  image: nanobox/postgresql:9.5

data.cthulu  
  image: nanobox/redis:3.0

...the following environment variables will be generated:

# Postgres Connection Variables
DATA_DB_HOST  
DATA_DB_USER  
DATA_DB_PASS

# Redis Connection Variable
DATA_CTHULU_HOST  

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

Use Environment Variables in Your Connection

Coming from Heroku, you already know this, but using environment variables for service connections will keep your app portable across environments.

Example database.yml
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. More info below.

Run Your App Locally

If you haven't already, create a free Nanobox account and download Nanobox. Once Nanobox is installed, cd into your project directory and run:

nanobox run  

This will use settings in your boxfile.yml to create a virtual local development environment with everything you need to run your app. Once the environment is built, it'll drop you into a console where you can run the command(s) necessary to start your app.

# if your app is a rails app
bundle exec rails s  

This is where you can make sure everything is working before deploying to live servers.

You may need to seed or migrate data in order for you app to function properly. Seeding can be done from the command line. Information about migrating data is available below.

Stage Your App Locally

Nanobox gives you the ability to stage you application locally before deploying it to production. While this step is optional, it's highly recommended.

To stage your app run:

nanobox deploy dry-run  

Once your application works in this dry-run environment it's guaranteed to work in production.

Note: To fully simulate a production environment you can set RAILS_ENV to production with nanobox evar add dry-run RAILS_ENV=production before you deploy dry-run.

If you're having problems getting your app running in dry-run don't hesitate to contact us. We're here to help!

Deploy Your App to a Live Server

Time to go live! Nanobox lets you deploy to your cloud provider of choice. We have official integrations with AWS, Digital Ocean, and Linode available in your dashboard, but you can also build a custom integration using our open provider spec. Go ahead and link your Nanobox account to your provider.

Launch a New App

In your dashboard, launch a new app.

Launch a New App

This will provision a server on your provider and install all the Nanobox platform components required to run your app.

Add Your App as a Remote

With your new app created, run the following from the root of your project to add it as a deployable remote:

nanobox remote add [app-name]  

Be sure to replace [app-name] with your actual app name.

Deploy!

Now that your new app has been added as a remote, run the following to deploy to it:

nanobox deploy  

Nanobox will build your runtime, compile your app, package it up into a deployable package, push it up to your live server, and provision your entire app.

Helpful Information

The following information is referenced above and will likely help as you migrate.

Adding Custom Environment Variables

Nanobox provides multiple environments for your app and environment variables can be added to each. To add environment variables to your local app, use the following pattern:

nanobox evar add local KEY1=value1,KEY2=value2  

To add environment variables to your live app, use the following pattern:

nanobox evar add KEY1=value1,KEY2=value2  

More information is available in the Environment Variable documentation.

Migrating Data

Data can be migrated into your locally running app or into your live app. The process depends on the type of data and service you're using. But essentially, Nanobox exposes connections to data components running locally and in production. You can then connect, and use your client of choice to migrate data. Specific instructions for managing data components are available in the guides.

Need Help Getting Started?

Everyone hates getting stuck with no one to talk to. If you're running into any issues or have any questions as you're getting started let us help!

Scott Anderson

Designer, code-dabbler, writer, foodie, husband, and father. Core Team Member at Nanobox.

Subscribe to Nanobox

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!