Skip Navigation
Show nav
Heroku Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku Architecture
    • Dynos (app containers)
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Command Line
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery
    • Continuous Integration
  • Language Support
    • Node.js
    • Ruby
      • Working with Bundler
      • Rails Support
    • Python
      • Working with Django
      • Background Jobs in Python
    • Java
      • Working with Maven
      • Java Database Operations
      • Working with Spring Boot
      • Java Advanced Topics
    • PHP
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • Other Data Stores
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
    • Compliance
  • Heroku Enterprise
    • Private Spaces
      • Infrastructure Networking
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
    • Single Sign-on (SSO)
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Deployment
  • Deploying with Docker
  • Building Docker Images with heroku.yml

Building Docker Images with heroku.yml

English — 日本語に切り替える

Last updated November 02, 2022

Table of Contents

  • Getting started
  • heroku.yml Overview
  • setup: Defining your app’s environment
  • build: Defining your build
  • release: Configuring release phase
  • run: Defining the processes to run
  • Review apps and app.json
  • Creating your app from ‘setup’
  • Known issues and limitations

The heroku.yml file is a manifest you can use to define your Heroku app. It allows you to:

  • Build Docker images on Heroku
  • Specify add-ons and config vars to create during app provisioning
  • Take advantage of Review Apps when deploying Docker-based applications

The Heroku container stack is intended for advanced use-cases only. Unless you have a specific need for custom Docker images, we recommend using Heroku’s default buildpack-powered build system instead, which offers automatic stack-image security updates, language-specific optimisations, and avoids the need to maintain a Dockerfile.

Getting started

  1. Create a heroku.yml file in your application’s root directory. The following example heroku.yml specifies the Docker image to build for the app’s web process:

    build:
      docker:
        web: Dockerfile
    run:
      web: bundle exec puma -C config/puma.rb
    

    In this example, both heroku.yml and Dockerfile are in the same directory. If the Dockerfile lives in a non-root directory, specify the relative path in the build.docker.web value, such as app/Dockerfile.

    If you don’t include a run section, Heroku uses the CMD specified in the Dockerfile.

  2. Commit the file to your repo:

    $ git add heroku.yml
    $ git commit -m "Add heroku.yml"
    
  3. Set the stack of your app to container:

    $ heroku stack:set container
    
  4. Push your app to Heroku:

    $ git push heroku master
    

Your application will be built, and Heroku will use the run command provided in heroku.yml instead of your Procfile.

heroku.yml Overview

A heroku.yml manifest has 4 top-level sections:

  • setup - Specifies the add-ons and config vars to create during app provisioning
  • build - Specifies the Dockerfile to build
  • release - Specifies the release phase tasks to execute
  • run - Specifies process types and the commands to run for each

Details for each of these sections are described below.

Here’s an example that illustrates using a heroku.yml manifest to build Docker images:

setup:
  addons:
    - plan: heroku-postgresql
      as: DATABASE
  config:
    S3_BUCKET: my-example-bucket
build:
  docker:
    web: Dockerfile
    worker: worker/Dockerfile
  config:
    RAILS_ENV: development
    FOO: bar
release:
  command:
    - ./deployment-tasks.sh
  image: worker
run:
  web: bundle exec puma -C config/puma.rb
  worker: python myworker.py
  asset-syncer:
    command:
      - python asset-syncer.py
    image: worker

setup: Defining your app’s environment

Configuring add-ons

heroku.yml supports creating add-ons at app provisioning time. To provision an add-on, add it to the setup.addons section:

setup:
  addons:
  - plan: heroku-postgresql
    as: DATABASE

The optional as option allows you to attach multiple instances of the same add-on provider with different names.

Setting config vars

heroku.yml supports setting config vars at app provisioning time. To set a config var, add it to the setup.config section:

setup:
  config:
    S3_BUCKET: my-example-bucket

Learn how to create an app from setup.

build: Defining your build

Specify Dockerfiles using paths relative to heroku.yml:

build:
  docker:
    web: Dockerfile
    worker: worker/Dockerfile

The Docker build context is set to the directory containing the Dockerfile.

If you do not specify a run section, the CMD specified in the Dockerfile is used.

Setting build-time environment variables

The config field of the build section allows you set environment variables available to the build environment. Variables set in this section do not create runtime config vars. Also runtime config vars (e.g., those set with heroku config:set) are not available at build-time.

build:
  config:
    RAILS_ENV: development
    FOO: bar

