Skip to content

Instantly share code, notes, and snippets.

@syntaqx
Last active December 2, 2024 05:40
Show Gist options
  • Save syntaqx/98489f02b4431a793079eb490d72f1f1 to your computer and use it in GitHub Desktop.
Save syntaqx/98489f02b4431a793079eb490d72f1f1 to your computer and use it in GitHub Desktop.
How to Set Up Your Existing Heroku App for Docker Deployment

Setting Up Your Heroku App for Docker-Based Deployment

Follow these instructions to prepare your Heroku app for Docker-based deployment.


Step 1: Open Your Terminal and Navigate to Your Code

  • Open a terminal.
  • Move into your project directory. For example:
cd ~/Code/example/api

Confirm you’re in the right place by listing the files:

ls

You should see your Dockerfile and Python app files here.


Step 2: Log In to Heroku

Authenticate with the Heroku CLI:

heroku login

Step 3: Install the Heroku Container Plugin

Ensure the Heroku CLI is ready for Docker-based deployments by installing the required plugin:

heroku plugins:install @heroku-cli/plugin-container-registry

Step 4: Create or Link Your Heroku App

If the app doesn’t exist, create it:

Replace example-api with the name you want for your app:

heroku create example-api

If the app already exists, link it to your local repository:

Replace example-api with the name of your Heroku app:

heroku git:remote -a example-api

Step 5: Clear Any Existing Buildpacks

Since we are deploying with Docker, clear any buildpacks set for the Heroku app:

heroku buildpacks:clear --app example-api

Step 6: Log In to Heroku Container Registry

Authenticate Docker with Heroku’s container registry:

heroku container:login

Step 7: Configure Environment Variables

Set environment variables required for your Python app. Replace placeholder values with actual data:

heroku config:set FLASK_ENV=production --app example-api
heroku config:set MONGO_URI=mongodb+srv://<username>:<password>@cluster.example.com/dbname --app example-api
heroku config:set ADMIN_USERNAME=admin --app example-api
heroku config:set ADMIN_PASSWORD=securepassword --app example-api

Step 8: Scale the Dynos

Make sure the app has at least one dyno running for the web process:

heroku ps:scale web=1 --app example-api

Step 9: Build and Tag Your Docker Image Locally

Before pushing the image to Heroku, build it locally and tag it for the Heroku container registry:

docker build -t registry.heroku.com/example-api/web .

Step 10: Push Your Docker Build to Heroku

Push the Docker image to Heroku and release it to confirm that the app is live:

heroku container:push web --app example-api
heroku container:release web --app example-api

Setup Complete

Your Heroku app is now configured for Docker-based deployments. You’ve also pushed a build to Heroku to confirm everything is working. Going forward, you can automate this process using GitHub Actions.


Example GitHub Workflows for Future Automation

To automate deployments, consider the following example workflows

name: Docker CI
on:
push:
branches:
- main # Trigger only on the main branch
env:
DOCKERHUB_IMAGE: example/api
HEROKU_APP_NAME: example-api
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
jobs:
build:
runs-on: ubuntu-latest
steps:
# Step 1: Check out the repository
- name: Checkout repository
uses: actions/checkout@v4
# Step 2: Generate metadata for Docker images
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKERHUB_IMAGE }}
tags: |
type=ref,event=branch
type=sha
flavor: |
latest=auto
prefix=
suffix=
# Step 3: Set up QEMU for cross-platform builds
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# Step 4: Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Step 5: Log in to Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# Step 6: Sign into the Heroku Container Registry
- name: Sign into the Heroku Container Registry
run: heroku container:login
# Step 7: Build and push Docker images to both Docker Hub and Heroku with caching
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
cache-from: type=registry,ref=${{ env.DOCKERHUB_IMAGE }}:buildcache
cache-to: type=registry,ref=${{ env.DOCKERHUB_IMAGE }}:buildcache,mode=max
tags: |
${{ steps.meta.outputs.tags }}
registry.heroku.com/${{ env.HEROKU_APP_NAME }}/web
labels: ${{ steps.meta.outputs.labels }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Only deploy on the main branch
environment:
name: production
url: https://api.example.org/
steps:
# Step 1: Sign into the Heroku Container Registry
- name: Sign into the Heroku Container Registry
run: heroku container:login
# Step 2: Release the image on Heroku
- name: Release to Heroku
run: heroku container:release web --app ${{ env.HEROKU_APP_NAME }}
name: Docker CI
on:
push:
branches:
- main # Trigger only on the main branch
env:
HEROKU_APP_NAME: example-api
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
jobs:
build:
runs-on: ubuntu-latest
steps:
# Step 1: Check out the repository
- name: Checkout repository
uses: actions/checkout@v4
# Step 2: Generate metadata for Docker images
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: registry.heroku.com/${{ env.HEROKU_APP_NAME }}/web
tags: |
type=ref,event=branch
type=sha
flavor: |
latest=auto
prefix=
suffix=
# Step 3: Set up QEMU for cross-platform builds
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
# Step 4: Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Step 5: Sign into the Heroku Container Registry
- name: Sign into the Heroku Container Registry
run: heroku container:login
# Step 6: Build and push the Docker image to Heroku
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Only deploy on the main branch
environment:
name: production
url: https://api.example.org/
steps:
# Step 1: Sign into the Heroku Container Registry
- name: Sign into the Heroku Container Registry
run: heroku container:login
# Step 2: Release the image on Heroku
- name: Release to Heroku
run: heroku container:release web --app ${{ env.HEROKU_APP_NAME }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment