shc update
shc update
Section titled “shc update”update a deployment
Synopsis
Section titled “Synopsis”Update a deployment in place: bump the app version, change variables, add or remove hosts and ports, and rewire integrations. The update runs asynchronously on the daemon, which re-renders and re-deploys the stack with the merged settings.
—var overrides are persistent deployment state: a bare update replays the overrides the deployment was installed (or last updated) with, —var key=value adds or replaces a single key, and a trailing ’!’ (—var key!) drops that key back to the app’s default.
The trailing ’!’ is the removal marker on the spec flags: —host blog.example.com! drops a persisted route, —port 8080! drops a persisted port mapping, and -i sso! disconnects an integration. You remove a thing by the same identity you would use to replace it, and a token carrying more than that identity is refused rather than having the extra silently discarded: a port removal names [conn@]external[/udp] and never a service or container port, so —port 80:web! is refused; a route removal names hostname[/path] and never a selector, so —host web:80@blog.example.com! is refused.
A removal and an add of the same identity on one line is an add: the removal applies to what the deployment already had, and the add lands afterwards, so the order you type them in does not matter.
A removal token that matches nothing is reported and ignored — the rest of the update still applies — because re-running a correct command must not fail. Pass —strict-removals (or set SHC_STRICT_REMOVALS=1) to make it a hard failure instead.
Integrations are persistent deployment state like routes, ports and —var overrides: -i sso=keycloak adds or repoints ONE edge and leaves every other integration on the deployment wired.
An integration edge is identified by its consumer plug, so -i sso!
always names exactly one edge, and a bare removal token is ALWAYS
read as a plug — never as a provider, however much the deployment
happens to hold. That is what makes re-running a removal safe: once
the plug is gone the same token matches nothing and is reported,
instead of quietly meaning something else on the second run. The bare
ADD form is still sugar — -i keycloak is resolved to the plug it
means before anything else happens, and is refused if it cannot be —
so the edge it wires is named by that plug, not by ‘keycloak’.
An edge whose plug could not be resolved (a sidecar written before
this rule, on a node where the provider is not deployed) is named by
its provider reference instead: -i @aws-primary! or
-i postgres@default!, exactly as shc update prints it back to you.
A disconnect drops the edge from the re-rendered compose, from the
deployment’s persisted state and from the integration table, so it
stops being replayed. It does NOT run the provider’s unintegration
teardown — a disconnected keycloak edge leaves its OIDC client in
the realm — and it does not revoke a connection-backed edge’s
minted credential; both still happen only on uninstall.
To remove several, either repeat the flag (—host a.com! —host b.com!) or comma-join them (—host a.com!,b.com!) — —host, —port and -i comma-split, so both spellings arrive as two removals. —var alone has no comma form: a var value may itself contain commas, so —var takes one key per flag, and a removal key carrying a comma, a semicolon or whitespace is rejected rather than read as one strange key. The comma form always works in scripts, in CI and over the Terraform provider, which do not run history expansion at all; it needs SINGLE quotes only when typed at an interactive bash or zsh prompt, where a bang followed by a comma is a history reference and an unquoted line fails loudly with ‘event not found’ without running anything. A ’!’ inside a —var VALUE is never a marker: the token carries an ’=’, so —var password=hunter2! sets the password to hunter2!. When you do quote a marked token, use SINGLE quotes — zsh runs history expansion inside double quotes, so double quotes are the one form that breaks.
On a terminal, running with no —var opens a form prefilled with the deployment’s current variable values; edited fields become overrides and a cancelled form leaves the deployment untouched. Non-interactive runs skip the form. —ha/—no-ha toggle high availability and —gated/—open switch the SSO gate. —from/—ref/—path/—token repoint or refresh the deployment’s git/path source.
shc update <stack> [<version>] [flags]Examples
Section titled “Examples” shc update myblog shc update myblog 2.4.1 --var theme=dark shc update myblog --var theme! shc update myblog --host web:8080@blog.example.com --gated shc update myblog --host blog.example.com! --host old.example.com! shc update myblog --host 'a.example.com!,b.example.com!' shc update myblog --port 8080! shc update myblog -i sso=keycloak shc update myblog -i sso! shc update myblog --cpu web=1.0 --memory web=512Mi --scale web=3Options
Section titled “Options” --acme-provider string override ACME provider (which named CA issues public certs; blank = acme.default) -c, --connection strings rebind a declared connection: name=connection (bare connection ok when the app declares exactly one) --cpu strings per-service CPU quota --disk string disk quota --dns-provider string override DNS provider -e, --environment string environment name (default "default") --force allow --ttl against a protected environment (prod/production) --from string change source (git URL or local path) --gated require Keycloak SSO in front of the app --ha enable HA mode -h, --help help for update --host strings add or replace an HTTP route: [service[:container-port]@]hostname[/path] (hostname[/path]! removes one) -i, --integrate strings integrate with provider: [plug=]provider[@env] or plug=@connection (provider! or plug! disconnects one edge) --memory strings per-service memory quota --no-ha disable HA mode --open no SSO gate; rely on the app's own auth --path string subdirectory path when using --from or an existing git source -p, --port strings add or replace a port: [conn@]external[:service][:container][/udp] (conn@ = via that connection's load balancer; [conn@]external[/udp]! removes one) --preset string re-resolve preset to NAME[@VERSION] --protected protect the deployment: refuse uninstall/destroy until 'shc unprotect' --public expose to the internet (default: LAN-only) -q, --quiet suppress progress output --ref string git reference when using --from or an existing git source --scale strings per-service replica override --strict-removals fail the update when a removal token ('!') matches nothing, instead of reporting it and carrying on --tls string tls resolver --token string authentication token for private git repositories --ttl string re-stamp the deployment lease (e.g. 72h); unset leaves any existing lease untouched --unprotected clear the deployment's protection flag --var stringArray variable override: key=value sets, key! removes the persisted override (one key per flag, no comma form) --vault-provider string override vault providerOptions inherited from parent commands
Section titled “Options inherited from parent commands” --config stringArray extra YAML config file to layer on top of auto-discovered config; repeatable, later files win -d, --debug enable debug mode (default: $SHC_DEBUG) --exclude string comma-separated dotted paths to drop --fields string comma-separated columns/keys to show (and their order) --filter string comma-separated dotted paths to keep (drops everything else) -o, --output string output format: tty|text|json|yaml (default: $SHC_OUTPUT) -s, --stack string stack name (default: $SHC_STACK) -t, --tenant string tenant name (default: $SHC_TENANT) -v, --verbose verbose output (default: $SHC_VERBOSE)SEE ALSO
Section titled “SEE ALSO”- shc - Selfhosted Cloud CLI