Skip to content
All guides

Apps ·

Deploy from a GitHub repository

Connect a repository to a Container App, pick a branch, and have every push built and deployed. Covers the first build, build logs, environment and build variables, and the usual failures.

A Container App can be built straight from a GitHub repository: connect the repository once, pick a branch, and every push to that branch is built and deployed for you. No Dockerfile is required, though one is used when present. This guide walks through the first deploy, what happens on a push, and how to read a failed build.

What you need

  • A Headpat Space account with a verified email address and your billing details filled in.
  • A GitHub repository with a web application in it: Node, Python, Go, Ruby, PHP, Rust, Java, or anything with a Dockerfile. You need permission to install GitHub Apps on the account or organisation that owns it.

1. Create the app from GitHub

  1. Sign in to the panel, open Apps in the sidebar and click Create App.
  2. Under Template, select Container App.
  3. Under the source options choose From GitHub and click Connect GitHub. GitHub opens, asks on which account or organisation to install the Headpat app and which repositories it may see. Pick the repository, or all of them, and confirm; GitHub sends you back to the wizard.
  4. Pick the GitHub account, the Repository and the Branch to deploy. A note under the branch reminds you that every push to it rebuilds and redeploys the app.
  5. Set the Container port: the port your app listens on inside the container, for example 3000 for a Node server. The platform routes HTTPS traffic to it.
  6. Add Environment variables your app needs at runtime, and Build-time variables if the build needs any (a package registry token, a NODE_ENV). Secrets belong here, never in the repository.
  7. Optionally set Persistent storage to a folder whose contents must survive redeploys, such as /data for an SQLite database or uploads. Leave it empty for stateless apps.
  8. Choose a package, fill in a Display name, click Deploy app and complete the payment.

2. The first build

The app page shows a Build card. The build fetches your branch, detects the language and builds an image. If the repository contains a Dockerfile, that is used as is; otherwise the build picks a recipe from the files it finds: package.json, requirements.txt or pyproject.toml, go.mod, Gemfile, composer.json, and so on.

Click View logs to follow it live. The log is split into three stages, fetch, prepare and build; a failure names the stage and shows the last lines, which is usually enough to see the missing dependency or the command that failed.

Once the build succeeds the app starts, gets its hostname and a TLS certificate, and the card shows Build succeeded. Until the first successful build there is nothing to serve, and the card says so.

3. Deploying changes

Push to the branch. Within seconds the Build card shows a new build for that commit, with the short commit hash in its status. For apps without persistent storage the old version keeps serving traffic until the new image is ready; apps with a volume stop briefly while the new version takes the volume over. If you push again while a build is running, the running build is cancelled and the newest commit wins.

Other ways to roll:

  • Rebuild builds the current branch head again without a new commit, useful after changing build variables.
  • Replace source switches the app to an uploaded archive instead of GitHub; Download source gives you the exact tree of the current build.
  • Build history lists every build with its outcome, so you can see what was deployed when.

Changing environment variables or the port in the Configuration card restarts the app with the new values; it does not need a rebuild. Build-time variables do, so change them and click Rebuild.

When the build fails

The log tells you where. The common ones:

  • No recipe found: the repository root has none of the files the detector recognises, or the app lives in a subfolder. Add a Dockerfile, or move the app to the root.
  • A dependency install fails: the lockfile and manifest disagree, or a private package needs a token. Fix the lockfile, or add the token as a build-time variable.
  • The app builds but never becomes ready: it listens on a different port than the one you set, or it binds to localhost instead of all interfaces. Bind to 0.0.0.0 and match the port.
  • The app crashes at start: a missing runtime environment variable, most of the time. The Logs & diagnostics card shows the stack trace.

Good to know

  • The GitHub App only needs read access to the repositories you grant it. Revoking it on GitHub stops future deploys; the running app is unaffected.
  • One repository can back several apps, for example main for production and staging for a test instance.
  • You can also push the image yourself and let the panel run it instead; see Deploy any Docker image with Container App. Rolling that out from your own CI is covered in Automate the panel with API keys and the CLI.

Ready to try it?

Do you need help?

If something in this guide does not work for you, send us a message and we will help you out.

Contact us