Files
sencho/docs/features/stack-management.mdx
T
Anso 0be479100c docs: v1 docs refresh (#966)
* docs(introduction): rewrite intro page and refresh screenshots

Rewrite the Getting Started introduction to reflect the current product:
adds the Mesh, Blueprints, Pilot, Fleet, Resources concepts up front;
restructures capability sections around Stacks, Fleet (now including
Fleet Actions), Mesh, Blueprints, Monitoring, Resources, Security,
Automation, and Pilot/Remote ops; cross-links every claim to the
matching feature page.

Replaces the dashboard hero shot with a fresh capture against the
redesigned cockpit chrome and adds three inline shots (running stack
with anatomy and logs, fleet command deck, resources hub with
reclaim header). All screenshots taken at 1920x900, dark theme,
with node names, usernames, IPs, and home paths neutralized.

Drops outdated claims: stale "190+ templates" count, the
"viewer accounts" RBAC summary, and the "atomic" deployment label
that did not match the actual rollback mechanism.

* docs(introduction): add Federation and Fleet Secrets

Federation has shipped (Admiral) with cordon and pin policy as
operator overrides on the blueprint reconciler. Fleet Secrets is
landing as a Skipper+ tab for versioned env-var bundles encrypted
at rest, with diff preview and target push.

Mirror those in the Run-one-machine-or-many bullet list and in the
Tiers paragraph so the introduction matches the current product.

* docs(introduction): re-shoot screenshots against v0.72.0 production

Re-capture all four introduction screenshots from the upgraded
production node so the fleet view shows the current full tab strip
(Overview / Snapshots / Status / Deployments / Traffic / Federation
/ Fleet Actions / Secrets) instead of the older Overview / Snapshots
/ Status only. Same 1920x900 dark-theme capture and the same PII
scrub applied (node names, usernames, IPs, home paths neutralized).

* docs(quickstart): rewrite around v0.72.0 cockpit and add screenshots

Replaces the bare install snippet with a five-minute walkthrough that
matches the redesigned UI. Leads with a docker-compose.yml block (the
bare docker run command is collapsed in an Accordion), keeps the 1:1
path rule, and adds two new sections that show the user what happens
on first boot.

Adds two screenshots at 1920x900 dark theme:
- setup-cold-start.png: the Cold start card with Username, Password,
  Confirm password fields, and the Initialize console button.
- dashboard.png: the post-sign-in dashboard captured against v0.72.0
  with the full top nav (Home, Fleet, Resources, App Store, Logs,
  Auto-Update, Console, Audit, Schedules) and the populated Stack
  health table sorted by load.

Where-to-next now uses CardGroup cols=2 to match the introduction
page's pattern.

* docs(configuration): align env var reference with current backend

Bring docs/getting-started/configuration.mdx up to date with the
v0.72.0 backend:

- Remove PORT from the optional env vars table. The listen port is
  hardcoded to 1852 in backend/src/helpers/constants.ts and is never
  read from the environment. Replace it with a Listen port section
  that explains the fixed port and host-port remapping.
- Document API_RATE_LIMIT (default 200) and API_POLLING_RATE_LIMIT
  (default 300), both applied in production only.
- Note the /app/compose fallback default for COMPOSE_DIR while still
  pointing readers at the 1:1 path rule.
- Point the SSO env var section at the new SSO Quickstart page and
  keep the SSO feature reference as the deeper dive.
- Tighten First boot and cross-link to Quickstart so the screenshot
  is not duplicated.
- Add a Where to next CardGroup matching the refreshed Introduction
  and Quickstart pages.

Drop stale PORT=1852 and JWT_SECRET=your-secure-jwt-secret-here
lines from .env.example so the example no longer contradicts the
docs (PORT is hardcoded, JWT_SECRET is auto-generated and persisted
to the database during initial setup).

* docs(configuration): replace em-dash-substitute hyphens in prose

Three sentences used ` - ` (space-hyphen-space) as an em-dash
substitute. Replaced with the punctuation that fits each case:

- "How Sencho organizes your compose directory": semicolon between
  the two related clauses.
- Data directory Warning: parentheses around the parenthetical
  insertion.
- 1:1 path rule explanation: comma before the contrastive clause.

Heading slugs and YAML code-block comments are unchanged.

* docs(sso): refresh setup guide and drop misleading "one-click" wording

Brings the SSO Setup Guide in line with how SSO actually works in the
current build, and corrects misleading copy across both SSO docs pages.

- Setup Guide: explains the env-var-seeds-once / DB-is-authoritative
  config model up front, replacing per-section "Restart Sencho"
  wording that implied a restart was always required.
- Setup Guide: promotes the per-provider Test Connection button out
  of the LDAP-only paragraph into a generic intro callout, and adds
  a self-signed LDAPS tip.
- Setup Guide: notes that all OIDC providers accept a *_DISPLAY_NAME
  override for the login button label, and adds a commented LDAP TLS
  toggle to the full compose example.
- Setup Guide: adds two screenshots of the redesigned Settings > SSO
  panel (overview + LDAP card expanded with form).
- Both pages: replaces "one-click presets" / "one-click configuration"
  with "preset providers". The Skipper-tier presets still require an
  OAuth app provisioned in the provider's console; what they actually
  buy is provider-aware defaults and a branded login button. The old
  wording overpromised.

* docs(features-overview): regroup catalog and add 17 missing features

Restructure the Features Overview into the same six groups the docs
sidebar uses (Stacks & Deployments, Observability, Fleet & Multi-Node,
Security & Identity, Automation, Platform) plus a short Reference tail.

Add catalog entries for 17 shipped features that the previous overview
never mentioned: Stack Activity, Stack File Explorer, Deploy Progress,
Deploy Enforcement, Blueprints, Git Sources, Global Search, Pilot Agent,
Sencho Mesh, Fleet Federation, Fleet Actions, Fleet Sync, Fleet Secrets,
Two-Factor Authentication, CVE Suppressions, Auto-Heal Policies, Stack
Sidebar.

Fix two factual inaccuracies:
- Fleet View blurb wrongly gated search, sort, filter, and stack
  drill-down behind Skipper. The deep-dive is explicit that those are
  available on every tier; only the bulk Update All action inside the
  Node Updates modal is paid.
- Auto-update entry was titled and described as a scheduling system.
  The deep-dive page is the Auto-Update Readiness board (risk tags,
  changelog previews, rollback targets); the scheduler lives under
  Scheduled Operations.

Add three hero screenshots captured from production at 1920x900,
illustrating the redesigned cockpit visual language: Home dashboard,
stack anatomy, and fleet topology.

* docs(stack-management): refresh page around v0.72.0 cockpit and add screenshots

Updates the Stack Management page to match the current UI: sidebar with
filter chips and label groups, bulk mode, restructured kebab menu,
two-tab anatomy panel, and three-source New stack dialog (Empty, From
Git, From Docker Run).

Adds sections for Filter chips, Pinned and label groups, and Bulk mode.
Restructures the Stack context menu around the inspect, organize,
lifecycle, and destructive groups with their keyboard shortcuts.
Documents the From Git tab and cross-links Git Sources for the full
sync flow.

Replaces every existing screenshot with fresh captures from the current
UI and adds eight new captures for the new sections. Cross-links Stack
Activity, Stack Labels, Stack File Explorer, Compose Editor, Atomic
Deployments, Scheduled Operations, Auto-Heal Policies, Auto-Update
Policies, and Alerts and Notifications for features documented on
their own pages.

* docs(stack-activity): refresh page around v1 cockpit and recapture screenshots

Realign the page with the current Anatomy panel tab strip and the
StackActivityTimeline component:

- Frame the Activity tab as a sibling of Anatomy under the right-hand
  panel, with files/edit actions belonging to the strip.
- Expand the category guidance: list the five iconized categories and
  call out that other stack-scoped notifications (deploy failure,
  available image updates, auto-heal triggers, monitor alerts, scan
  findings) flow into the timeline with a generic icon.
- Tighten the actor-attribution rule to match the component: omitted
  for events without an actor and for system-driven events.
- Add the day-format example to the relative-time row.
- Recapture both screenshots from a populated stack (Today + Yesterday
  + Earlier with three distinct icons) and an empty stack.
- Convert troubleshooting blurbs to H3 for anchor links and consistency
  with the v1-refresh sibling pages.

* docs(stack-activity): wrap troubleshooting entries in Accordion blocks

Match the foldable troubleshooting pattern established by
docs/features/deploy-progress.mdx so the page stays compact and
readers can scan to their issue. This is the canonical formatting
for the /features section's troubleshooting blurbs going forward.

* docs(editor): refresh page around v1 cockpit and recapture screenshots

Rewrites the page around the dual-mode right panel (Anatomy by default,
Monaco when the user clicks edit), the redesigned Command Center action
bar, the new container row layout with status badges and live stats, the
Structured / Raw terminal logs toggle, the Git Source toolbar button, and
the opt-in diff preview. Drops the obsolete persistent embedded terminal
section. Preserves the #diff-preview-before-save and #log-viewer anchors
referenced from settings.mdx and global-observability.mdx. Replaces
editor-overview.png and container-exec-modal.png with fresh captures
against v0.72.0 production at 1920x900 dark theme; renames container
-actions.png to containers-list.png; adds command-center.png and
editor-edit-mode.png. PII scrubbed (host paths normalized) and the
compose-diff-preview/diff-modal.png shared asset is left untouched after
visual diff against the live UI showed no chrome change.

* docs(features): wrap troubleshooting accordions in AccordionGroup

Wraps the loose <Accordion> blocks in editor.mdx and stack-activity.mdx
in a single <AccordionGroup> to match the troubleshooting design used
by fleet-federation.mdx. Structural only; no content changes.

* docs(stack-file-explorer): refresh page around v1 explorer and add screenshots

Full rewrite to match the live two-pane Files tab. Replaces the false
'Edit' toolbar flow with the read-only chip + always-on Save model,
fixes the protected-files list (5 names) and dedicated-tab redirect
list (3 names), drops the fabricated 100 MB download cap, and corrects
the upload claim to single file at a time.

Adds sections for New File, Rename, Permissions, the type-to-confirm
protected-file delete flow, the non-empty folder delete confirmation,
the 500-entry tree display cap, and the symlink rendering. Restructures
troubleshooting around <AccordionGroup> + <Accordion> to match
fleet-federation.mdx, and adds two new entries (display cap, 403 on
Community admin write).

Ships nine screenshots captured against v0.72.0 production at 1920x900
in dark theme: overview, two-pane layout, protected-tree-marker,
viewer-edit-mode, new-file-dialog, context-menu-folder, context-menu-file,
permissions-dialog, delete-protected-confirm.

* docs(deploy-progress): rewrite around current modal + capture v1 screenshots

Aligns the page with the v0.72.0 implementation and standardizes the
troubleshooting layout with the rest of the docs refresh.

Setting and gating
- Renames the Settings field to "Deploy progress modal" and quotes the
  current helper text verbatim. Documents that the toggle is off by
  default, lives under Settings > Appearance > Display, is stored in
  localStorage, and syncs across tabs in the same browser.

Modal anatomy
- Names every visible UI string: header verbs, status indicator (with
  the "closes in <n>s" countdown that was previously undocumented),
  empty-body strings, footer toggle that flips between "Raw output" and
  "Hide raw", and the destructive border on ERR rows vs the softer warn
  tint on WARN rows.
- Replaces the vague "after a few seconds" with the actual 4-second
  auto-close timer; documents hover-to-pause and the
  leave-hover-restarts-the-countdown behavior.
- Documents the truncated error message in the failed-state header and
  the manual close-only requirement.
- Notes that the pill is portal-mounted and survives navigation.

Stage badges
- Keeps the 9-badge table but adds an honest note that most lines render
  as LOG because the badges are gated on Compose's "[+]" progress
  prefix, which Compose only emits in TTY mode and Sencho spawns it
  without one.

Entry points
- Splits the supported actions into the four that produce a populated
  structured-log body (Deploy, Update, Install, Git Apply) and the two
  that bypass compose and finish with 0 lines (Restart, Stop). Drops the
  "Down" claim from the user-facing list since no UI control currently
  triggers it; mentions the down route as an automation surface only.

Troubleshooting
- Wraps the existing accordions in an <AccordionGroup> matching the
  pattern used by the editor and stack-activity refreshes. Adds two new
  entries: one explaining the Restart/Stop "0 lines" outcome, one
  explaining the LOG-everywhere case for non-TTY compose output.

Screenshots (six PNGs in docs/images/deploy-progress/, 1920x900, dark
theme, captured against the upgraded production node)
- setting-toggle.png: the Display section with the toggle enabled.
- modal-streaming.png: a real update in flight at 19s, 554 lines.
- modal-succeeded.png: succeeded state with the live closes-in
  countdown visible.
- modal-raw-output.png: structured rows with the Raw output panel
  expanded beneath.
- pill.png: minimized pill anchored bottom-center on a stack editor
  view.
- modal-failed.png: failed state with the truncated error in the
  header and ERR rows highlighted.

* docs(resources): refresh Resources Hub page for v1 redesign and feature additions

Rewrite the page to match the shipping UI and replace stale screenshots
with fresh captures of the redesigned chrome.

- Document the admin-only Reclaim hero and clarify the per-tile Sencho-only
  vs. All Docker (includes external) split in Quick Clean.
- Add coverage of the Scan history toolbar button and the per-row severity
  badge plus shield-icon scan dropdown in the Images tab; cross-link to the
  vulnerability scanning page.
- Correct the Volumes column list (no Size column; size lives on the Largest
  5 landing card) and call out admin gates on browse and delete.
- Spell out the List/Topology view-mode toggle and that Create Network is
  admin-only and List-mode only.
- Rewrite the Unmanaged tab section around the project-grouped layout, the
  Select all + Purge Selected (N) admin-only multi-select, and the empty
  state copy.
- Replace screenshots: resources-reclaim, networks-list, create-network,
  network-inspect, network-topology, network-topology-toggle. Add fresh
  resources-volumes-tab and resources-unmanaged-tab captures.

* docs(app-store): refresh page around v1 deploy sheet, scan integration, and registry settings

Rewrites the App Store reference to match the current cockpit:

- Documents the weekly-rotated featured banner picked from the top-5 by GitHub stars and the star-descending grid sort.
- Adds the deploy-sheet structure (breadcrumb, meta line, About panel with Read more) and splits the Advanced tab into Ports, Volumes, Environment variables, Custom variables, and Security subsections.
- Documents the Trivy-gated Security checkbox, atomic vs non-atomic deploys by tier, and the rollback semantics driven by error class.
- Adds a Watching the deploy section linking to the deploy-progress modal.
- Rewrites the Custom registry section against the new two-panel settings layout (Default + Custom) with the URL validation rule and the using default / using custom hint.
- Adds a four-entry Accordion troubleshooting block in the house style.
- Replaces three screenshots and adds two (Advanced tab, Settings registry panel) captured against the production node.

Permissions wording aligns with current backend (admin only); the broader stack:create gate will land in a follow-up fix branch.

* docs(app-store): describe inline port-conflict messaging on deploy sheet

Update the deploy-sheet section to match the visible port-conflict
behavior: the Essentials tab surfaces a Port-conflict warning that
replaces the defaults hint when any default port is already bound, and
the Advanced tab shows an inline "in use by {stack}" message next to
the container port instead of a hover-only tooltip. Refresh the
screenshot alt-text and the troubleshooting Accordion to match.

* docs(app-store): align permissions note with stack:create gate

Pairs with the backend gate swap in fix/templates-deploy-rbac (#986)
which moves POST /api/templates/deploy from requireAdmin to
requirePermission('stack:create'). Updates the Note block under
'Watching the deploy' so the docs match the new behavior: admin and
node-admin can deploy templates from the App Store; viewer, deployer,
and auditor cannot.
2026-05-07 23:44:13 -04:00

383 lines
22 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Stack Management
description: Create, deploy, control, and remove Docker Compose stacks.
---
A **stack** in Sencho is a Docker Compose project: a directory inside your `COMPOSE_DIR` that contains at least a `compose.yaml` (or `docker-compose.yml`) file. Sencho discovers every subdirectory as a stack and surfaces them in the left sidebar.
<Frame>
<img src="/images/stack-management/sidebar-grouped.png" alt="Sencho sidebar showing the stack list grouped by label, with filter chips at the top" />
</Frame>
## Creating a stack
Click **Create Stack** in the left sidebar to open the **New stack** dialog. Pick a source from the tabs at the top:
- **Empty**: start with a blank `compose.yaml` and write it from scratch.
- **From Git**: clone a Git repository so its compose file becomes the stack source. Future webhook pulls keep it in sync. See [Git Sources](/features/git-sources) for the full sync flow.
- **From Docker Run**: paste a `docker run` command and let Sencho convert it to compose YAML.
<Frame>
<img src="/images/stack-management/create-stack-dialog.png" alt="New stack dialog on the Empty tab with a stack name field" />
</Frame>
**Naming rules:**
- Lowercase letters, numbers, and hyphens only (e.g. `my-app`, `nextcloud`)
- No spaces or special characters
- Must be unique; duplicates are rejected
Sencho creates a new directory inside `COMPOSE_DIR` with the chosen seed file. You land in the editor for the new stack and can deploy it from there.
### From Git
The **From Git** tab clones a public or private repository and treats its compose file as the stack's source of truth.
<Frame>
<img src="/images/stack-management/create-stack-git.png" alt="New stack dialog on the From Git tab with repository URL, branch, compose file path, authentication, and apply behavior fields" />
</Frame>
Fill in:
- **Stack Name**: same naming rules as the Empty tab.
- **Repository URL**: HTTPS only. SSH URLs are not supported.
- **Branch**: defaults to `main`.
- **Compose file path**: path inside the repository, defaults to `compose.yaml`.
- **Also sync sibling .env file**: when checked, a `.env` next to the compose file is pulled along with it.
- **Authentication**: pick **Public (no auth)** or **Personal Access Token** for private repos.
- **Apply behavior**: controls what happens on future webhook pulls:
- **Review only**: diffs surface in the sidebar; you apply manually.
- **Auto-write files**: pulls write to disk; you redeploy manually.
- **Auto-deploy**: pulls write and redeploy automatically.
- **Deploy after create**: deploys the stack immediately after the repo is cloned.
Click **Create from Git**. Sencho clones the repo, writes the compose file into the stack directory, and (when **Deploy after create** is checked) runs `docker compose up -d`.
### Convert from a docker run command
If you have a `docker run` command from a README, a forum post, or your shell history, the **From Docker Run** tab turns it into a ready-to-deploy `compose.yaml` without hand translation.
<Frame>
<img src="/images/stack-management/convert-tab-empty.png" alt="New stack dialog on the From Docker Run tab with stack name and command paste fields" />
</Frame>
**How to use it:**
1. Enter a **Stack Name**. Same rules as the Empty tab (lowercase, hyphens, unique).
2. Paste your full command into **Paste your docker run command**. The whole command should be on one logical line; line continuations with `\` are fine.
3. Click **Convert**. Sencho parses the command and shows the resulting compose YAML in a read-only preview below.
4. Review the YAML. If it looks right, click **Create Stack**. Sencho creates the stack directory and writes the converted YAML into `compose.yaml`, then opens the editor on the new stack.
<Frame>
<img src="/images/stack-management/convert-tab-result.png" alt="Converted compose YAML preview shown after a successful conversion" />
</Frame>
**Supported flags:**
The converter handles the flags you reach for most often:
| Flag | Purpose |
|------|---------|
| `-d` / `--detach` | Detached mode (implied by compose) |
| `--name` | Container name |
| `-p` / `--publish` | Port mappings (`host:container`) |
| `-v` / `--volume` | Volumes and bind mounts |
| `-e` / `--env` | Environment variables |
| `--env-file` | Env file reference |
| `--restart` | Restart policy (`no`, `always`, `unless-stopped`, `on-failure`) |
| `--network` | Attach to a named network |
| `--label` | Container labels |
| `--user` | Run as a specific user |
| `--workdir` | Set the working directory |
| `--entrypoint` | Override the entrypoint |
| `--cap-add` / `--cap-drop` | Linux capabilities |
| `--privileged` | Privileged mode |
| `--read-only` | Read-only root filesystem |
| `--tmpfs` | Temporary filesystem mount |
The image tag is taken from the final positional argument (for example `nginx:alpine`). Any trailing command arguments are preserved as the service `command`.
**Troubleshooting conversion:**
<Frame>
<img src="/images/stack-management/convert-tab-error.png" alt="Error toast shown above the New stack dialog when the converter cannot parse the input" />
</Frame>
If the converter cannot produce a usable compose file, the request fails with a clear error toast. Common causes:
- **Not a docker run command.** The input must begin with `docker run` and include an image reference. Free-form text, `docker compose` commands, and shell pipelines are rejected.
- **Unrecognized flag.** The parser supports the flags listed above. Rare flags (such as `--userns`, `--ipc`, custom runtime options) are not recognized. Remove the flag, convert the rest, and add it back by hand in the editor.
- **Quoting issues.** Multi-line commands with embedded quotes can confuse the parser. Paste the command as a single line with escaped quotes, or simplify the command first.
- **Command is too long.** The endpoint accepts commands up to 8192 characters. Longer inputs are rejected; trim anything you do not need and convert in pieces.
When a flag is not supported, paste the partial output into the **Empty** tab as a starting point and fill in the rest by editing `compose.yaml` directly.
## The stack list
All discovered stacks appear in the left sidebar. The list groups stacks by label (Skipper+) and by pinned status, so the most relevant entries surface at the top.
### Status indicator
Each row leads with a two-character status indicator that summarizes the stack's runtime state.
| Indicator | Meaning |
|-----------|---------|
| `UP` (green) | All containers running |
| `DN` (red) | One or more containers exited |
| (blank) | No containers running, status unknown, or the stack has never been deployed |
A small fuchsia dot to the right of the stack name flags that an image update is available. A pulsing brand-color dot on the **Git Source** affordance signals the upstream branch has moved ahead of the working copy.
### Search and filter chips
The search box above the list filters stacks by name. The chip row below it filters by state and is independent of search.
<Frame>
<img src="/images/stack-management/filter-chips.png" alt="Sidebar filter chip row showing All, Up, Down, and Updates with count badges" />
</Frame>
- **All**: every stack discovered in `COMPOSE_DIR`.
- **Up**: stacks where every container is running.
- **Down**: stacks with at least one stopped or exited container.
- **Updates**: stacks with a pending image update.
Each chip carries a live count. Click **Hide filters** in the top-right of the row to collapse the chips when you want a denser list. Search and chips combine: filtering by **Updates** and typing a few characters returns the intersection.
### Pinned and label groups
The list is grouped to keep frequently used stacks reachable.
- **PINNED**: sits at the very top when at least one stack is pinned. Pin a stack with **Pin to top** in the kebab menu (`P` shortcut).
- **Label groups**: each label produces its own collapsible section, header rendered uppercase. Labels are a Skipper+ feature; see [Stack Labels](/features/stack-labels) for color and assignment options.
- **UNLABELED**: bottom group with everything that has no label.
Click any group header to collapse or expand it. The group's stack count appears in the header.
## Stack header
Opening a stack puts identity and state front and center.
<Frame>
<img src="/images/stack-view/identity-header.png" alt="Stack identity header showing breadcrumb, title, state pill, image and digest, and action row" />
</Frame>
The header answers three questions at a glance:
- **What is this?** A breadcrumb (`LOCAL · STACKS · NAME`) and the stack name as the title.
- **Is it healthy?** A state pill to the right of the title reports the live state:
- `running · healthy` (green) when at least one container reports a passing healthcheck.
- `running · unhealthy` (red) when any container reports a failing healthcheck.
- `running · starting` (amber) during the Docker healthcheck start period.
- `running` (green) when no healthcheck is defined.
- `exited` (red) when no containers are up.
- **What does it ship?** A mono line under the title shows the primary image tag and the short image digest, with a copy button to grab the full digest.
The action row to the right of the header keeps everyday lifecycle controls visible. The **More actions** overflow holds Rollback, Scan config, and Delete; the next sections cover both surfaces.
## Container health strip
Below the header, each container in the stack gets a single row that answers "is this piece working, and how do I reach it?" without expanding anything.
<Frame>
<img src="/images/stack-view/containers.png" alt="CONTAINERS section showing a container card with health badge, uptime, port mapping, open link, and CPU, memory, and network stat tiles" />
</Frame>
Each row includes:
- **Health badge.** A colored glyph reports the Docker healthcheck state: `✓` green for passing, `✗` red for failing, `…` amber while the healthcheck start period is in flight. Containers without a `healthcheck:` block show a neutral `✓`.
- **Container name** in mono.
- **Meta line.** Uptime (`up 12 hours`) and the primary port mapping (`8989 → 8989/tcp`).
- **Open link.** When the container publishes a port, an `open ↗` link launches the app in a new tab using the active node's hostname.
- **Live stat tiles.** Three tiles show CPU, memory, and network I/O with a rolling sparkline. The sparkline uses the cyan data color and refreshes roughly every 1.5 seconds.
- **Action icons.** Shortcuts to **View logs**, open a bash shell, and the per-service kebab.
## Logs viewer
The logs area at the bottom of the stack view has two modes. Toggle between them with the segmented control in the top-right of the panel; your choice is remembered for next time.
<Frame>
<img src="/images/stack-view/logs-viewer.png" alt="Logs panel in Structured mode with toolbar, level filter pills, and timestamped INFO log rows" />
</Frame>
**Structured** (default) parses every line into a DOM row with three columns: local time, level badge, and message. Level detection is automatic:
- `err` rows get a red left rail and a subtle rose tint.
- `warn` rows get a warm tint.
- `info` rows render plainly.
The toolbar includes:
- **Following indicator.** A green dot reads `following` while auto-scroll is engaged. Scrolling up stops follow; a `resume follow` link re-engages it and jumps to the bottom.
- **Level filter.** `ALL · INFO · WARN · ERR` pills. The `ERR` pill shows the running error count as a badge.
- **Download.** Exports the current buffer as a plain text file.
The structured viewer holds up to 10,000 lines; older entries are dropped from the top as new ones arrive.
**Raw terminal** keeps the original xterm-based viewer for cases where ANSI art, control sequences, or interactive TTY output matter. Lines include the raw ISO timestamp.
## Anatomy panel
The right column of the stack view is a two-tab panel: **Anatomy** is the read-only summary of what the compose file declares, and **Activity** is the audit log for that stack.
<Frame>
<img src="/images/stack-view/anatomy-panel.png" alt="Anatomy panel with services, ports, volumes, restart, env_file, network, and source rows, plus a footer link for the exposed port" />
</Frame>
The header carries:
- **Anatomy / Activity tabs.** Activity is documented on its own page; see [Stack Activity](/features/stack-activity).
- **Files** button. Opens the in-stack file explorer; see [Stack File Explorer](/features/stack-file-explorer).
- **Edit** button. Slides the Monaco editor over the panel for inline compose and env edits.
Each row inside the **Anatomy** tab maps one compose concept to the value it resolves to right now:
- **Services**: Cyan pills, one per key under `services:`.
- **Ports**: `{host} → {container}/{proto}` per service, host port highlighted.
- **Volumes**: `{host-path} → {container-path}` per mount.
- **Restart**: The effective restart policy.
- **Env file**: Filename plus a count of defined variables. If the compose file references a `${VAR}` that the env file does not define and has no `:-default`, the missing name is called out inline.
- **Network**: Derived network name and driver (default `{stack}_default · bridge`).
- **Source**: `git · {host}/{repo}#{branch}` when Git Source is configured, else `local`. The whole row is clickable and opens the Git Source dialog. A pulsing dot appears when upstream has moved ahead of the working copy.
A footer card under the rows surfaces the first published port as a clickable **EXPOSED** link, so you can jump straight to the running app.
If an image update is available for the primary service, an inline banner appears below the rows with the version bump (`27.1.4 → 27.1.5`), risk classification (`safe · patch`, `minor`, or `major · review required`), and an **apply** button that runs the update on this stack. Major bumps show a rose banner and require explicit review before applying.
### Editing compose.yaml
Click **Edit** in the panel header to open the Monaco editor. Tabs at the top switch between `compose.yaml`, `.env` (when one exists), and **Files** (the stack directory tree). The save split-button reads **Save & Deploy** by default; its dropdown also offers **Save Only** and **Discard Changes**. Close the editor to return to the anatomy view; unsaved changes are kept in the buffer until you discard them. See [Compose Editor](/features/editor) for autocomplete, schema validation, and Git Source workflow.
## Deploying a stack
Select a stack and click **Start** (or **Restart** when it's already running) in the stack header. This runs `docker compose up -d`, pulling images if needed and creating or recreating containers.
For deploy progress, error surfacing, atomic backups, and rollback, see [Atomic Deployments](/features/atomic-deployments).
## Controlling a running stack
The stack header groups actions by frequency of use. The most common action is the filled cyan button on the left, everyday secondaries sit next to it, and destructive or occasional actions are tucked behind the **More actions** overflow.
**When running:**
| Placement | Button | Command | What it does |
|-----------|--------|---------|--------------|
| Primary | **Restart** | `docker compose restart` | Restarts all containers in the stack. |
| Secondary | **Stop** | `docker compose stop` | Stops containers without removing them. State is preserved. |
| Secondary | **Update** | `docker compose pull` + `up -d` | Pulls the latest image tags and recreates containers. |
| Overflow | **Rollback** | Restores backup | Reverts compose and env files to the pre-deploy snapshot and redeploys. Only shown when a backup exists (Skipper+). |
| Overflow | **Scan config** | Trivy config scan | Scans the compose file for misconfigurations (Skipper+, admin). |
| Overflow | **Delete** | `down --volumes` + removes files | Stops and removes containers and volumes, then deletes the stack directory. |
**When stopped:**
| Placement | Button | Command | What it does |
|-----------|--------|---------|--------------|
| Primary | **Start** | `docker compose up -d` | Starts the stack. |
| Secondary | **Update** | `docker compose pull` + `up -d` | Pulls the latest image tags and recreates containers. |
| Overflow | **Delete** | Removes files | Deletes the stack directory. |
<Warning>
**Delete** is irreversible. It removes the stack directory, including `compose.yaml`, `.env`, and any bind-mounted files stored there. Back up important files before deleting.
</Warning>
<Note>
Stack directories often contain root-owned files, either because Docker Compose creates them, or because the stacks were originally set up outside of Sencho with `sudo`. Sencho handles this automatically: if a normal deletion fails due to permissions, it uses Docker to clean up root-owned files. No manual intervention is needed in the standard setup.
</Note>
## Bulk mode
Bulk mode lets you run a single lifecycle action across several stacks at once, instead of opening each stack individually.
<Frame>
<img src="/images/stack-management/bulk-action-bar.png" alt="Sidebar with bulk mode active, three stacks selected, and the action bar showing Start, Stop, Restart, and Update buttons" />
</Frame>
**Enter bulk mode** with the toggle next to **Create Stack** in the sidebar, or by pressing `B`. Each stack row turns into a checkbox.
**Select stacks** by clicking rows. The action bar above the list shows `{N} selected` and a **Clear selection** link.
**Run an action** with one of the four buttons:
- **Start**: deploys every selected stack that is currently down.
- **Stop**: stops every selected stack that is currently running.
- **Restart**: restarts every selected stack that is currently running.
- **Update**: pulls the latest image tags and redeploys (Skipper+).
Press `B` again or toggle the bulk mode button to leave bulk mode.
## Controlling a single service
Inside the stack detail view, each container card has a **Service actions** kebab on the right side. Use it to act on that service without touching the rest of the stack.
- **Restart service**: stops and starts all containers for that service.
- **Stop service**: stops all containers for that service. Only shown when the service is running.
- **Start service**: starts all containers for that service. Only shown when the service is stopped or exited.
For services running multiple replicas, the action applies to every replica simultaneously. Sibling services are not affected.
<Note>
The service name in the action must match the `services:` key in your `compose.yaml`. If no containers exist yet for that service, the action will fail with a "service not found" error. Make sure the service is defined in the compose file and has been deployed at least once.
</Note>
## Stack context menu
Click the kebab on a stack row in the sidebar to open its context menu. The menu adapts to the stack's current state; items are grouped by purpose.
<Frame>
<img src="/images/stack-management/context-menu.png" alt="Sidebar stack context menu showing inspect, organize, lifecycle, and destructive groups with keyboard shortcuts" />
</Frame>
**inspect**
- **Alerts** (`A`): open the alert rule editor for this stack. See [Alerts and Notifications](/features/alerts-notifications).
- **Auto-Heal** (`H`): configure auto-recovery for this stack (Skipper+). See [Auto-Heal Policies](/features/auto-heal-policies).
- **Auto-update** (`Enabled` or `Disabled`): toggle automatic updates for this stack (Skipper+). See [Auto-Update Policies](/features/auto-update-policies).
- **Check updates** (`U`): force an image update check now.
- **Open App** (`↗`): open the stack's web interface in a new tab. Shown only when the stack is running and exposes a web port.
**organize**
- **Labels** (``): assign or remove labels (Skipper+). See [Stack Labels](/features/stack-labels).
- **Pin to top** (`P`): pin or unpin the stack from the **PINNED** group at the top of the list.
**lifecycle**
- **Stop** (`⌘.`): shown when running.
- **Restart** (`⌘R`): shown when running.
- **Update** (`⌘↑`): pulls the latest image tags and redeploys.
- **Schedule task**: open the scheduler for this stack (Skipper+). See [Scheduled Operations](/features/scheduled-operations).
- **Deploy** (`⌘↵`): shown when stopped, in place of Stop and Restart.
**destructive**
- **Delete** (`⌘⌫`): admin only.
Items are disabled while another operation is in progress on that stack.
## Scanning for stacks
If you place Docker Compose files directly into the stacks directory (for example, via `scp`, a file manager, or the command line), you can import them without going through the full **Create Stack** flow.
<Frame>
<img src="/images/stack-management/sidebar-actions.png" alt="Sidebar action row with Create Stack button, bulk mode toggle, and scan stacks folder icon button" />
</Frame>
Click the **Scan stacks folder** icon button to the right of **Create Stack**. Sencho scans the configured stacks directory and reports what it finds:
- **New stacks detected**: a success notification lists the newly discovered stack names, and they appear immediately in the sidebar.
- **Stacks removed from disk**: an informational notification lists stacks that are no longer present in the directory.
- **No changes**: a notification confirms no new stacks were found.
<Tip>
Any subdirectory inside your `COMPOSE_DIR` that contains a `compose.yaml`, `compose.yml`, `docker-compose.yaml`, or `docker-compose.yml` file is recognized as a valid stack.
</Tip>
## Troubleshooting
### Service action returns a "service not found" error
The service name used in the action must match the `services:` key in the stack's `compose.yaml`. This error occurs when no running containers match that service name, either because the service was never deployed or because the compose file defines a different name. Verify the service key in your compose file and ensure the stack has been deployed at least once so containers exist for that service.
### Bulk **Update** is missing from the action bar
The bulk **Update** action is a Skipper-tier feature; on Community, it does not appear in the action bar at all. **Start**, **Stop**, and **Restart** are available on every tier.