Every deploy starts with a build: Hangar clones your repository at the commit being deployed and produces a container image from it. The Settings → Source section of a service decides how.
Build time is not billed. Only the resources your running services use count toward your usage.
Builders
| Builder | Use it when | What it does |
|---|---|---|
| Automatic (default) | Your repository is a standard app in a common language | Detects the language and framework, installs dependencies, builds and picks a start command |
| Dockerfile | You already have a Dockerfile, or need full control of the image | Builds the Dockerfile in your repository |
| Static site | The repository is plain HTML, CSS and JavaScript | Serves the files as they are |
Three more builders are available for apps that already depend on them: Nixpacks, Heroku buildpacks and Paketo buildpacks.
Automatic
The automatic builder is Railpack, an open source builder. It reads your repository, recognises the stack (Node.js, Python, Go, PHP, Ruby, Java, Rust, Elixir, Deno, Bun and more) and builds an image without any configuration file.
The Railpack version is pinned per service, so a build today and a build in six months behave the same. You can change the pinned version in the builder's advanced settings.
Dockerfile
Choose Dockerfile and set the path to the file, relative to the service's root directory. Two optional settings cover less common layouts:
- Build context: the directory sent to the build, when it is not the root.
- Target stage: the stage to stop at in a multi-stage Dockerfile. By default the last stage is built.
Static site
The files in the repository are served directly. Turn on Single-page app to send unknown routes to index.html, which client-side routers need.
Monorepos
A service has a root directory. Point two services at the same repository with different root directories to deploy, for example, an API and a web app from one monorepo. Watch paths limit which changes trigger a deploy of each service.
Start command
The builder picks how to start your app. To override it, set a start command in the service's Settings → Runtime. This is the place for commands such as gunicorn app.wsgi --bind 0.0.0.0:8000.
The command runs directly, without a shell: it is split on spaces, so &&, pipes, $VARIABLES and quotes are passed to the program as they are. To chain commands, for example to migrate before starting, run them through a shell. Set the command to sh and add two arguments, -c and the whole line:
| Field | Value |
|---|---|
| Command | sh |
| Arguments | -c |
python manage.py migrate && gunicorn app.wsgi --bind 0.0.0.0:8000 |
Each argument is passed as one value, spaces included.
Deploys on push
Once a repository is connected through GitHub, GitLab, Bitbucket or Gitea, every push to the selected branch deploys the service. Each deploy keeps its build log, and you can cancel a build that is still running.
Docker images
A service can also run a prebuilt image from a registry instead of building from source. In that case there is no build step: Hangar pulls the image and runs it. See Deploy a Docker image.