Top Related Projects
A docker-powered PaaS that helps you build and manage the lifecycle of applications
CLI for building apps using Cloud Native Buildpacks
CLI tool for spawning and running containers according to the OCI specification
The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
Podman: A tool for managing OCI containers and pods.
Quick Overview
Herokuish is an open-source utility that emulates Heroku build and runtime tasks in Docker containers. It allows developers to run Heroku-like builds and execute apps as if they were running on Heroku, but within their own infrastructure or CI/CD pipelines.
Pros
- Enables local testing and development of Heroku-style applications
- Facilitates migration from Heroku to other platforms or self-hosted environments
- Supports multiple buildpacks, allowing for flexibility in application stacks
- Integrates well with Docker-based workflows and CI/CD pipelines
Cons
- May not perfectly replicate all Heroku features or behaviors
- Requires Docker knowledge and setup, which can be a learning curve for some users
- Maintenance and updates may lag behind official Heroku changes
- Limited community support compared to official Heroku tools
Getting Started
To use Herokuish, follow these steps:
- Install Docker on your system
- Pull the Herokuish Docker image:
docker pull gliderlabs/herokuish
- Run a Herokuish container with your application code:
docker run -v /path/to/your/app:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack build
- To run the built application:
docker run -it -p 3000:3000 gliderlabs/herokuish /bin/herokuish procfile start web
These commands will build your application using Herokuish and then run it, exposing it on port 3000. Adjust the port and other parameters as needed for your specific application.
Competitor Comparisons
A docker-powered PaaS that helps you build and manage the lifecycle of applications
Pros of Dokku
- Full-featured PaaS solution with built-in deployment and scaling capabilities
- Extensive plugin ecosystem for additional functionality
- Active community and regular updates
Cons of Dokku
- More complex setup and configuration compared to Herokuish
- Requires dedicated server or VPS to run
- Steeper learning curve for beginners
Code Comparison
Herokuish:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
gliderlabs/herokuish buildpack build
Dokku:
dokku apps:create myapp
git remote add dokku dokku@yourdomain.com:myapp
git push dokku main
Key Differences
Herokuish is a utility for emulating Heroku build and runtime environments, while Dokku is a complete PaaS solution. Herokuish is often used as a component in other systems, including Dokku itself.
Herokuish focuses on providing a consistent build environment, while Dokku offers a full deployment and management platform. Dokku provides additional features like custom domains, SSL management, and database provisioning out of the box.
Herokuish is generally easier to integrate into existing CI/CD pipelines, while Dokku is better suited for those looking for a standalone PaaS solution with minimal setup.
CLI for building apps using Cloud Native Buildpacks
Pros of Pack
- Designed specifically for Cloud Native Buildpacks, offering better compatibility with modern cloud-native environments
- Supports multi-language applications and provides a more flexible build process
- Actively maintained and developed, with regular updates and improvements
Cons of Pack
- Steeper learning curve compared to Herokuish, especially for developers familiar with Heroku-style deployments
- May require more configuration and setup for certain use cases
- Less extensive documentation and community resources compared to Herokuish
Code Comparison
Herokuish:
docker run --rm -v /path/to/app:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack build
Pack:
pack build myapp --builder cnbs/sample-builder:bionic
Summary
Pack is a more modern and flexible tool designed for Cloud Native Buildpacks, offering better support for multi-language applications and cloud-native environments. However, it may have a steeper learning curve and require more configuration compared to Herokuish. Herokuish provides a simpler, Heroku-like experience but may be less suitable for complex, modern cloud-native deployments. The choice between the two depends on specific project requirements and the development team's familiarity with each tool.
CLI tool for spawning and running containers according to the OCI specification
Pros of runc
- More lightweight and focused on container runtime functionality
- Better performance and resource efficiency for running containers
- Wider adoption and support in the container ecosystem
Cons of runc
- Requires more setup and configuration compared to Herokuish
- Less abstraction for developers, potentially steeper learning curve
- Lacks built-in support for Heroku-style buildpacks
Code Comparison
runc:
spec, err := loadSpec(context)
if err != nil {
return err
}
status, err := startContainer(context, spec, CT_ACT_CREATE)
Herokuish:
if [[ -f /tmp/app/.heroku-buildpack ]]; then
selected_buildpack=$(cat /tmp/app/.heroku-buildpack)
buildpack-build
fi
The runc code snippet shows low-level container creation, while Herokuish focuses on buildpack detection and execution. runc provides more granular control over container lifecycle, whereas Herokuish abstracts away many container-related details for a more Heroku-like experience.
The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
Pros of Moby
- Larger, more active community with frequent updates and contributions
- More comprehensive containerization platform with broader feature set
- Better performance and scalability for large-scale container deployments
Cons of Moby
- Steeper learning curve and more complex setup compared to Herokuish
- Requires more system resources and overhead for smaller projects
- Less focused on Heroku-style workflows and buildpacks
Code Comparison
Herokuish (simplified buildpack execution):
/bin/herokuish buildpack build
/bin/herokuish procfile start web
Moby (Docker container creation and run):
FROM docker:dind
RUN docker build -t myapp .
CMD ["docker", "run", "-p", "8080:8080", "myapp"]
Summary
Herokuish is a lightweight tool focused on emulating Heroku-style deployments, making it ideal for simple projects and those familiar with Heroku workflows. Moby, on the other hand, is a more comprehensive containerization platform offering greater flexibility and scalability but with increased complexity. Choose Herokuish for quick, Heroku-like deployments, and Moby for more advanced containerization needs and larger-scale projects.
Podman: A tool for managing OCI containers and pods.
Pros of Podman
- Native support for rootless containers, enhancing security
- OCI-compliant, offering better compatibility with other container technologies
- Daemonless architecture, reducing system overhead
Cons of Podman
- Less mature ecosystem compared to Docker-based solutions
- May require additional configuration for certain use cases
- Limited support for some Docker-specific features
Code Comparison
Herokuish:
docker run --rm -v /path/to/app:/tmp/app gliderlabs/herokuish buildpack build
Podman:
podman run --rm -v /path/to/app:/tmp/app registry.fedoraproject.org/fedora:latest buildah bud -t myapp .
Key Differences
Herokuish focuses on emulating Heroku's build and runtime environment, making it easier to run Heroku-like apps locally or in CI/CD pipelines. It's particularly useful for teams transitioning from Heroku or maintaining compatibility with Heroku's ecosystem.
Podman, on the other hand, is a more general-purpose container engine that aims to be a drop-in replacement for Docker. It offers enhanced security features and is designed to be more flexible and standards-compliant.
While Herokuish is specialized for Heroku-style deployments, Podman provides a broader range of container management capabilities, making it suitable for a wider variety of containerization scenarios.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
herokuish
A command line tool for emulating Heroku build and runtime tasks in containers.
Herokuish is made for platform authors. The project consolidates and decouples Heroku compatibility logic (running buildpacks, parsing Procfile) and supporting workflow (importing/exporting slugs) from specific platform images like those in Dokku/Buildstep, Deis, Flynn, etc.
The goal is to be the definitive, well maintained and heavily tested Heroku emulation utility shared by all. It is based on the Heroku:20, Heroku:22, and Heroku:24 system images. Together they form a toolkit for achieving Heroku compatibility.
Herokuish is a community project and is in no way affiliated with Heroku.
Getting herokuish
Download and uncompress the latest binary tarball from releases.
For example, you can do this directly in your Dockerfiles installing into /bin
as one step:
RUN curl --location --silent https://github.com/gliderlabs/herokuish/releases/download/v0.10.1/herokuish_0.10.1_linux_x86_64.tgz \
| tar -xzC /bin
Herokuish depends on Bash (4.0 or newer) and a handful of standard GNU utilties you probably have. It likely won't work on Busybox, though neither will any Heroku buildpacks.
Using herokuish
Herokuish is meant to work behind the scenes inside a container. It tries not to force decisions about how you construct and operate containers. In fact, there's nothing that even ties it specifically to Docker. It focuses on neatly emulating Heroku, letting you design and orchestrate containers around it.
$ herokuish
Available commands:
buildpack Use and install buildpacks
build Build an application using installed buildpacks
install Install buildpack from Git URL and optional committish
list List installed buildpacks
test Build and run tests for an application using installed buildpacks
help Shows help information for a command
paths Shows path settings
procfile Use Procfiles and run app commands
exec Run as unprivileged user with Heroku-like env
parse Get command string for a process type from Procfile
start Run process type command from Procfile through exec
slug Manage application slugs
export Export generated slug tarball to URL (PUT) or STDOUT
generate Generate a gzipped slug tarball from the current app
import Import a gzipped slug tarball from URL or STDIN
test Test running an app through Herokuish
version Show version and supported version info
Main functionality revolves around buildpack commands, procfile/exec commands, and slug commands. They are made to work together, but can be used independently or not at all.
For example, build processes that produce Docker images without producing intermediary slugs can ignore slug commands. Similarly, non-buildpack runtime images such as google/python-runtime might find procfile commands useful just to support Procfiles.
herokuish exec
will by default drop root privileges through use of setuidgid,
but if already running as a non-root user setuidgid will fail, you can opt-out from this by setting the env-var HEROKUISH_SETUIDGUID=false
.
Buildpacks
Herokuish does not come with any buildpacks, but it is tested against recent versions of Heroku supported buildpacks. You can see this information with herokuish version
. Example output:
$ herokuish version
herokuish: 0.3.0
buildpacks:
heroku-buildpack-multi cddec34
heroku-buildpack-nodejs v60
heroku-buildpack-php v43
heroku-buildpack-python v52
heroku-buildpack-ruby v127
...
You can install all supported buildpacks with herokuish buildpack install
, or you can manually install buildpacks individually with herokuish buildpack install <url> [committish]
. You can also mount a directory containing your platform's supported buildpacks (see Paths, next section), or you could bake your supported buildpacks into an image. These are the types of decisions that are up to you.
Paths
Use herokuish paths
to see relevant system paths it uses. You can use these to import or mount data for use inside a container. They can also be overridden by setting the appropriate environment variable.
$ herokuish paths
APP_PATH=/app # Application path during runtime
ENV_PATH=/tmp/env # Path to files for defining base environment
BUILD_PATH=/tmp/build # Working directory during builds
CACHE_PATH=/tmp/cache # Buildpack cache location
IMPORT_PATH=/tmp/app # Mounted path to copy to app path
BUILDPACK_PATH=/tmp/buildpacks # Path to installed buildpacks
Entrypoints
Some subcommands are made to be used as default commands or entrypoint commands for containers. Specifically, herokuish detects if it was called as /start
, /exec
, or /build
which will shortcut it to running those subcommands directly. This means you can either install the binary in those locations or create symlinks from those locations, allowing you to use them as your container entrypoint.
Help
Don't be afraid of the help command. It actually tells you exactly what a command does:
$ herokuish help slug export
slug-export <url>
Export generated slug tarball to URL (PUT) or STDOUT
slug-export ()
{
declare desc="Export generated slug tarball to URL (PUT) or STDOUT";
declare url="$1";
if [[ ! -f "$slug_path" ]]; then
return 1;
fi;
if [[ -n "$url" ]]; then
curl -0 -s -o /dev/null --retry 2 -X PUT -T "$slug_path" "$url";
else
cat "$slug_path";
fi
}
Using Herokuish to test Heroku/Dokku apps
Having trouble pushing an app to Dokku or Heroku? Use Herokuish with a local Docker instance to debug. This is especially helpful with Dokku to help determine if it's a buildpack issue or an issue with Dokku. Buildpack issues should be filed against Herokuish.
Running an app against Herokuish
docker run --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish test
Mounting your local app source directory to /tmp/app
and running /bin/herokuish test
will run your app through the buildpack compile process. Then it starts your web
process and attempts to connect to the web root path. If it runs into a problem, it should exit non-zero.
::: BUILDING APP :::
-----> Ruby app detected
-----> Compiling Ruby/Rack
-----> Using Ruby version: ruby-1.9.3
...
You can use this output when you submit issues.
Running an app tests using Heroku buildpacks
docker run --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack test
Mounting your local app source directory to /tmp/app
and running /bin/herokuish buildpack test
will run your app through the buildpack test-compile process. Then it will run test
command to execute application tests.
-----> Ruby app detected
-----> Setting up Test for Ruby/Rack
-----> Using Ruby version: ruby-2.3.3
...
-----> Detecting rake tasks
-----> Running test: bundle exec rspec
.
Finished in 0.00239 seconds (files took 0.07525 seconds to load)
1 example, 0 failures
If you are on macOS, you'll want to explicitly set the platform:
docker run --platform linux/amd64 --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack test
However, there is a risk of compatibility issues when running on a different platform than the one you are developing on. If you are getting strange compilation or segfaults, try running the build process on an x86 platform.
Troubleshooting
If you run into an issue and looking for more insight into what herokuish
is doing, you can set the $TRACE
environment variable.
$ docker run --rm -e TRACE=true -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish test
+ [[ -d /tmp/app ]]
+ rm -rf /app
+ cp -r /tmp/app /app
+ cmd-export paths
+ declare 'desc=Exports a function as a command'
+ declare fn=paths as=paths
+ local ns=
++ cmd-list-ns
++ sort
++ grep -v :
++ for k in '"${!CMDS[@]}"'
++ echo :help
...
++ unprivileged /tmp/buildpacks/custom/bin/detect /tmp/build
++ setuidgid u33467 /tmp/buildpacks/custom/bin/detect /tmp/build
++ true
+ selected_name=
+ [[ -n /tmp/buildpacks/custom ]]
+ [[ -n '' ]]
+ title 'Unable to select a buildpack'
----->' Unable to select a buildpack
+ exit 1
You can also set a custom buildpack:
docker run -e BUILDPACK_URL="https://github.com/custom/buildpack.git#with-a-branch" -e STACK=heroku-20 -e TRACE=true --rm -v ./:/tmp/app -it gliderlabs/herokuish /bin/herokuish test
Note that the underlying buildpacks will not trace their commands with TRACE=true
is enabled. They need to independently set set -x
in order to trace execution.
Contributing
Pull requests are welcome! Herokuish is written in Bash and Go. Please conform to the Bash styleguide used for this project when writing Bash.
Developers should have Go installed with cross-compile support for Darwin and Linux. Tests will require Docker to be available. If you have OS X, we recommend boot2docker.
For help and discussion beyond Github Issues, join us on Freenode in #gliderlabs
.
Releases
Anybody can propose a release. First bump the version in Makefile
and Dockerfile
, make sure CHANGELOG.md
is up to date, and make sure tests are passing. Then open a Pull Request from master
into the release
branch. Once a maintainer approves and merges, Github Actions will build a release and upload it to Github.
Acknowledgements
This project was sponsored and made possible by the Deis Project.
That said, herokuish was designed based on the experience developing and re-developing Heroku compatibility in Dokku, Deis, and Flynn. Herokuish is based on code from all three projects, as such, thank you to all the contributors of those projects.
In fact, since I hope this is the final implementation of Heroku emulation I'm involved with, I'd like to finally thank Matt Freeman (@nonuby). I've been more or less copy-and-pasting code he originally wrote for the now defunct OpenRuko since 2012.
Lastly, thank you Heroku for pioneering such a great platform and inspiring all of us to try and take it further.
License
BSD
Top Related Projects
A docker-powered PaaS that helps you build and manage the lifecycle of applications
CLI for building apps using Cloud Native Buildpacks
CLI tool for spawning and running containers according to the OCI specification
The Moby Project - a collaborative project for the container ecosystem to assemble container-based systems
Podman: A tool for managing OCI containers and pods.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot