Files
sencho/docs/tutorials/connect-a-git-source.mdx
T
Anso d07cfc34d1 docs: v1 docs refresh (batch 10) (#2182)
* docs(tutorials): refresh the create and approve a Blueprint walkthrough

Walk the 0.98.0 Blueprint editor, rollout preview, and detail sheet end to end and update the steps to match: the empty-catalog button, the staged label tags, the GitOps authority and evidence block, the approval state shown in the sheet, the audit rows each action leaves, and the real port-conflict recovery. Permissions are described as the stack and node permissions they are, and all seven screenshots are retaken.

* docs(tutorials): refresh the connect a Git source walkthrough

Walk the 0.98.0 Git Source sheet from an unlinked stack to an applied commit and update the steps to match: the toolbar and Anatomy entry points, the Custom CA field, the four apply behaviors, the first-pull Add row in the change plan, the Accepted answer and stage row, and the exact ref error. Add the rule that a linked stack must be detached before its repository or ref changes. All six screenshots are retaken.

* docs(tutorials): refresh the catch and fix drift walkthrough

Walk a real image drift through detection, re-check, redeploy, and dismiss on 0.98.0 and update the text to match: the redeploy confirmation's consequence label, the health gate entry on the Activity timeline, and the Dismiss toast with Undo. Dismissing and restoring a finding is noted as needing the same stack permission as redeploying. All seven screenshots are retaken.

* docs(tutorials): refresh the move a Blueprint to a new node walkthrough

Walk a real migration between a retiring proxy node and the hub on 0.98.0 and update the tutorial to match: the Placement control tab, the toasts on pin and cordon, Cordon in the node details sheet, the Needs confirmation status block before the rollout is confirmed, the transient Completion unknown state after it, and the audit rows including the stack the apply creates. All eleven screenshots are retaken.

* docs(tutorials): refresh the missing required variable guardrail walkthrough

Walk the guardrail on 0.98.0 from a clean deploy to a refused Save & Deploy and Update and back to a healthy update, and update the steps to match: the toast and the Update failed chip that carry the message, the readiness dialog wording, the Environment tab's missing count, the Deploy Guardrails section as it reads now, and the activity entries. Adds the screenshots for the blocked Save & Deploy and the failure chip, and retakes the rest.

* docs(tutorials): refresh the deploy from CI webhook walkthrough

Run the webhook end to end on 0.98.0, including a signed trigger and the newline-signed request the troubleshooting section describes, and update the text to match: the Action list, including Git source sync with a pointer to the Webhooks page, the new form, callout, and Recent executions states, and the uptime and log wording on the redeployed stack. All five screenshots are retaken with the trigger URL and secret replaced by generic values.

* docs(tutorials): refresh the enroll a remote node walkthrough

Enroll a real Pilot agent on 0.98.0 and update the steps to match: the Pilot enrollment dialog and its Done button, the tunnel states after the agent starts, the switcher and Fleet cards beside the nodes already enrolled, the pencil that opens Edit node, and the hub-only view list, which now includes GitOps. The example compose directory is changed to a dedicated media path, and all six screenshots are retaken with host addresses, seal pins, and the token replaced by generic values.

* docs(tutorials): refresh the Custom OIDC single sign-on walkthrough

Run the whole flow on 0.98.0 against a real Keycloak 26 over a private CA and update the text to match: the login button is labelled with the Display Name rather than a fixed phrase, the Active badge and header counts after Save, the stored-secret state after Save, the Log Out path, what happens when the browser is already signed in at the identity provider, and the full list of fields to leave blank. All six screenshots are retaken with the issuer shown as a generic host.

* docs(tutorials): refresh the auto-patch with a label walkthrough

Run the label-driven update schedule twice on 0.98.0 and update the text to match: the Labels submenu states, the Current matches panel that lists every node, the run time and per-node details in the Execution history, the second "all images up to date" run, and the node's Updates chip as the proof the pending update cleared. The Update board example is replaced because other stacks on a real fleet keep it from ever being empty. All eight screenshots are retaken.
2026-10-23 18:29:04 -04:00

105 lines
10 KiB
Plaintext

---
title: Deploy Compose Changes by Pulling From Git Instead of Editing by Hand
sidebarTitle: Deploy compose changes from Git
description: Link a running stack to a Git repository, pull a real commit, review the classified change plan, and deploy it, instead of hand-editing the compose file in the browser.
---
Say `marketing-site` is a small nginx stack you created directly in Sencho, and your team has decided the compose file should live in a Git repository instead, so changes go through a commit and a pull request before they reach the stack. This walks through connecting that already-running stack to a repository, pulling a real commit a teammate pushed, reviewing the classified change plan Sencho builds against what is on disk, and applying it, which both writes the new files and redeploys the container.
This tutorial covers linking an existing stack to a Git source and running one manual pull-review-apply cycle. It doesn't cover creating a brand-new stack directly from a repository, provider hooks, the apply behaviors beyond Review only, polling, suspend, multi-file compose sources, or converting the source onto a Git-managed Blueprint; see [Git Sources](/features/git-sources), [Trigger pulls from Git hosts and CI](/features/git-webhooks), and [Git-managed Blueprints](/features/git-managed-blueprints) for those.
## Prerequisites
- The `admin` or `node-admin` role. Linking a source and running a pull or apply needs the `stack:edit` permission, which `deployer`, `viewer`, and `auditor` do not hold.
- A running stack to link. If you don't have one, select **Create Stack**, name it `marketing-site`, and replace its compose file with:
```yaml
services:
web:
image: nginx:1.27-alpine
restart: always
ports:
- "8098:80"
```
Select **Save & Deploy**. This tutorial's steps and screenshots use this exact stack, so if you use a different name or port, adjust accordingly.
- A public Git repository over HTTPS that you control, with a compose file committed at its root. The screenshots below use a small throwaway demo repository; any repository with the same shape works.
- Available on every tier, including Community; no Admiral requirement.
<Steps>
<Step title="Open the Git Source sheet">
Open the `marketing-site` stack and select **Edit compose**, then **Git Source** in the editor toolbar. (The **Source** row on the stack's Anatomy tab opens the same sheet.) The sheet opens from the right with the repository form, and its header reads **Not linked** since nothing is connected yet.
<Frame>
<img src="/images/tutorials/connect-a-git-source/git-source-panel-empty.png" alt="Empty Git Source sheet for the marketing-site stack, with crumb Stack, marketing-site, Git source, heading Git source, meta Not linked, a Save toolbar button, and Repository fields for URL, Ref, Compose files with compose.yaml as primary, Project directory, Also sync sibling .env file, Authentication with Public (no auth) selected, and Apply behavior with Review only selected among Manual, Review only, Auto-write files, and Auto-deploy." />
</Frame>
</Step>
<Step title="Point it at your repository">
Paste your repository's HTTPS URL into **Repository URL** (for example `https://github.com/your-org/your-repo.git`). Leave **Ref** on its default, `main`, unless your repository uses a different branch, tag, or pinned commit SHA. A **Custom CA certificate (optional)** field appears once the URL is HTTPS; leave it empty for a host like GitHub, and paste the certificate authority's PEM only when your Git server uses a private one.
Select **Browse** to confirm Sencho can actually reach the repository and see its files, rather than trusting the URL is correct. The browser lists every file in the repository; `compose.yaml` is already ticked as the primary compose file, since that name matches the picker's default.
<Frame>
<img src="/images/tutorials/connect-a-git-source/browse-picker.png" alt="Git Source sheet with a Repository URL filled in, Ref main, and the Browse file picker open below the Compose files list, showing a checked compose.yaml and an unchecked README.md fetched live from the repository. The Custom CA certificate field sits below the Authentication choices." />
</Frame>
Leave **Authentication** on **Public (no auth)** for a public repository, and **Apply behavior** on **Review only**, the default: a fetched commit only stages a change plan for you to review, it never writes or deploys on its own. The other choices are **Manual** (Sencho fetches only when you ask), **Auto-write files**, and **Auto-deploy**; see [Git Sources](/features/git-sources) for what each does. Select **Save**. Sencho runs a reachability check against the repository before persisting anything; if that check fails, nothing is saved and the sheet reports why. On success the sheet reloads with a **Pull now** toolbar button and the **Overview**, **Source**, **Automation**, and **Secrets** tabs, and the Overview reads **Never reconciled**: no commit from the repository has been accepted yet.
</Step>
<Step title="Pull the latest commit">
Now make a change the way your team actually would: edit the compose file in your repository (not in Sencho) and push a commit. For this tutorial, bump the pinned tag from `nginx:1.27-alpine` to `nginx:1.28-alpine` and push it to the ref you configured.
Back in the Git Source sheet, select **Pull now**. Sencho fetches the ref's current commit and opens a **Git · Change plan** dialog that classifies each file against what's on disk.
<Frame>
<img src="/images/tutorials/connect-a-git-source/pull-preview-diff.png" alt="GIT · CHANGE PLAN dialog for marketing-site, listing an Add row for compose.yaml, with an unticked Deploy after apply checkbox and Dismiss and Apply buttons in the footer." />
</Frame>
The plan lists only the files that actually change, and files Sencho does not manage are left untouched. `compose.yaml` shows as **Add** here because this is the first commit Sencho takes from the repository: the path becomes Git-managed and the file on disk is replaced with the repository's version. Later pulls list the same file as **Modify**. If the incoming compose file failed `docker compose config` validation, an **Incoming compose failed validation** banner would appear and **Apply** would stay disabled; since this pull is clean, Apply is enabled. **Dismiss** discards the plan without writing anything.
</Step>
<Step title="Apply and deploy in one step">
Tick **Deploy after apply** at the bottom of the dialog, then select **Apply**. This both writes the incoming file to disk and runs `docker compose up -d` against it, so the running container picks up the new tag immediately instead of just staging the file for a later manual deploy.
A toast reads `Changes applied and deployed.` when the deploy finishes.
</Step>
</Steps>
## Verify it worked
Check from two places, since neither alone proves the pull was actually applied and deployed.
**The Git Source sheet.** Reopen it. The header now shows the short SHA of the commit you just pulled and a state of `accepted`, meaning Sencho took that commit as the current generation rather than merely writing its files, and the footer shows when the source was last updated. The Overview answers **Accepted**, with a stage row of **Source accepted**, **Artifact qualified**, and **Runtime synced and healthy**, and no **Review update** button because nothing is waiting. For a few seconds right after a deploy the runtime can read **Artifact unverified** while Sencho identifies the running image; reopen the sheet and it settles. **Evidence** stays collapsed until you open it to see the digests Sencho compared.
<Frame>
<img src="/images/tutorials/connect-a-git-source/last-applied-commit.png" alt="Git Source sheet for marketing-site with the header showing a short commit SHA and the state accepted, an Overview answering Accepted, a stage row reading Source accepted, Artifact qualified, and Runtime synced and healthy, a collapsed Evidence control, an Open in GitOps portfolio link, and a freshness line in the footer." />
</Frame>
**The stack itself.** Reopen `marketing-site`. The container recreated on the new image: a fresh uptime, and its logs now start with `nginx/1.28.3` instead of `1.27.5`. The compose editor reflects the same change, showing `nginx:1.28-alpine`, and the **Source** row on the Anatomy tab now names the repository and ref.
<Frame>
<img src="/images/tutorials/connect-a-git-source/stack-redeployed.png" alt="marketing-site stack page after redeploy, showing marketing-site-web-1 up about two minutes, logs reporting nginx/1.28.3, and the compose editor open with Git Source and Save & Deploy buttons and the image nginx:1.28-alpine." />
</Frame>
## If something goes wrong
**Saving the source fails with "The configured branch, tag, or commit was not found in the repository," even though the URL is right.** Ref names are case-sensitive, and a typo there (`Main` instead of `main`, for example) surfaces as a distinct not-found error rather than a repository error, because Sencho resolves the ref on the remote before fetching. Double-check the ref against what your Git host actually shows before assuming the URL itself is wrong.
**You can't change the repository or branch of a linked stack.** Once Sencho manages the stack's files from Git, editing the source's repository or ref is refused with a message telling you to detach first. Select **Detach** (**Detach and export** renders the effective compose model into a single `compose.yaml`), then link the stack again with the new repository or ref.
<Frame>
<img src="/images/tutorials/connect-a-git-source/branch-error.png" alt="Git Source sheet with Ref set to the incorrect value Main, and a red error toast in the corner reading The configured branch, tag, or commit was not found in the repository." />
</Frame>
## Related
<CardGroup cols={2}>
<Card title="Git Sources" icon="code-branch" href="/features/git-sources">
Multi-file sources, the apply modes, polling, and the troubleshooting table.
</Card>
<Card title="Git hosts and authentication" icon="key" href="/features/git-authentication">
Private repositories over HTTPS tokens or SSH deploy keys, and custom certificate authorities.
</Card>
<Card title="Deploy a Stack Automatically From Your CI Pipeline" icon="satellite-dish" href="/tutorials/set-up-a-webhook">
Trigger a Git source sync from CI when your pipeline already calls Sencho, or use provider hooks on the Git Source sheet when the Git host can post events directly.
</Card>
</CardGroup>