Skip to content

Integrations and repositories

Source-built applications (kind: Application) need three things on a fresh installation before the first deploy:

  1. The GitHub integration, configured once on the installation by the operator. Two modes are supported: a Personal Access Token (recommended) or a GitHub App.
  2. Your own user connection to GitHub, once per Flui user. In PAT mode you paste your own classic PAT. In App mode you install the App on your account or organisation.
  3. The repository itself, imported into your Flui account.

Two CLI topics cover this, and they answer different questions.

flui integration …: is Flui connected to GitHub? setup github and reset github are the operator’s once-per-installation commands. connect github is the once-per-user one. status github and list show where you stand, and ghcr-pat set|status|revoke manages the credential that pulls the images Flui builds.

flui repo connect | list | disconnect: which repositories may be deployed? This is a separate step, and the one people forget. Connecting GitHub lets Flui see your repositories but does not import any of them. A repository has to be connected before flui deploy touches it, and disconnecting it stops future deploys without changing anything on GitHub. See Repositories.

The dashboard has the same flows under Apps → Repositories → GitHub setup. CatalogApps (kind: CatalogApp) skip every step: they pull a pre-built image from a public registry, with no source repository on the install side.

Choosing a mode

Personal Access TokenGitHub App
Identity used to talk to GitHubYour own userBot identity owned by the App
Per-user setupPaste a classic PATInstall the App on your account / org
Can register webhooksYes, the PAT grants admin:repo_hookYes, with the App
Org policies that block PATsMay block the PAT entirelyUnaffected
Container registry (GHCR)The same PAT covers cloning and pulling imagesNeeds a separate per-user PAT (see GHCR PAT)
Recommended forMost installations, including your ownTeams that want one shared bot identity

On an installation that keeps images in its own registry (see Where the image is kept), neither mode needs a token for images. The GitHub App then needs nothing beyond the one-click install, and flui integration list shows the GHCR token as not needed.

A Personal Access Token is the recommended path: nothing has to be registered on GitHub, one token covers repositories and images, and each person connects in a minute. Choose a GitHub App when a team wants one shared identity instead of personal tokens, or when an organisation’s policy blocks personal access tokens.

Registering webhooks does not by itself make a push go live. See A push does not redeploy on its own.

A push does not redeploy on its own

GitHub calls Flui back when a build finishes, in both App mode and PAT mode. What Flui does with that call depends on the application.

An application’s first deploy always goes live once the build succeeds.

For an application that is already running, a later push redeploys automatically only if that application has auto-deploy on push turned on, and by default it does not. Otherwise the finished build is recorded as an available image and nothing rolls out. flui app versions <app> marks that image unreleased, and you deploy it yourself with flui app redeploy <app> <target> (a tag, a digest, or --build <id>). See Release management in the applications reference.

The setting is per application, not installation-wide. flui app auto-deploy <app> shows it, and --on or --off changes it; see flui app auto-deploy. If a push did not roll out, check flui app versions for an unreleased build waiting for you.

Setup (operator, once per installation)

flui integration setup github

Interactive setup that walks the operator through either mode. Admin only.

Terminal window
flui integration setup github
flui integration setup github --headless # print URLs instead of opening a browser

If the integration is already configured, the command asks before overwriting. Run flui integration reset github first if you want a clean slate.

The command opens GitHub’s token-creation page with the required scopes pre-filled, then validates the token against GitHub before saving it. Missing scopes are reported inline, so you know what to fix.

Scopes requested:

  • repo: clone and push private repositories
  • workflow: commit .github/workflows/flui.yml on first deploy
  • user:email: identify the user
  • admin:repo_hook: register webhooks
  • write:packages, read:packages, delete:packages: push, pull and clean up images on GHCR

The same token covers the repository side and the GHCR side, so PAT mode has no separate GHCR step.

A fine-grained token works too, and can be limited to the repositories you choose. Give it, on those repositories: Contents and Workflows Read and write, Secrets Read and write, Actions Read-only. It cannot reach GitHub’s container registry, so it is enough only on an installation that keeps images in its own registry (see Where the image is kept). Elsewhere use a classic token with the scopes above.

GitHub App branch

