Why and How to Migrate From Heroku to AWS
The Difference Between Heroku and AWS
Heroku and AWS are two cloud computing platforms, both with their own pros and cons. Heroku tends to be simpler and easier to get started with than AWS, but for larger projects it can quickly become costly. Because of this, it's common to eventually migrate a growing infrastructure to AWS. In this article, we'll take a look at some of the reasons why this might be advantageous as well as the basic steps of migration.
Heroku is a platform as a service (PaaS) solution based on AWS infrastructure. AWS, meanwhile, is the world's largest cloud platform. As such, it covers a lot more ground: infrastructure as a service (IaaS) and software as a service (SaaS) as well as PaaS. They're both cloud computing services and offer the same basic benefits: access to resources from anywhere in the world with a pay-as-you-go model.
The key difference is the scope of the service. While Heroku comes with a ready-made environment allowing developers to deploy directly from code without needing to work with the infrastructure, AWS covers it all from start to finish with a wide array of products and services. Depending on your project and needs, both come with advantages and disadvantages.
Should I Deploy with Heroku or AWS?
When choosing which service to use, the key factor will likely be PaaS vs IaaS. In a nutshell, Heroku offers a platform with a fixed infrastructure, meaning it's simple to use and quick to deploy, but there's less control over your infrastructure. AWS, meanwhile, offers vaster services, but you need a more solid grasp of the basics of infrastructure. Let's look at the top considerations in a little more detail:
- DevOps: Because AWS works with the entirety of the infrastructure, you'll need an understanding of DevOps to set up servers. Heroku doesn't ask you to set up your own configurations. It uses Git to deploy, meaning you don't have to be versed in DevOps or AWS.
- Flexibility: AWS is a massive platform, and it offers a lot more room for scaling and infrastructure changes. However, that's not the only flexibility it offers. It's also available in more regions and supports more operating systems and architectures.
- Pricing: Heroku's pricing plans range from $0.01 per hour of computing for small (hobby) projects to $0.34–$0.69 per hour for high-traffic projects. Meanwhile, AWS has more robust services that move around $0.13 per hour. For larger projects, Heroku can be significantly more expensive.
- Commonality: AWS has a lot of services. Many teams will already be using various AWS services for other parts of their project. In this case, it's easier to keep everything in one place, and AWS makes that easy.
If you're just getting started with a small team without a lot of time or expertise for infrastructure, Heroku offers quick deployment with all the benefits of cloud computing. However, as you scale, both in terms of your team and your project, it's likely that it'll eventually grow costly and overly rigid and simplistic for your needs.
How to Migrate
You might start off with Heroku and eventually want to migrate to AWS. If you're reading this article, that's probably already the case. Let's look at the basics of one way to do so using Docker.
Create Your AWS App
You'll first want to create an AWS app to migrate to. If you're looking to start with PaaS support that's similar to what Heroku offers, there are a few AWS services you can use. Elastic Beanstalk is the closest equivalent. Once you choose your platform, it automatically creates an EC2 instance without needing much infrastructure management. AWS Lightsail also handles many of these steps via pre-configured servers that act like virtual private servers.
However, you can also create your own EC2 instance. You can do this by heading to the EC2 dashboard, where you'll find the Launch Instance section.
Launching an EC2 instance on AWS
This will take you to the launch page. We won't go through the details here. If you don't have specific infrastructure needs, the default settings will do. Amazon's default AMI is generally the most cost-effective option, and other aspects of the setup will be app specific. You'll want to create a key pair in the key pair section and save it to your machine.
Creating key pairs in AWS
Create Docker Files and Docker Compose
You'll then want to create Docker files for your application. Heroku keeps your code on GitHub, meaning the majority of the migration will deal with the environment and configuration. Docker ensures that you're working in a consistent environment when migrating, and it makes setup and deployment on AWS significantly easier. This step can seem pretty daunting and vary according to the stack you're using, but Docker's documentation has an array of samples you can use as guidance.
As a side note, if you're not running Linux, Docker runs on a virtual machine. This can make it quite slow, but you can check out this article for tips on how to speed things up.
For the most part, in your Docker folders you'll likely want the following:
- an app Docker file defining the application
- an environment file with the environment variables as key-value pairs
- a web Docker file defining your server
- a configuration file for your server
The environment file will be a copy of your Heroku configuration variables, which you can find in the Settings tab of your Heroku dashboard:
Getting the environment variables from Heroku
You'll then want to create a Docker Compose file, docker-compose.yml, to manage your Docker files. This will point to your database, your application and server containers, and your environment variables. This will again depend on your specific stack, but the basic structure will be similar. You'll need a 'db', 'app' and 'web' service. Your 'web' service will depend on your 'app' service, which will in turn depend on your 'db' service. The app and web services need to be built from Docker files, while the 'db' only needs to specify the database.
> docker-compose build
For more details on how to set up this file, make sure to read the Docker documentation.
You can then use Docker Compose to initiate the Docker containers with the following commands:
> docker-compose up -d
> docker ps
Migrate the Database
There are more elegant ways to do this, depending on your stack (for example, rake for Rails applications), but the surest way to migrate your database is to simply make a backup with the Heroku CLI, then change the DATABASE_URL to point to your new database.
Set Up Docker Containers on AWS
For this section, we'll work on the AWS CLI. Make sure to follow the steps in the documentation to get the CLI set up. Once you're done with that, you can SSH into your EC2 instance with the key you saved on your machine earlier by clicking Connect and following the instructions on the pop-up.
Connect to the EC2 instance
Then run the following commands to set up Docker:
> sudo yum update -y
> sudo yum install git
> sudo amazon-linux-extras install docker
> sudo service docker start
> sudo usermod -a -G docker ec2-user
> sudo curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
> sudo chmod +x /usr/local/bin/docker-compose
> docker-compose --version
Then create your Docker containers:
> cd /var
> sudo mkdir www
> sudo mkdir <app name>
> sudo chown -R ecs-user <app name>
> git clone <source code github repo>
> cd <app name>
And finally, with Docker Compose:
> docker-compose build
> docker-compose up -d
In order to allow traffic to the instance, you'll have to change a few settings. This goes into some security aspects that can get complicated, so take note that this is a very simplified approach that'll allow you to get things running and can be augmented with more precise rules and best practices.
- Add an inbound rule to your security group to match the port in your container and allow any IP address to access it. This will be in the "Security" tab when you click on your instance.
- Click on your instance's VPC ID to see your VPCs. From here, click Actions > "Edit DNS hostnames" and enable DNS hostnames in order to allow public DNS names
And with that, you should be able to start your app on AWS!
Heroku can be an easy way to get started, but as your app grows and expands, it's likely that AWS will become more cost-effective and give you room to scale and further options to control your infrastructure. With Docker, you can migrate your app in stable containers and get up and running on AWS quickly and consistently and reap the benefits of AWS's services and economical rates.
This post was written by Vivienne Roberts. Vivienne is a versatile medical physicist turned developer involved in all manner of projects, from web development and database management for small businesses to machine learning in agricultural automation. Their focus is on providing software for companies and community organizations in need of solid infrastructure.