Moving from Heroku to Packet

This guide will show you how you can easily move away from Heroku and on to Packet. Packet offers the Promise of the cloud, delivered on bare metal. Built for developers, it provides improve performance and minimize cost with single tenant, dedicated servers paid for by the hour.

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 Packet 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 Packet.

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:

  engine: ruby
  start: bundle exec puma -C config/puma.rb

  start: bundle exec sidekiq

  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:

  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:



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
  start: bundle exec puma -C config/puma.rb

  start: bundle exec sidekiq

Note: Each component in your boxfile.yml has a component ID that follows the pattern: For example, 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


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:

  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

With Nanobox, in order for your app to receive requests from the public network, it must listen on 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 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:

  image: nanobox/postgresql:9.5

  image: nanobox/redis:3.0

...the following environment variables will be generated:

# Postgres Connection Variables

# Redis Connection Variable

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 Packet Account

If you haven't already, create a Packet account.

Add a New API Key

In your Packet portal, click on "API Keys" in the left nav and add a new API key.

Add an API Key

Give your key a description, Read/write privileges, and click "Generate".

API Key Details

Copy your API Key's Token. You'll need this later.

API Key Token

Create a New Project

"Projects" are Packet's way of grouping ordered servers under a single payment method. Go to the "Manage" tab in your left nav and create a new project.

Create a New Project

Give it a name and assign it a payment method, then click "Create Project".

Project Name & Payment Method

Click on the "Settings" tab inside your new Project, and copy your Project ID. You will need it.

Create a New Provider Account

In your Nanobox dashboard, go to the Hosting Accounts section of your account admin and click "Add Account", select Packet, and click "Proceed".

Add a New Packet Provider

Enter the required credentials.

Enter Packet Auth Credentials

Click "Verify & Proceed". Name your provider, select your default region, then click "Finalize/Create".

Name Your Provider & 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 Packet provider from the dropdown and choose the region in which you'd like to deploy your app.

Select your Packet provider

Confirm and click "Let's Go!" Nanobox will order an server on Packet under your account. When the server 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.


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 server, network everything together, and boom! Your app will be live.

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 servers/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 server 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, Packet, Deployment, Migrating