Each build-time environment variable must match an ARG line in your Dockerfile:

ARG RAILS_ENV=production
ARG FOO

Targeting a stage from a multi-stage build

With a multi-stage Docker build you can manage build and production images for your application in a single Dockerfile. For example, you might want to have specific packages or database migration scripts only available at build and release time, but not in your final production image.

Here’s an example of a multi-stage Dockerfile. The builder stage includes database migration scripts and the production stage only has the app code and dependencies necessary to run the app.

FROM heroku/heroku:18-build AS builder
...

FROM heroku/heroku:18 AS production
...

Here’s an example heroku.yml which specifies to only use the output of the builder stage as the release image:

build:
  docker:
    release:
       dockerfile: Dockerfile
       target: builder
    web: Dockerfile

release: Configuring release phase

Release phase enables you to run tasks before a new release is deployed to production (e.g., sending CSS/JS/assets to a CDN, priming cache stores, or running database schema migrations).

To define a release phase command, specify a release section with a command in your heroku.yml manifest, as well as the image you would like to use:

build:
  docker:
    web: Dockerfile
    worker: worker/Dockerfile
release:
  image: worker
  command:
    - ./deployment-tasks.sh

Runtime config vars, such as a database connection url, are available during release phase.

If you would like to see streaming logs as release phase executes, your Docker image is required to have curl. If your Docker image does not include curl, release phase logs are available in your application logs. If you’re using a Heroku stack as your base image, curl is included.

run: Defining the processes to run

The run section allows you to define the process that you would like Heroku to run when your application starts. If your project also includes a Procfile, it is ignored and run is used instead.

run:
  web: bundle exec puma -C config/puma.rb

To use a specific Docker image for multiple processes, specify it with image:

build:
  docker:
    web: Dockerfile
run:
  web: bundle exec puma -C config/puma.rb
  worker:
    command:
      - python myworker.py
    image: web

If you do not include a run section in your heroku.yml manifest, the Dockerfile CMD is used instead.

To learn more about the runtime requirements for Docker images, review the Container Registry and Runtime documentation.

Review apps and app.json

An app.json file is still required when using Review Apps with the heroku.yml manifest. Be sure to set the stack value in your app.json file to container.

Apps using Docker images can’t use pr-predestroy scripts. These scripts get ignored if included in your app.json file.

Creating your app from ‘setup’

Creating an app from setup is currently in beta. Please email heroku-build-manifest-feedback@salesforce.com to provide feedback.

To create an app from the setup section defined in your heroku.yml manifest, install the heroku-manifest plugin from the beta update channel:

$ heroku update beta
$ heroku plugins:install @heroku-cli/plugin-manifest

You can switch back to the stable update stream and remove the plugin at any time:

$ heroku update stable
$ heroku plugins:remove manifest

Then create your app using the --manifest flag. The stack of the app will automatically be set to container:

$ heroku create your-app-name --manifest
Creating ⬢ your-app-name... done, stack is container
Adding heroku-postgresql... done
Setting config vars... done

Commit heroku.yml to git:

$ git add heroku.yml
$ git commit -m "Added heroku.yml"

Push the code:

$ git push heroku master

Known issues and limitations

  • Caching of Docker image layers is not supported.
  • Private Spaces do not honor the run section in heroku.yml yet, so the command must instead be specified via the Dockerfile.
  • Private repositories/registries are not supported in the FROM line of the Dockerfile.
  • The Docker build context is always set to the directory containing the Dockerfile and cannot be configured independently.
  • The environment where heroku.yml builds occur may use a slightly different CPU generation to that at runtime (depending on choice of runtime environment and dyno size), such that binary executables compiled for a specific CPU instruction set may not work at runtime. If you encounter Illegal instruction errors at runtime, try adjusting the build time compilation options to disable CPU-specific optimisations. When using GCC, this can be achieved by passing -march=x86-64 -mtune=generic to the compiler.
  • The known issues and limitations of the underlying container runtime also apply.

Keep reading

  • Deploying with Docker

Feedback

Log in to submit feedback.

Local Development with Docker Compose Container Registry & Runtime (Docker Deploys)

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Podcasts
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing

Subscribe to our monthly newsletter

Your email address:

  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Heroku Podcasts
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Facebook
  • Instagram
  • Github
  • LinkedIn
  • YouTube
Heroku is acompany

 © Salesforce.com

  • heroku.com
  • Terms of Service
  • Privacy
  • Cookies
  • Cookie Preferences