{"id":13452417,"url":"https://github.com/gliderlabs/herokuish","last_synced_at":"2026-04-18T11:18:20.161Z","repository":{"id":23614826,"uuid":"26984122","full_name":"gliderlabs/herokuish","owner":"gliderlabs","description":"Utility for emulating Heroku build and runtime tasks in containers","archived":false,"fork":false,"pushed_at":"2025-03-30T18:09:01.000Z","size":3334,"stargazers_count":1464,"open_issues_count":14,"forks_count":153,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-03-30T19:22:25.205Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gliderlabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-22T00:50:55.000Z","updated_at":"2025-03-30T18:09:04.000Z","dependencies_parsed_at":"2023-01-13T23:34:56.570Z","dependency_job_id":"da4d32e4-d0eb-44db-aae3-fb5cd7f448a2","html_url":"https://github.com/gliderlabs/herokuish","commit_stats":{"total_commits":1419,"total_committers":59,"mean_commits":"24.050847457627118","dds":0.686398872445384,"last_synced_commit":"f58a1afd0091359e66e5d6b464bfe7b234e9f23e"},"previous_names":[],"tags_count":110,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gliderlabs%2Fherokuish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gliderlabs%2Fherokuish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gliderlabs%2Fherokuish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gliderlabs%2Fherokuish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gliderlabs","download_url":"https://codeload.github.com/gliderlabs/herokuish/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248338356,"owners_count":21087206,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T07:01:23.624Z","updated_at":"2026-04-18T11:18:20.150Z","avatar_url":"https://github.com/gliderlabs.png","language":"Shell","funding_links":[],"categories":["Shell","PHP","others"],"sub_categories":[],"readme":"# herokuish\n\n[![Build Status](https://github.com/gliderlabs/herokuish/workflows/CI/badge.svg)](https://github.com/gliderlabs/herokuish/actions?query=workflow%3ACI)\n[![IRC Channel](https://img.shields.io/badge/irc-%23gliderlabs-blue.svg)](https://kiwiirc.com/client/irc.freenode.net/#gliderlabs)\n[![Docker Hub](https://img.shields.io/badge/docker%20hub-v0.11.10-blue)](https://hub.docker.com/r/gliderlabs/herokuish)\n\nA command line tool for emulating Heroku build and runtime tasks in containers.\n\nHerokuish 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.\n\nThe goal is to be the definitive, well maintained and heavily tested Heroku emulation utility shared by all. It is based on the [Heroku:24 system image](https://github.com/heroku/base-images). Together they form a toolkit for achieving Heroku compatibility.\n\nHerokuish is a community project and is in no way affiliated with Heroku.\n\n## Getting herokuish\n\nDownload and uncompress the latest binary tarball from [releases](https://github.com/gliderlabs/herokuish/releases).\n\nFor example, you can do this directly in your Dockerfiles installing into `/bin` as one step:\n\n```shell\nRUN curl --location --silent https://github.com/gliderlabs/herokuish/releases/download/v0.11.10/herokuish_0.11.10_linux_x86_64.tgz \\\n    | tar -xzC /bin\n```\n\nHerokuish 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.\n\n## Using herokuish\n\nHerokuish 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.\n\n```shell\n$ herokuish\n\nAvailable commands:\n  buildpack                Use and install buildpacks\n    build                    Build an application using installed buildpacks\n    detect                   Detect buildpack to use for an application\n    install                  Install buildpack from Git URL and optional committish\n    list                     List installed buildpacks\n    test                     Build and run tests for an application using installed buildpacks\n  help                     Shows help information for a command\n  paths                    Shows path settings\n  procfile                 Use Procfiles and run app commands\n    exec                     Run as unprivileged user with Heroku-like env\n    parse                    Get command string for a process type from Procfile\n    start                    Run process type command from Procfile through exec\n  slug                     Manage application slugs\n    export                   Export generated slug tarball to URL (PUT) or STDOUT\n    generate                 Generate a gzipped slug tarball from the current app\n    import                   Import a gzipped slug tarball from URL or STDIN\n  test                     Test running an app through Herokuish\n  version                  Show version and supported version info\n\n```\n\nMain 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.\n\nFor 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](https://github.com/GoogleCloudPlatform/python-runtime/tree/master/runtime-image) might find procfile commands useful just to support Procfiles.\n\n`herokuish exec` will by default drop root privileges through use of [setuidgid](https://cr.yp.to/daemontools/setuidgid.html),\nbut 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`.\n\n### Buildpacks\n\nHerokuish 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:\n\n```shell\n$ herokuish version\nherokuish: 0.3.0\nbuildpacks:\n  heroku-buildpack-multi     cddec34\n  heroku-buildpack-nodejs    v60\n  heroku-buildpack-php       v43\n  heroku-buildpack-python    v52\n  heroku-buildpack-ruby      v127\n  ...\n```\n\nYou can install all supported buildpacks with `herokuish buildpack install`, or you can manually install buildpacks individually with `herokuish buildpack install \u003curl\u003e [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.\n\n### Paths\n\nUse `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.\n\n```shell\n$ herokuish paths\nAPP_PATH=/app                    # Application path during runtime\nENV_PATH=/tmp/env                # Path to files for defining base environment\nBUILD_PATH=/tmp/build            # Working directory during builds\nCACHE_PATH=/tmp/cache            # Buildpack cache location\nIMPORT_PATH=/tmp/app             # Mounted path to copy to app path\nBUILDPACK_PATH=/tmp/buildpacks   # Path to installed buildpacks\n\n```\n\n### Entrypoints\n\nSome 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.\n\n### Help\n\nDon't be afraid of the help command. It actually tells you exactly what a command does:\n\n```shell\n$ herokuish help slug export\nslug-export \u003curl\u003e\n  Export generated slug tarball to URL (PUT) or STDOUT\n\nslug-export ()\n{\n    declare desc=\"Export generated slug tarball to URL (PUT) or STDOUT\";\n    declare url=\"$1\";\n    if [[ ! -f \"$slug_path\" ]]; then\n        return 1;\n    fi;\n    if [[ -n \"$url\" ]]; then\n        curl -0 -s -o /dev/null --retry 2 -X PUT -T \"$slug_path\" \"$url\";\n    else\n        cat \"$slug_path\";\n    fi\n}\n\n```\n\n## Using Herokuish to test Heroku/Dokku apps\n\nHaving trouble pushing an app to Dokku or Heroku? Use Herokuish with a local Docker\ninstance to debug. This is especially helpful with Dokku to help determine if it's a buildpack\nissue or an issue with Dokku. Buildpack issues should be filed against Herokuish.\n\n### Running an app against Herokuish\n\n```shell\ndocker run --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish test\n```\n\nMounting 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.\n\n```shell\n::: BUILDING APP :::\n-----\u003e Ruby app detected\n-----\u003e Compiling Ruby/Rack\n-----\u003e Using Ruby version: ruby-1.9.3\n  ...\n\n```\n\nYou can use this output when you submit issues.\n\n### Running an app tests using Heroku buildpacks\n\n```shell\ndocker run --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack test\n```\n\nMounting 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.\n\n```shell\n-----\u003e Ruby app detected\n-----\u003e Setting up Test for Ruby/Rack\n-----\u003e Using Ruby version: ruby-2.3.3\n  ...\n-----\u003e Detecting rake tasks\n-----\u003e Running test: bundle exec rspec\n       .\n       Finished in 0.00239 seconds (files took 0.07525 seconds to load)\n       1 example, 0 failures\n```\n\nIf you are on macOS, you'll want to explicitly set the platform:\n\n```shell\ndocker run --platform linux/amd64 --rm -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish buildpack test\n```\n\nHowever, 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.\n\n## Troubleshooting\n\nIf you run into an issue and looking for more insight into what `herokuish` is doing, you can set the `$TRACE` environment variable.\n\n```shell\n$ docker run --rm -e TRACE=true -v /abs/app/path:/tmp/app gliderlabs/herokuish /bin/herokuish test\n+ [[ -d /tmp/app ]]\n+ rm -rf /app\n+ cp -r /tmp/app /app\n+ cmd-export paths\n+ declare 'desc=Exports a function as a command'\n+ declare fn=paths as=paths\n+ local ns=\n++ cmd-list-ns\n++ sort\n++ grep -v :\n++ for k in '\"${!CMDS[@]}\"'\n++ echo :help\n...\n++ unprivileged /tmp/buildpacks/custom/bin/detect /tmp/build\n++ setuidgid u33467 /tmp/buildpacks/custom/bin/detect /tmp/build\n++ true\n+ selected_name=\n+ [[ -n /tmp/buildpacks/custom ]]\n+ [[ -n '' ]]\n+ title 'Unable to select a buildpack'\n-----\u003e' Unable to select a buildpack\n+ exit 1\n```\n\nYou can also set a custom buildpack:\n\n```shell\ndocker run -e BUILDPACK_URL=\"https://github.com/custom/buildpack.git#with-a-branch\" -e STACK=heroku-24 -e TRACE=true --rm -v ./:/tmp/app -it gliderlabs/herokuish /bin/herokuish test\n```\n\nNote 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.\n\n`BUILDPACK_URL` must be a git remote (`https://`, `git://`, `ssh://`, `git@host:path`) or a tarball URL ending in `.tgz`, `.tar.gz`, `.tbz`, `.tar.bz`, or `.tar`. If the value is malformed or the download fails, herokuish now exits non-zero with a message such as `!     Invalid buildpack URL: 'ruby'` or `!     Failed to download buildpack from '\u003curl\u003e'` — previously this path could stop silently.\n\nIf `BUILDPACK_URL` is not set and the app's build directory contains a `.buildpacks` file with exactly one entry, herokuish treats that entry as `BUILDPACK_URL`. This bypasses `heroku-buildpack-multi` (and its \"Multiple default buildpacks reported\" warning) when only one buildpack is declared, since there is no real ambiguity. A `.buildpacks` file with two or more entries still goes through `heroku-buildpack-multi` as before. An explicit `BUILDPACK_URL` always wins over the file.\n\n### Entropy for `/dev/random`\n\nWorkloads built on `libsodium` (used by `libzmq`, `pyzmq`, and transitively by Jupyter/`voila`) can hang on startup when the container's kernel entropy pool is not yet seeded. The runtime image ships with `rng-tools5` (which provides `rngd`) and will start it before `procfile-exec` hands off to the application when `HEROKUISH_ENTROPY=true` is set:\n\n```shell\ndocker run --rm --cap-add=SYS_ADMIN -e HEROKUISH_ENTROPY=true gliderlabs/herokuish /start web\n```\n\n`rngd` needs `CAP_SYS_ADMIN` to inject entropy into `/dev/random`; without it the daemon either no-ops or logs a warning (`!     rngd failed to start`), and the application is still executed. The setting is off by default to preserve existing behavior — enable it only if you are seeing startup hangs caused by entropy starvation (see gliderlabs/herokuish#659).\n\n## Contributing\n\nPull requests are welcome! Herokuish is written in Bash and Go. Please conform to the [Bash styleguide](https://github.com/progrium/bashstyle) used for this project when writing Bash.\n\nDevelopers 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.\n\nFor help and discussion beyond Github Issues, join us on Freenode in `#gliderlabs`.\n\n## Releases\n\nAnybody 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.\n\n## Acknowledgements\n\nThis project was sponsored and made possible by the [Deis Project](http://deis.io).\n\nThat 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.\n\nIn 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](https://twitter.com/nonuby)). I've been more or less copy-and-pasting code he originally wrote for the now defunct [OpenRuko](https://github.com/openruko) since 2012.\n\nLastly, thank you Heroku for pioneering such a great platform and inspiring all of us to try and take it further.\n\n## License\n\nBSD\n\u003cimg src=\"https://ga-beacon.appspot.com/UA-58928488-2/herokuish/readme?pixel\" /\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgliderlabs%2Fherokuish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgliderlabs%2Fherokuish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgliderlabs%2Fherokuish/lists"}