Migrating Your Production Application and Database from Heroku to Hatchbox

Migrating production systems requires careful planning. This guide outlines the steps to move your Heroku-hosted application and PostgreSQL database to Hatchbox, ensuring a smooth transition.


1. Connect Your Git Repository to Hatchbox

click “Repositories” in the Hatchbox dashboard and select “Add Repository” to connect your GitHub repository.

hatchbox https://www.hatchbox.io/announcements/38


2. Create Databases on Hatchbox

  • Access Hatchbox Dashboard: Log into Hatchbox and locate the database management section.
  • Create a New Database: Use the provided interface create your REDIS/PostgreSQL databases.

3. Configure Production DATABASE_URL

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %>
development:
  <<: *default
  database: yourapp_development
test:
  <<: *default
  database: yourapp_test
production:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>

4. Copy Environment Variables

  • Export Heroku Config:
heroku config --json > herokuenv.json

Open the file and remove/update any unnecessary variables:

  • convert DATABASE_URL to HEROKU_URL
  • remove starting with HEROKU_

  • Automate Upload via API (Optional):

    Alternatively, you can manually prepare the environment variables in the required format and upload them using the Hatchbox API.

    1. Manually Prepare the JSON Payload:

      • Open the herokuenv.json file you exported.
      • Rename the DATABASE_URL key to HEROKU_DATABASE_URL.
      • Remove any other keys starting with HEROKU_ that you don’t need on Hatchbox.
      • Create a new file named hatchbox_env.json.
      • Format the contents of this new file exactly as the Hatchbox API expects. It must be a single JSON object with one key, env_vars, whose value is an array of objects, each having name and value keys.

      Example hatchbox_env.json format:

      {
        "env_vars": [
          {
            "name": "HEROKU_DATABASE_URL",
            "value": "postgres://user:pass@host:port/dbname"
          },
          { "name": "LANG", "value": "en_US.UTF-8" },
          { "name": "PGBOSS_QUEUE", "value": "update-database" },
          { "name": "RACK_ENV", "value": "production" },
          { "name": "RAILS_ENV", "value": "production" },
          { "name": "RAILS_LOG_TO_STDOUT", "value": "enabled" },
          { "name": "RAILS_MASTER_KEY", "value": "your_master_key" },
          { "name": "RAILS_SERVE_STATIC_FILES", "value": "enabled" }
          // ... add other necessary variables here
        ]
      }
      
    2. Upload the Prepared File: Run the following script in your terminal. Ensure hatchbox_env.json is in the same directory. Remember to replace YOUR_ACCOUNT_ID, YOUR_APP_ID, and YOUR_HATCHBOX_TOKEN with your actual values.

      # Read the prepared JSON payload from the file
      payload=$(cat hatchbox_env.json)
      
      # Check if the file was read successfully
      if [ $? -ne 0 ]; then
        echo "Error reading hatchbox_env.json. Make sure the file exists and is readable."
        exit 1
      fi
      
      # Upload to Hatchbox
      curl https://app.hatchbox.io/api/v1/accounts/YOUR_ACCOUNT_ID/apps/YOUR_APP_ID/env_vars \
        -X PUT \
        -d "$payload" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer YOUR_HATCHBOX_TOKEN"
      
      echo "\nEnvironment variables upload attempted using hatchbox_env.json. Check Hatchbox dashboard to confirm."
      

    This approach requires you to manually format the JSON correctly, but avoids the need for additional tools like jq in the script.

  • Manual Update via Hatchbox UI:

    If you prefer not to use the API, log into Hatchbox, navigate to your application’s “Environment Variables” section, and manually copy/paste the necessary variables from your edited herokuenv.json file. Remember to rename DATABASE_URL to HEROKU_DATABASE_URL and exclude other HEROKU_* variables.

  • Secure Sensitive Data: Double-check sensitive items (e.g., API keys, secrets) are transferred securely, whether using the API or the UI.

4. Copy PostgreSQL Data

  • Backup Data from Heroku:

    heroku pg:backups:capture --app YOUR_HEROKU_APP
    heroku pg:backups:download --app YOUR_HEROKU_APP
    
  • Restore Data on Hatchbox:

    Use pgsync with the database credentials provided by Hatchbox.

https://blair.biz/heroku-pg-hatchbox/

  • Verify Data Integrity: Check logs and confirm that your database schema and data have been restored correctly.

5. Migrate Scheduled Tasks (Cron Jobs)

  • Review Existing Cron Jobs:

    • List any scheduled tasks or jobs on Heroku (using Heroku Scheduler or your custom setup).
  • Set Up Cron on Hatchbox:

    • On Hatchbox, set up a cron daemon or use the hosting’s scheduler service if available.
    • Transfer your job definitions. For example, add your cron entries to your server’s crontab:

      crontab -e
      # Example entry:
      0 * * * * /bin/bash -l -c 'cd /path/to/app && bundle exec rake some:task'
      
  • Test Scheduled Tasks: Confirm that cron jobs execute as planned in the new environment.


6. Additional Considerations

  • DNS & Domain Settings:

    • Update DNS records to point to the new Hatchbox application servers.
    • Verify SSL/TLS certificates and renew if necessary.
  • Configuration Files:

    • Review application configuration files (e.g., database.yml, secrets.yml) to ensure they use Hatchbox credentials.
  • Asset Precompilation & Caching:

    • Rebuild assets if required and test performance settings for the new host.
  • Testing in a Staging Environment:

    • Before switching production, deploy to a staging area on Hatchbox.
    • Run automated tests and manual QA to ensure everything functions as expected.
  • Plan for Downtime:

    • Schedule the migration during a low-traffic period.
    • Notify your users about potential downtime or maintenance windows.

Conclusion

Migrating from Heroku to Hatchbox involves syncing your code, replicating your database, transferring environment configurations, and setting up scheduled tasks. Follow these steps carefully, and always perform thorough testing before going live. This methodical approach will help ensure a seamless transition for your production application.