Deploy

Git repositories

Build a Git repository with its Dockerfile or with Railpack, from public URLs or private GitHub and GitLab repositories.

A Git service builds your repository on every deploy and runs the result. Repositories with a Dockerfile build from it. Repositories without one build through Railpack, which detects the language and framework and creates an image for you.

Create a Git service

Open the project

Open a project and click New service → Git repository.

Fill in the form

Name
required
Up to 64 characters, for example Web.
Repository
required
Choose a repository from a Git connection, or enter a public https:// URL. See Private repositories.
Branch
required
The branch to build. Defaults to main. Choosing a repository from a Git connection fills in its default branch.
Root directory
Where your app lives in the repository, for example apps/web in a monorepo. Leave it empty for the top level.
Dockerfile path
The Dockerfile to build, relative to the root directory. Leave it empty to use a Dockerfile in the root directory if there is one, or Railpack if there isn't.
Port
The port your app listens on, from 1 to 65535. Harblet passes it to your app as PORT. Leave it empty if the service doesn't take requests, such as a worker.

Create it

Click Create service. Harblet starts the first build right away.

Follow the build on the service's Deployments tab. See Deployments and logs.

Public repositories

Any public repository works through its https:// URL, from GitHub, GitLab, Codeberg or any other host:

https://github.com/owner/repository

Harblet clones it without credentials. URLs with a username or password, SSH URLs and other protocols aren't accepted.

Private repositories

Private repositories need a Git connection. Harblet has two kinds:

  • GitHub through a GitHub App that Harblet creates for you. The app can only read the repositories you choose.
  • GitLab through an access token that you create, on GitLab.com or on a GitLab you host yourself.
Adding and removing Git connections is for admins. Once a connection is added, every member can choose its repositories.

Connect GitHub

Start on Harblet

Go to Settings → Git, click Connect and choose GitHub.

  • For your personal account, leave Organization empty.
  • For an organization, enter its name as it appears in its GitHub URL, for example acme for github.com/acme. You need to be allowed to create apps in that organization.

Click Continue on GitHub.

Create the app on GitHub

GitHub shows the app Harblet asks for: a private app named harblet-… that can read the contents and metadata of repositories. Confirm it.

Install the app

GitHub then asks where to install the app. Choose All repositories or Only select repositories, then install it. GitHub sends you back to Settings → Git.

The connection now shows under Settings → Git. Its Access column shows All repositories or Selected repositories. Click Choose repositories to change them on GitHub.

If you left GitHub before installing the app, the connection shows Not installed. Click Install to finish.

Connect GitLab

Create an access token on GitLab

Create an access token with the scopes read_api and read_repository:

  • A personal access token reads every project you're a member of.
  • A group access token or a project access token reads only that group or project. Give it the Reporter role.

Connect it

Go to Settings → Git, click Connect and choose GitLab.

GitLab URL
required
Keep https://gitlab.com for GitLab.com. If you host GitLab yourself, enter its address, for example https://gitlab.example.com, with https:// and without a path.
Access token
required
The token you created.

Click Connect. Harblet checks the token with GitLab before it saves the connection.

The connection shows under Settings → Git with the token's name. Account shows your username for a personal access token, or the group or project for a group or project access token. Access shows when the token expires, with Expires soon in its last 30 days.

Your servers have to reach your GitLab over HTTPS, since builds clone from it.
MessageWhat to do
GitLab doesn't accept this token. Check that you copied all of it and that it hasn't expired.Copy the token again, or create a new one.
The token needs the scopes read_api and read_repository.Create a new token with both scopes.
Harblet can't reach GitLab at ….Check the GitLab URL, and that your server reaches it over HTTPS.

Replace a GitLab token

Harblet doesn't renew tokens. Before a token expires, create a new one on GitLab. Then click Replace token next to the connection under Settings → Git, enter the new token and click Replace token.

The services that use the connection keep it, and their next build clones with the new token. The new token needs the same scopes and has to come from the same GitLab.

A token that expired or was revoked shows Expired or revoked. Builds of its private repositories fail until you replace it.

Choose a repository

The Repository field in New service from Git and in a service's Settings lists every repository the Git connections can read, grouped by connection, for example GitHub · acme or GitLab · acme. Private repositories have a lock. Choosing one also sets the branch to the repository's default branch.

To enter a URL instead, click Use a public URL. Click Choose a repository to go back to the list.

A connection that Harblet can't reach shows Unreachable under Settings → Git. Hover over it for the reason.

One connection serves all projects. Connect each GitHub account or organization, or each GitLab token, once.

Remove a connection

Under Settings → Git, click the trash button of the connection, then Remove connection. Services that used it clone without credentials from then on, so builds of private repositories fail.

  • GitHub: Harblet uninstalls the app from the account and forgets it. The app itself stays on GitHub. Delete it there in the app's settings under Advanced.
  • GitLab: Harblet forgets the token. The token stays valid on GitLab. Revoke it there if nothing else uses it.

How Harblet builds

Every build runs these steps:

  1. Clone. Harblet clones the newest commit of the branch. The build output names the commit.
  2. Build. Harblet builds the root directory:
    • with the Dockerfile at Dockerfile path, if you set one,
    • otherwise with a Dockerfile in the root directory, if there is one,
    • otherwise with Railpack.
  3. Deploy. Harblet stores the image in its own registry and deploys it.

Railpack

Railpack finds out how to build and start your app from its files, for example a package.json, requirements.txt or go.mod. If it can't find a start command, the build fails. Configure Railpack with a railpack.json in the root directory or with environment variables, as described in the Railpack documentation.

Variables during the build

All of the service's environment variables reach the build too:

  • Railpack gets them as environment variables and as build secrets.
  • Dockerfiles get them as build arguments and as build secrets. Read them with ARG, or mount them as a secret:
Dockerfile
ARG NEXT_PUBLIC_API_URL
RUN --mount=type=secret,id=NPM_TOKEN NPM_TOKEN=$(cat /run/secrets/NPM_TOKEN) npm ci

Prefer the secret mount for credentials, since build arguments can end up in the image's history.

The PORT variable

When your Git service has a port, Harblet sets PORT to it while the service runs, unless you set PORT yourself. Make your app listen on PORT. PORT isn't set during the build.

Build limits

  • 30 minutes. Builds that take longer fail with "The build took longer than 30 minutes."
  • x86_64 and arm64. Railpack builds run on these architectures only.
  • The last five builds of each service stay in Harblet's registry. Older builds may no longer be available to redeploy.

Deploy on every push

Harblet doesn't deploy on push by itself yet. Call the service's deploy hook at the end of your CI pipeline instead. The build then takes the newest commit of the branch.

Build errors

MessageWhat to do
There is no directory … in the repository.Check Root directory under Settings.
There is no … in the repository.Check Dockerfile path under Settings. It's relative to the root directory.
The build failed. See the build logs.Open the deployment on the Deployments tab and read the Build output.
The GitHub App … can't access …. Choose its repositories on GitHub.Under Settings → Git, click Choose repositories and add the repository.
The GitLab access token … can't access …. It needs at least the Reporter role there.Give the token at least the Reporter role in that project, or choose the repository from a connection that can read it.
GitLab rejected the access token …. It expired or was revoked, so an admin has to replace it in Settings → Git.Replace the token, see Replace a GitLab token.
… isn't a repository on ….The repository's address doesn't match the connection's GitLab URL. Choose the repository again from the list.
The build took longer than 30 minutes.Speed up the build, for example with a smaller build context or a Dockerfile with cached layers.
Copyright © 2026 Harblet