Files
sencho/docs/tutorials/connect-a-git-source.mdx
T
Anso de7ecee497 docs: tutorials batch 1 (#1656)
* docs: scaffold Tutorials tab and write enroll-a-remote-node

Adds the Tutorials tab to docs.json with 15 stub pages across three
groups (Fleet & nodes, Deploy & automate, Secure & integrate), and
writes the first full tutorial: enrolling a remote node via Pilot
Agent mode, verified end to end against a live control instance and
a second host running an existing Jellyfin Compose stack.

* docs: write Schedule an Operation tutorial

* docs: fix MDX parse error in Schedule an Operation tutorial

* docs: write Set Up SSO with Custom OIDC tutorial

Registers an OAuth client in a self-hosted identity provider (Keycloak
worked example), configures Sencho's Custom OIDC settings, tests the
connection, and verifies a real end-to-end login with auto-provisioning
from two independent surfaces.

* docs: drop unused SSO tutorial screenshot

sso-settings-empty.png isn't referenced by the tutorial content.

* docs: write Set Up Fleet Federation tutorial

Migrates a Blueprint-managed workload from one node to another using
pin and cordon, with the confirm-before-mutate rollout in between.
Corrects the published feature page's claim that pin requires the
global admin role; the code gates cordon and pin identically, scoped
to the target node.

* docs: write Create and Approve a Blueprint tutorial

Covers labeling a target node, authoring a stateless Blueprint,
walking through the create-then-approve rollout flow, verifying
from the Deployments tab and the audit log, and recovering from a
port-conflict deploy failure. Cross-links with Move a Blueprint
Deployment to a New Node in both directions.

* docs: write Automatically Patch a Stack With an Auto-Update Label tutorial

* docs: write Configure Auto-Heal Policies tutorial

Adds the full step-by-step content for the Configure Auto-Heal Policies
stub: an nginx+redis scenario stack, adding a service-scoped policy,
and a live verification that breaks a container's healthcheck,
confirms the policy restarts it, and recovers it.

* docs: write Set Up Deploy Enforcement tutorial

Covers configuring a block-on-deploy scan policy against a stack running
a deliberately outdated nginx image, reading the block dialog, and
overriding it as an admin with the bypass confirmed in the audit log.
Includes a stack-pattern mismatch as the most likely first-time failure.

* docs: write Configure Environment Guardrails tutorial

Covers the Block deploy on missing required env vars guardrail end to
end: deploy a Postgres stack with a required password, enable the
guardrail, watch a real update get refused with a named-variable
message, fix it, and verify from the Activity and Environment tabs.

* docs: write Deploy a Stack Automatically From Your CI Pipeline tutorial

* docs: write Catch and Fix a Container That's Drifted From Its Compose File tutorial

Covers reading a real Drift finding after an out-of-band container
change and resolving it by redeploying through Sencho.

* docs: write Connect a Git Source tutorial

* docs: write Push a Shared Environment File to Every Node tutorial

Writes the Fleet Secrets tutorial: create a bundle, target nodes by
label, read the push preview/results, verify via the audit log, and
recover from a stack-name typo. Removes the three unwritten
placeholder stubs (RBAC, Sencho Mesh, private registries) that had no
scheduled content.
2026-08-08 01:49:21 -04:00

100 lines
7.7 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 diff, 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 diff Sencho builds against what is on disk, and applying it, which both writes the new file 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, the three webhook-driven apply modes, or multi-file compose sources; see the [Git Sources](/features/git-sources) feature page for all of that.
## 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 panel">
Open the `marketing-site` stack and select **Git Source** in the editor toolbar. The panel opens empty, since nothing is linked yet.
<Frame>
<img src="/images/tutorials/connect-a-git-source/git-source-panel-empty.png" alt="Empty Git source panel for the marketing-site stack, showing blank Repository URL and Branch fields defaulted to main, a compose.yaml entry marked primary in Compose files, Public (no auth) selected under Authentication, and Review only selected under Apply behavior." />
</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 **Branch** on its default, `main`, unless your repository uses a different 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 panel with a Repository URL filled in 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." />
</Frame>
Leave **Authentication** on **Public (no auth)** for a public repository, and **Apply behavior** on **Review only**, the safest default: a pull only stages a diff for you to review, it never writes or deploys on its own. Select **Save**. Sencho runs a reachability check against the repository before persisting anything; if that check fails, nothing is saved and the panel reports why.
</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 branch you configured.
Back in the Git Source panel, select **Pull now**. Sencho fetches the branch's current commit and opens a side-by-side diff against what's on disk.
<Frame>
<img src="/images/tutorials/connect-a-git-source/pull-preview-diff.png" alt="GIT · PULL PREVIEW dialog for marketing-site, showing a Monaco side-by-side diff with the on-disk compose.yaml on the left and the incoming commit on the right, the only difference highlighted on the image line: nginx:1.27-alpine changing to nginx:1.28-alpine." />
</Frame>
The diff shows only the line that actually changed. If the incoming compose file failed `docker compose config` validation, an error banner would appear here and the **Apply** button would stay disabled; since this pull is clean, Apply is enabled.
</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.
Sencho shows the deploy's progress the same way any other deploy does, ending in a health check on the recreated container.
</Step>
</Steps>
## Verify it worked
Check from two places, since neither alone proves the pull was actually applied and deployed.
**The Git Source panel.** Reopen it. The **Last applied commit** stat strip at the bottom now shows the short SHA of the commit you just pulled, with an updated timestamp.
<Frame>
<img src="/images/tutorials/connect-a-git-source/last-applied-commit.png" alt="Git source panel for marketing-site with Apply behavior still on Review only, and a Last applied commit stat strip at the bottom showing a short commit SHA and a just-now timestamp." />
</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 tab reflects the same change; if it still shows the old tag, reload the page, since the editor buffer doesn't refresh itself after a Git-driven write.
<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 a minute, logs starting from nginx/1.28.3, and the compose editor showing image nginx:1.28-alpine." />
</Frame>
## If something goes wrong
**Saving the source fails with "Repository not found or not accessible," even though the URL is right.** Branch names are case-sensitive, and a typo there (`Main` instead of `main`, for example) surfaces as this same repository-level error rather than a distinct branch error, since Sencho can't always tell a missing branch apart from a missing repository during the reachability check. Double-check the branch name against what your Git host actually shows before assuming the URL itself is wrong.
<Frame>
<img src="/images/tutorials/connect-a-git-source/branch-error.png" alt="Git source panel with Branch set to the incorrect value Main, and a red error toast in the corner reading Repository not found or not accessible." />
</Frame>
## Related
<CardGroup cols={2}>
<Card title="Git Sources" icon="code-branch" href="/features/git-sources">
Multi-file sources, the three webhook apply modes, private-repo authentication, and the full troubleshooting table.
</Card>
<Card title="Deploy a Stack Automatically From Your CI Pipeline" icon="satellite-dish" href="/tutorials/set-up-a-webhook">
Trigger a Git source pull and deploy from CI instead of pulling by hand from the panel.
</Card>
</CardGroup>