The command builds a GitHub App manifest, opens GitHub with the App name and all permissions pre-filled, and waits for you to confirm. When you click Create, GitHub redirects back to the API, which exchanges the temporary code for the final App credentials and stores them.

The command asks for:

FieldNotes
App nameMust be unique across GitHub. Defaults to flui-<hostname>.
Flui public URLBase URL of this Flui API as reachable from github.com. Callback, manifest redirect and (if enabled) webhook URL are all derived from this. For local development behind a tunnel, use the tunnel URL.
Enable webhooks for deploy-on-push?Off by default. Whether a push redeploys a running application is decided per application; see A push does not redeploy on its own.
Allow install on other accounts / organizations?Off by default (only the owner account can install). Turn on if Flui needs repos under multiple accounts or orgs.

After you confirm, the credentials (App ID, slug, Client ID, Client Secret, Webhook Secret, private-key PEM) are stored in Flui, with nothing to copy and paste.

Equivalent dashboard flow

Open Apps → Repositories → GitHub setup in the dashboard for the same choice of two cards (PAT, or App via manifest). The dashboard polls the API the same way and the resulting configuration is identical. Under the App card, an “I already have a GitHub App” disclosure lets you enter existing App credentials instead of running the manifest flow.

User connection

flui integration connect github

The command asks the installation which mode it uses and follows it.

In PAT mode it opens GitHub’s token page with the required scopes, asks for your classic PAT, validates it and connects it. In a script, pipe the token in with --stdin instead of typing it, so it never appears on the command line. If you are already connected it says so, and --stdin replaces the token.

In App mode it opens the browser so you can install the Flui GitHub App on your account or organisation, and waits for the local callback. The same round trip also performs the OAuth grant your user needs to commit .github/workflows/flui.yml on first deploy.

Terminal window
flui integration connect github
printf %s "$GITHUB_TOKEN" | flui integration connect github --stdin # PAT mode, scripted
flui integration connect github --headless # print URLs instead of opening a browser

If the integration is not configured, the command exits with a hint that an administrator must run flui integration setup github first, instead of showing the raw API error.

FlagEffect
--stdinPAT mode: read the token from standard input rather than prompting.
--headlessPrint the URL instead of opening one. Useful over SSH.

The callback uses the same ports as flui auth login: 8899, then 8900, 8901, 8902 and 8910.

flui integration list

Lists the third-party integrations configured for your account, whether each is connected, and the state of the GHCR PAT.

Terminal window
flui integration list

github is the only provider the topic accepts.

Status and health

flui integration status github

Shows the active mode (App or PAT), runs a live health check against GitHub (administrators see the result) and, in PAT mode, prints your own user connection state.

Terminal window
flui integration status github

Sample output (App mode):

Instance configuration
Mode: github_app
App slug: flui-acme
Health: ✔ App auth ok — 2 installations

Sample output (PAT mode):

Instance configuration
Mode: pat
Health: ✔ PAT mode enabled (per-user credentials)
Your connection
Authenticated: @acme-dev
Scopes: repo user:email admin:repo_hook write:packages …

When the health check fails (App deleted on GitHub, credentials revoked, network unreachable), the output flags it and the dashboard shows a banner with the same information.

Reset

flui integration reset github

Removes the instance-wide GitHub configuration and every per-user token and App installation Flui has on file. Use it to switch modes (from App to PAT or back) or to start over after a bad registration. Admin only.

Terminal window
flui integration reset github # type "reset" to confirm
flui integration reset github --yes # skip the confirmation (CI / scripts)

The App on github.com is not uninstalled. Uninstall it there if you want to clean up the GitHub side too.

After a reset, run flui integration setup github to configure a new integration. Every user then reconnects.

GHCR PAT (App mode only)

