What Is Heroku Deployment?
Heroku is a platform-as-a-service (PaaS) for deploying, scaling, and managing applications. It supports various programming languages such as Ruby, Java, Node.js, Scala, Clojure, Python, PHP, and Go. Being cloud-based, Heroku removes the need for server and hardware management, enabling developers to concentrate on coding.
To deploy on Heroku, you upload your application’s code to the Heroku platform. This can be done using Git, containerizing your app with Docker, or leveraging Heroku’s integrations with third-party systems. After deployment, Heroku runs your application in a dyno, which is a lightweight, containerized Linux environment. An application can utilize multiple dynos to scale up for increased traffic or scale down when less capacity is required.
Preparing a Codebase for Heroku Deployment
Before deploying your codebase to Heroku, ensure it adheres to a few conventions to ensure a successful deployment. Below are the steps to prepare your codebase:
1. Track your codebase in a Git repository
Heroku’s deployment system uses Git, so your codebase must be committed to a Git repository. If you don’t have Git installed, install it and set it up. If you are using another version control system, export your codebase to Git.
git init git add . git commit -m "My first commit"
2. Add a Heroku Git remote
Every Heroku application has its own Heroku-hosted Git repository. To deploy your app, push your code changes to this repository. Add the Heroku remote to your local Git repository:
heroku git:remote -a my-application
3. Add a Procfile
A Procfile is a text file in the root directory of your application that specifies the commands Heroku should run to start your app. Create a Procfile with the following content if you’re using a Node.js application:
web: node app.js
For a Rails application, it might look like:
web: bundle exec rails server -p $PORT worker: bundle exec rake jobs:work
4. Listen on the correct port On Heroku, your application must listen on a port specified by the PORT environment variable. Modify your code to use this variable. For instance, in a Node.js app using Express:
let port = process.env.PORT || 8000; app.listen(port, () => { console.log('Server is running on port ${port}'); });
5. Use a database or object storage instead of writing to the local filesystem
Heroku dynos have an ephemeral filesystem, so any data written to the local filesystem will be lost when the dyno cycles. Use a managed database service like Heroku Postgres or object storage like Amazon S3 for persistent storage.
6. Complete language-specific setup
Some languages and frameworks require additional setup. For instance, a Node.js app needs a package.json file with a start script, and a Python app needs a requirements.txt file. Refer to Heroku’s language-specific deployment guides for detailed instructions.
Now that we’re done preparing, let’s take a look at the top three ways to deploy your applications to Heroku.
TIPS FROM THE EXPERT
In my experience, here are tips that can help you better deploy applications to Heroku:
- Integrate with GitHub: Utilize Heroku’s GitHub integration to automatically deploy changes from your repository. This setup can trigger deployments on each push to specific branches, facilitating a streamlined workflow.
- Monitor with Heroku Metrics: Leverage Heroku’s built-in monitoring tools to keep an eye on your app’s performance and resource usage. Setting up alerts for key metrics like response time and memory usage can help you proactively address issues.
- Enable review apps for pull requests: Automatically create temporary Heroku apps for each pull request using Heroku’s Review Apps feature. This allows you to test changes in an isolated environment before merging them into the main branch.
- Implement a caching layer: To improve performance, consider adding a caching layer using add-ons like Memcached or Redis. This can reduce load times and decrease the number of requests to your primary database.
- Optimize dyno formation: Experiment with different dyno types and quantities to optimize cost and performance. Standard-1X, Standard-2X, Performance-M, and Performance-L dynos offer various resource allocations that can be tailored to your app’s needs.
1. Deploying to Heroku with Git
Deploying an application to Heroku using Git involves several steps, which include initializing a Git repository, creating a Heroku remote, and pushing your code to Heroku. Below is a detailed guide.
Prerequisites:
- Ensure that both Git and the Heroku CLI are installed on your system.
Step 1: Create a Heroku remote Next, create a new Heroku application, which automatically sets up an empty Git repository hosted on Heroku. Use the heroku create command:
heroku create -a my-app
This command creates a new application named my-app and sets up the Heroku remote repository. You can verify the remote setup using:
git remote -v
The output should list the Heroku remote URLs for fetching and pushing:
heroku https://git.heroku.com/my-app.git (fetch) heroku https://git.heroku.com/my-app.git (push)
Step 2: Deploy your code To deploy your code to Heroku, push your local repository’s main branch to the Heroku remote:
git push heroku main
Heroku will receive the code, build the application, and deploy it to the specified app.
If you need to deploy code from a branch other than main, use the following syntax to push it to the main branch on Heroku:
git push heroku my-branch-name:main
This command tells Git to push the specified branch to the main branch on the Heroku remote.
2. Deploying Docker Images to Heroku
Deploying Docker images to Heroku involves several steps, leveraging Heroku’s Container Registry. Here’s a detailed guide to deploying your Docker images.
Prerequisites
Ensure that you have Docker installed and that you are logged into Heroku using the Heroku CLI.
1. Log in to Heroku container registry
First, log in to Heroku’s container registry. This can be done using the Heroku CLI:
heroku container:login
2. Clone a sample application
For demonstration purposes, you can clone a sample Python application based on Alpine Linux:
git clone https://github.com/heroku/alpinehelloworld.git
Navigate to the application directory:
cd alpinehelloworld
3. Create a Heroku application
Create a new Heroku application that uses the container stack:
heroku create --stack container
This command will create a new Heroku application and set up a Git repository for it. The output will include the app’s URL and Git repository.
4. Build and push the Docker image
Build the Docker image and push it to Heroku’s container registry:
heroku container:push web
5. Release the Docker image
After pushing the image, release it to your Heroku application:
heroku container:release web
6. Open the application
Finally, open your application in the browser:
heroku open
The following additional Docker commands might also come in useful:
You can build and push a Docker image using this command:
heroku container:push <process-type>
To push an image from Docker Hub to Heroku:
docker tag <image> registry.heroku.com/<app>/<process-type> docker push registry.heroku.com/<app>/<process-type>
For projects with multiple Dockerfiles, rename them as Dockerfile.<process-type> and use these commands:
ls -R ./webapp: Dockerfile.web ./worker: Dockerfile.worker ./image-processor: Dockerfile.image
From the project’s root directory, run:
heroku container:push --recursive
This command will build and push all specified images.
After pushing the images, release them as follows:
heroku container:release web worker
3. Deploying Node.js Apps on Heroku
Deploying a Node.js application on Heroku involves several steps, including preparing your codebase, defining dependencies, specifying the Node.js version, and finally deploying the application. Below is a detailed guide.
Preparing Your Node.js Application for Deployment
Prerequisites
Ensure you have the following:
- Node.js and npm installed.
- An existing Node.js application.
- A free Heroku account.
- The Heroku CLI installed.
Step 1: Create a package.json fileThe package.json file defines the dependencies your application needs. To create this file, run the following command in your application’s root directory:
npm init
Follow the prompts to set up your package.json file. Here is an example of what a package.json file might look like:
{ "name": "my-node-app", "version": "1.0.0", "description": "This is my Node.js application.", "main": "web.js", "scripts": { `"test": "echo \"Error: no test specified\" && exit 1"` }, "keywords": [ "example", "heroku" ], "author": "mark-smith", "license": "GNU" }
Step 2: Declare app dependenciesInstall the required dependencies for your application and ensure they are listed in your package.json file. For example, to install Express, run:
npm install express
Your updated package.json file should include the dependencies:
{ ... "dependencies": { "express": "^4.19.2" } }
Step 3: Specify the Node versionSpecify the Node.js version to ensure consistency between your development and production environments. Add the following to your package.json file:
"engines": { "node": "20.16.0" }
Step 4: Create a ProcfileA Procfile specifies the commands Heroku runs to start your application. Create a Procfile in your application’s root directory with the following content if you are using Express:
web: node web.js
Step 5: Build and test locally
Install the dependencies and start your application locally to ensure everything is set up correctly:
npm install heroku local web --port 5001
Your application should now be running at http://localhost:5001/.
Deploying Your Node.js Application
1. Commit your changes: Ensure all changes are committed to Git:
git add . git commit -m "Initial commit"
2. Log in to Heroku: Authenticate with Heroku:
heroku login
3. Create a Heroku application: Create a new Heroku app:
heroku create example-app
4. Deploy to Heroku: Push your code to Heroku:
git push heroku main
You should see output similar to:
-----> Node.js app detected ... -----> Launching... done http://example-app-1234567890ab.herokuapp.com deployed to Heroku
5. Open your application:
Finally, open your application in the browser:
heroku open
Moving from Heroku to a Full GitOps Workflow with Codefresh
Heroku is a great PaaS for rapid deployments and simple projects. Startups love Heroku because of the simplicity and easy integrations with Heroku add-ons.
However Heroku can be very expensive as the application scales up (the number of dynos needs to be increased) and presents a lot of challenges for complex scenarios and microservices based applications. Organizations who want full control over their deployments (including custom metrics) will quickly discover that Heroku is very inflexible and limited when it comes to Enterprise cloud applications.
Codefresh is an Enterprise Deployment platform focused on Kubernetes and GitOps.Codefresh is powered by the Argo family of tools (Argo CD, Argo Rollouts, Argo Events, Argo Workflows) and is specifically designed for organizations that work with containers and cloud applications.
Codefresh lets you answer many important questions within your organization, whether you’re a developer or a product manager. For example:
- What features are deployed right now in any of your environments?
- What features are waiting in Staging?
- What features were deployed last Thursday?
- Where is feature #53.6 in our environment chain?
What’s great is that you can answer all of these questions by viewing one single dashboard. Our applications dashboard shows:
- Services affected by each deployment
- The current state of Kubernetes components
- Deployment history and log of who deployed what and when and the pull request or Jira ticket associated with each deployment
This allows not only your developers to view and better understand your deployments, but it also allows the business to answer important questions within an organization. For example, if you are a product manager, you can view when a new feature is deployed or not and who was it deployed by.
The World’s Most Modern CI/CD Platform
A next generation CI/CD platform designed for cloud-native applications, offering dynamic builds, progressive delivery, and much more.
Check It Out