In App mode, the App’s bot token cannot pull container packages from ghcr.io (see community discussion #34084), so each user stores a small classic PAT scoped only for packages. PAT mode skips this step, because the main PAT already grants the package scopes.

flui integration ghcr-pat set

Saves or replaces the GHCR PAT for your user.

Terminal window
flui integration ghcr-pat set
flui integration ghcr-pat set --headless # print the token-creation URL

The command opens GitHub’s token-creation page with read:packages and delete:packages pre-filled. The first is required (or write:packages instead); the second lets Flui clean up old images. Paste the token at the masked prompt and pick an expiry, 90 days by default. Flui warns you 14 days before it expires.

flui integration ghcr-pat status

Shows the stored token’s login, scopes, days until expiry, when it was rotated and when it was last verified. Status values: VALID, EXPIRING_SOON, EXPIRED, INVALID, UNKNOWN_EXPIRY. With no token stored it says not configured.

Terminal window
flui integration ghcr-pat status

flui integration ghcr-pat revoke

Deletes the stored PAT from Flui. It does not revoke the token on GitHub; do that at https://github.com/settings/tokens. After revoking, flui deploy refuses to run until a new PAT is set.

Terminal window
flui integration ghcr-pat revoke
flui integration ghcr-pat revoke --yes

The installation’s image registry

These commands apply to an installation created with --image-registry flui, which keeps built images in a registry of its own. They need the permission to manage integrations.

flui registry storage status

Shows where the registry keeps images, the space they take and the applications that take the most, and the bucket it is connected to.

Terminal window
flui registry storage status
flui registry storage status --measure # measure now instead of showing the last measurement
flui registry storage status --json

The space is measured every 30 minutes. The total counts each layer once, however many applications share it; the size shown for an application counts its shared layers too. Administrators get an alert when the space passes a threshold: 80% of the volume, or 50 GiB on a bucket, which never fills but is paid by the GiB.

flui registry storage connect

Connects the registry to a bucket. On an installation created with --image-registry-storage s3, the registry moves to it right away.

Terminal window
flui registry storage connect scaleway --region fr-par
flui registry storage connect s3 --provider ovh_object_storage \
--endpoint https://s3.gra.io.cloud.ovh.net --region gra \
--bucket flui-registry --access-key <access key id>

scaleway needs nothing else: Flui uses the Scaleway connection the installation already has to create a project for the registry, a bucket in it, and a key whose only permission is object storage in that project, so it cannot open your backup buckets. It can take a few minutes, while Scaleway applies the new permissions.

s3 connects a bucket of your own. Give it a key that reaches only that bucket. The secret key is asked at a masked prompt, or read from standard input with --stdin. Flui writes and deletes a test file before it accepts the bucket.

Images already in the registry are not copied to the new bucket. An application whose image is not there anymore needs a new build before it can start somewhere else.

flui registry storage list

Lists the buckets the registry has been connected to: the one in use and the ones it replaced.

flui registry storage remove <id>

Removes a bucket the registry no longer uses. A bucket Flui created is deleted with the images in it, together with the project and the key made for it. A bucket of your own is only forgotten, and what it holds stays. The bucket in use cannot be removed.

Terminal window
flui registry storage remove 3f2c9a1e-…
flui registry storage remove 3f2c9a1e-… --yes

Admin diagnostics

flui integration installations

Lists every GitHub App installation Flui tracks, which helps when diagnosing a stale or duplicated record. It shows the numeric installationId that remove-installation needs.

Terminal window
flui integration installations

flui integration remove-installation <installationId>

Removes an installation record from the Flui database. It does not uninstall the App on GitHub. Uninstall it there first, otherwise the next webhook creates the record again.

Terminal window
flui integration remove-installation 12345678
flui integration remove-installation 12345678 --yes
FlagEffect
-y, --yesSkip the confirmation prompt.

Get the ID from flui integration installations.

Repositories

flui repo connect [<owner/repo>]

Imports a repository into your Flui account so flui deploy can deploy it. Pass the full owner/repo slug, or leave it out for an interactive picker over the repositories the connected integration can reach.

Terminal window
flui repo connect acme/my-app
flui repo connect # interactive picker

The repository must be visible to whichever side is connected: the GitHub App installation in App mode, or the PAT’s permissions in PAT mode. If the picker does not show it, run flui integration connect github again and add the repository on the GitHub install page (App mode), or issue the PAT again with broader access (PAT mode). flui deploy on a repository that is not imported is refused with Repository "<owner>/<repo>" is not connected to your account. In a terminal, if your credential reaches the repository, it offers to connect it on the spot and retries. Otherwise it tells you to run this command.

flui repo list

Lists the repositories already connected to your Flui account.

Terminal window
flui repo list
flui repo list --output json
FlagDefaultEffect
-o, --output text|jsontextOutput format.

flui repo disconnect <owner/repo>

Removes the repository from your Flui account. It requires admin privileges and asks for confirmation; pass -y, --yes to skip the prompt. The repository on GitHub is not touched.

Terminal window
flui repo disconnect acme/my-app
flui repo disconnect acme/my-app --yes

A disconnected repository cannot be deployed until you connect it again with flui repo connect.

Reading and deploying from the map

Two more commands answer a different question from the three above. Instead of whether a repository is connected, they show what it says about itself and whether it can be deployed as it stands. The full model is in How Flui reads a repository.

flui repo map show <repository>

Reads a connected repository without cloning it, refuses symlinks, and reports the limits it applied to the read. It prints the deployable units, the services they want, the variables they need, blockers, caveats, open questions, a verdict, and the flui.yaml Flui would render for each unit. Every fact comes with its own file:line and how confident Flui is in it. The command is read-only: nothing is deployed, provisioned, written or committed.

Terminal window
flui repo map show acme/shop
flui repo map show acme/shop --branch develop
flui repo map show acme/shop --unit api
flui repo map show acme/shop --output json

<repository> takes owner/repo, a full GitHub URL, or the repository’s own id.

FlagEffect
-b, --branch <ref>Git ref to read. Defaults to the repository’s default branch.
-c, --cluster <name|id>Weigh the map against this cluster. Half the verdict is capacity, so a cluster is always chosen, automatically when there is only one.
-u, --unit <id>Show only this unit (its id, . for the repository root).
-o, --output text|jsonjson prints the whole response, untouched.

The command has no client-side timeout. A large repository takes a while to read, and a client that gave up before the server did would report a failure that never happened.

flui repo map apply <repository>

Acts on the map. Flui creates its own branch, flui/deploy-<sha7>, at the exact commit the map was read from, and adds one commit to it with a rendered flui.yaml and a build workflow per unit. That commit starts the builds. Flui reads your branch and branches from it, but never writes to it.

Terminal window
flui repo map apply acme/shop
flui repo map apply acme/shop --unit api --unit web
flui repo map apply acme/shop --branch develop --yes
FlagEffect
-b, --branch <ref>The branch to read and cut from. Defaults to the repository’s default branch. Never written to.
-c, --cluster <name|id>Cluster the applications are created on.
-u, --unit <id>Apply only this unit; repeat for several. Without it, every rendered unit is applied.
-y, --yesSkip the confirmation prompt.
-o, --output text|jsonOutput format.

Run flui repo map show first. An apply is refused when the verdict is blocked, insufficient_capacity or not_assessed. Read what the map objected to instead of spending your repository’s Actions minutes to reach the same conclusion.

If a unit’s manifest declares deploy.services, that service is installed from the catalog and Flui waits for it to reach RUNNING before anything is committed to GitHub. The wait takes minutes, which is why this command, like flui repo map show, sets no client-side timeout of its own.

First-deploy flow, end to end

For an Application repository on a fresh installation, the operator runs:

Terminal window
flui auth login # OIDC against the installation
flui integration setup github # one-time: configure App or PAT

Then every user runs, in PAT mode (the recommended one):

Terminal window
flui auth login # OIDC, once per machine
flui integration connect github # paste your classic PAT
flui repo connect acme/my-app # import the repo
flui deploy # build via GitHub Actions, roll out

The same PAT covers cloning and GHCR pulls, so there is no separate image-registry step. On a single-user install the operator already connected their PAT during setup, so only the last two lines remain.

In App mode, every user runs instead:

Terminal window
flui auth login # OIDC, once per machine
flui integration connect github # install the Flui App on your account
flui integration ghcr-pat set # required for the cluster to pull built images
flui repo connect acme/my-app # import the repo
flui deploy # build via GitHub Actions, roll out

After the first deploy of a repository, later rollouts need only flui deploy. Replace your PAT before it expires by piping the new one to flui integration connect github --stdin (PAT mode), or rotate the GHCR PAT with another flui integration ghcr-pat set (App mode).