From 87f01e0fb6db83356f415d2200633c2918bd09cd Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Fri, 24 Jul 2026 10:33:04 -0400 Subject: [PATCH 1/2] Creating reusable components for lstk docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Built:** - 12 shared components in [src/components/lstk/](src/components/lstk/) covering Installation, QuickStart, Authentication, Configuration, LifecycleCommands, SnapshotCommands, CommonCommands, GlobalOptionsAndOutput, EnvironmentAndLogging, ShellCompletions, FaqCommon, and TroubleshootingCommon. - Rewrote the [AWS](src/content/docs/aws/developer-tools/running-localstack/lstk.mdx) and [Azure](src/content/docs/azure/developer-tools/lstk.mdx) pages to import them, keeping only what's native to each emulator. - Added the new [Snowflake page](src/content/docs/snowflake/developer-tools/lstk.mdx) plus a "Developer Tools" sidebar section in [astro.config.mjs](astro.config.mjs). - [src/lib/lstk-toc.ts](src/lib/lstk-toc.ts) + a hook in [src/routeData.ts](src/routeData.ts) that stitches shared-component headings into the right-hand nav automatically — verified all three pages now show a complete, correctly-ordered TOC. - Added a scoped `exclude` to `starlight-links-validator` in `astro.config.mjs` for same-page hash links on these files, since that plugin checks each file in isolation and can't see the cross-file composition. **Bugs fixed along the way** (all things you flagged wanting checked): - Azure's page no longer shows AWS-only commands (`aws`, `terraform`, `cdk`, `sam`, `setup aws`, `reset`) or the AWS-only "save/restore state" FAQ item. - Azure regained the "Structured output"/"Exit codes" section it had silently drifted out of sync on. - Fixed a broken volume-mounts example (AWS page linked to Snowflake-specific docs). - Fixed a real broken link: the Prerequisites section linked to `#managing-your-license` on the AWS auth-token page, but that page's heading is actually "License assignment" — fixed to `#license-assignment`. - `MAIN_CONTAINER_NAME`'s default value was hardcoded as `localstack-aws` in shared docs; genericized to reflect the configured emulator type. **Verified:** rendered all three pages in-browser, confirmed content and TOC accuracy, confirmed AWS-only content correctly appears/disappears via the `emulator` prop, and ran a full `npm run build`. --- astro.config.mjs | 19 + package-lock.json | 1 + package.json | 1 + src/components/lstk/Authentication.mdx | 42 + src/components/lstk/CommonCommands.mdx | 221 +++ src/components/lstk/Configuration.mdx | 184 +++ src/components/lstk/EnvironmentAndLogging.mdx | 76 + src/components/lstk/FaqCommon.mdx | 31 + .../lstk/GlobalOptionsAndOutput.mdx | 101 ++ src/components/lstk/Installation.mdx | 48 + src/components/lstk/LifecycleCommands.mdx | 191 +++ src/components/lstk/QuickStart.mdx | 19 + src/components/lstk/ShellCompletions.mdx | 52 + src/components/lstk/SnapshotCommands.mdx | 158 ++ src/components/lstk/TroubleshootingCommon.mdx | 97 ++ .../running-localstack/lstk.mdx | 1299 +--------------- .../docs/azure/developer-tools/lstk.mdx | 1379 +---------------- .../docs/snowflake/developer-tools/lstk.mdx | 70 + src/lib/lstk-toc.ts | 149 ++ src/routeData.ts | 19 + 20 files changed, 1559 insertions(+), 2598 deletions(-) create mode 100644 src/components/lstk/Authentication.mdx create mode 100644 src/components/lstk/CommonCommands.mdx create mode 100644 src/components/lstk/Configuration.mdx create mode 100644 src/components/lstk/EnvironmentAndLogging.mdx create mode 100644 src/components/lstk/FaqCommon.mdx create mode 100644 src/components/lstk/GlobalOptionsAndOutput.mdx create mode 100644 src/components/lstk/Installation.mdx create mode 100644 src/components/lstk/LifecycleCommands.mdx create mode 100644 src/components/lstk/QuickStart.mdx create mode 100644 src/components/lstk/ShellCompletions.mdx create mode 100644 src/components/lstk/SnapshotCommands.mdx create mode 100644 src/components/lstk/TroubleshootingCommon.mdx create mode 100644 src/content/docs/snowflake/developer-tools/lstk.mdx create mode 100644 src/lib/lstk-toc.ts diff --git a/astro.config.mjs b/astro.config.mjs index 48619de60..80f3f9391 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -365,6 +365,18 @@ export default defineConfig({ errorOnRelativeLinks: true, errorOnLocalLinks: false, // Allow localhost links in tutorials (they're instructional) errorOnInvalidHashes: true, + // The lstk pages and their shared components (src/components/lstk/) compose a single + // page out of multiple .mdx files, so same-page "#hash" links often point at a heading + // defined in a different file than the one linking to it. The validator checks each + // file in isolation and can't see that composition, so skip hash checks there; the + // headings themselves (and their slugs) are still real and verified via the lstk pages' + // right-hand nav (see src/routeData.ts). + exclude: ({ file, link }) => + link.startsWith('#') && + (file.includes('/components/lstk/') || + /\/content\/docs\/(aws\/developer-tools\/running-localstack|azure\/developer-tools|snowflake\/developer-tools)\/lstk\.mdx$/.test( + file + )), }), starlightUtils({ multiSidebar: { @@ -808,6 +820,13 @@ export default defineConfig({ { autogenerate: { directory: '/snowflake/capabilities' } }, ], }, + { + label: 'Developer Tools', + collapsed: true, + items: [ + { autogenerate: { directory: '/snowflake/developer-tools' } }, + ], + }, { label: 'Tooling', collapsed: true, diff --git a/package-lock.json b/package-lock.json index cbee1a7ec..281dc162e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "astro": "^7.0.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "github-slugger": "^2.0.0", "lucide-react": "^0.509.0", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/package.json b/package.json index 54c264e7e..b8628e177 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "astro": "^7.0.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "github-slugger": "^2.0.0", "lucide-react": "^0.509.0", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/src/components/lstk/Authentication.mdx b/src/components/lstk/Authentication.mdx new file mode 100644 index 000000000..86d6fbd8b --- /dev/null +++ b/src/components/lstk/Authentication.mdx @@ -0,0 +1,42 @@ +## Authentication + +`lstk` resolves your auth token in the following order: + +1. **System keyring**: a token stored by a previous `lstk login`. +2. **`LOCALSTACK_AUTH_TOKEN` environment variable**: used only when the keyring has no token. +3. **Browser login**: triggered automatically in interactive mode when neither of the above provides a token. + +:::caution +The keyring token takes precedence over `LOCALSTACK_AUTH_TOKEN`. +If you set or change the environment variable but a keyring token already exists, the environment variable is ignored. +Run `lstk logout` to clear the stored keyring token first. +::: + +### Logging in + +```bash +lstk login +``` + +Opens a browser window for authentication and stores the resulting token in your system keyring. +This command requires an interactive terminal. +See the [`login`](#login) command for the full flow and the endpoints it uses. + +### Logging out + +```bash +lstk logout +``` + +Removes the stored credentials from the system keyring and the file-based fallback, and clears the cached license. +`logout` cannot clear a token supplied via `LOCALSTACK_AUTH_TOKEN`; if you authenticated that way, unset the variable instead. +See the [`logout`](#logout) command for the full behavior. + +### File-based token storage + +On systems where the system keyring is unavailable, `lstk` automatically falls back to storing the token in a file (`/auth-token`, mode `0600`). +You can force file-based storage by setting: + +```bash +export LSTK_KEYRING=file +``` diff --git a/src/components/lstk/CommonCommands.mdx b/src/components/lstk/CommonCommands.mdx new file mode 100644 index 000000000..11f0378f6 --- /dev/null +++ b/src/components/lstk/CommonCommands.mdx @@ -0,0 +1,221 @@ +### `volume` + +Manage the emulator volume: the host directory that holds persistent state such as certificates, downloaded tools, and persistence data. + +```bash +lstk volume path +lstk volume clear [options] +``` + +#### `volume path` + +Prints the resolved volume directory for every emulator in your config, one per line. +With the default config (a single `aws` emulator) it prints one path. +Each path is the container's configured `volume` value, or the default OS cache location if `volume` is unset (`~/Library/Caches/lstk/volume/localstack-aws` on macOS, `~/.cache/lstk/volume/localstack-aws` on Linux). + +```bash +# Print the volume directory for each configured emulator +lstk volume path +``` + +#### `volume clear` + +Removes all data from the emulator volume directory, resetting cached state. +It operates on all configured emulators by default, or a single one with `--type`. +Before clearing, it lists each target as `: ()`. + +| Option | Description | +|:----------------|:------------------------------------------| +| `--force` | Skip the confirmation prompt | +| `--type ` | Clear only the emulator of this type | + +```bash +# Clear all configured emulator volumes (prompts for confirmation) +lstk volume clear + +# Clear only the AWS emulator volume +lstk volume clear --type aws + +# Skip the confirmation prompt +lstk volume clear --force + +# Clear without prompting in a non-interactive environment +lstk volume clear --type snowflake --force +``` + +In an interactive terminal, `lstk volume clear` prompts `Clear volume data? This cannot be undone` before deleting anything; choosing **NO** or pressing Ctrl+C cancels with no changes. +In non-interactive mode, `--force` is required, otherwise the command fails with `volume clear requires confirmation; use --force to skip in non-interactive mode`. + +:::caution +If the volume contains files owned by `root` (created by Docker), clearing fails with a permission error. +Re-run with elevated privileges: + +```bash +sudo lstk volume clear +``` +::: + +### `login` + +Authenticate with LocalStack via a browser-based device authorization flow and store the resulting credential in your system keyring. +This command requires an interactive terminal. + +```bash +lstk login +``` + +`lstk` opens your default browser to the LocalStack Web Application, shows a one-time code, and waits for you to approve the request. +If the browser cannot open automatically, `lstk` prints the URL to visit manually. +On success it stores the **license token** returned by the platform (not the raw browser bearer token). + +If you are already authenticated — either `LOCALSTACK_AUTH_TOKEN` is set or a token already exists in storage — `login` prints `You're already logged in` and exits without starting a new flow. + +In non-interactive mode (piped output, CI, or `--non-interactive`), `login` fails with `login requires an interactive terminal`. +The `--config ` flag selects which `config.toml` is loaded, which affects `keyring`, `web_app_url`, and `api_endpoint` resolution. + +:::note +If you approve the request in the browser only *after* pressing a key in the terminal, `lstk` reports `auth request not confirmed - please complete the authentication in your browser`. +Re-run `lstk login` and approve in the browser before continuing. +::: + +The credential is written to the system keyring (service `lstk`, key `lstk.auth-token`). +When the keyring is unavailable — or `LSTK_KEYRING=file` is set — `lstk` stores it in a file at `/auth-token` (mode `0600`) instead. + +Endpoints used by the flow can be overridden via config or environment: + +| Config key | Env var | Default | Description | +|:---------------|:---------------------|:---------------------------------|:-----------------------------------------------------------------------------| +| `keyring` | `LSTK_KEYRING` | (system keyring) | Set to `file` to force file-based token storage instead of the OS keyring. | +| `web_app_url` | `LSTK_WEB_APP_URL` | `https://app.localstack.cloud` | Base URL used to build the browser authorization link. | +| `api_endpoint` | `LSTK_API_ENDPOINT` | `https://api.localstack.cloud` | LocalStack platform API endpoint used for the device flow and license token. | + +```bash +# Force file-based token storage during login +LSTK_KEYRING=file lstk login + +# Use a specific config file +lstk --config ./.lstk/config.toml login +``` + +### `logout` + +Remove stored authentication credentials. + +```bash +lstk logout +lstk logout --non-interactive +``` + +`logout` deletes the auth token from your system keyring (falling back to the file-based token at `/auth-token` when the keyring is unavailable or `LSTK_KEYRING=file` is set) and removes the cached license file. +On success it prints `Logged out successfully`. + +The outcome depends on how you are authenticated: + +| Situation | Behavior | +|:----------|:---------| +| A token is stored (from `lstk login`) | The token is deleted from the keyring and file fallback, the cached license is removed, and `lstk` prints `Logged out successfully`. | +| No stored token, but `LOCALSTACK_AUTH_TOKEN` is set | Nothing is deleted. `lstk` prints a note that you are authenticated via the environment variable and to unset it to log out. | +| No stored token and no `LOCALSTACK_AUTH_TOKEN` | `lstk` prints `Not currently logged in` and exits successfully. | + +:::note +`logout` never clears the `LOCALSTACK_AUTH_TOKEN` environment variable, and it does not stop running emulators. +If a LocalStack emulator is still running after logout, `lstk` prints a note reminding you it is running in the background; run `lstk stop` to stop it. +::: + +### `config` + +Manage CLI configuration. +`config` has no behavior of its own; run it with a subcommand. + +#### `config path` + +Print the resolved path to the active `config.toml`. + +```bash +lstk config path +``` + +This subcommand is read-only: it never creates or initializes a config file. +If `--config ` is set, it prints that path verbatim. +Otherwise it prints the already-loaded config path, the first existing config in the search order, or the path where a config would be created on first run. + +### `update` + +Check for and apply updates to the `lstk` CLI itself. +`lstk` auto-detects how it was installed (Homebrew, npm, or direct binary) and updates using that same method. +Development builds (version `dev`) are skipped, and updates are checked against the latest [GitHub release](https://github.com/localstack/lstk/releases/latest). + +```bash +lstk update [options] +``` + +| Option | Description | +|:--------------------|:---------------------------------------------------------------| +| `--check` | Check for updates without installing them | +| `--non-interactive` | Use plain output instead of the TUI (update logic unchanged) | +| `--json` | Emit the result as a JSON envelope (see [Structured output](#structured-output)). With `--check`, `data` reports `currentVersion`/`latestVersion`/`updateAvailable`; after an applied update, `updatedVersion`/`updated`/`method`. | + +Examples: + +```bash +# Check for updates without installing +lstk update --check + +# Update to the latest version +lstk update + +# Update with plain (non-TUI) output +lstk update --non-interactive +``` + +By install method: + +- **Homebrew** (binary under a `Caskroom` path): runs `brew upgrade localstack/tap/lstk`. +- **npm** (binary under `node_modules`): runs `npm install -g @localstack/lstk@latest`. +- **Binary** (anything else): downloads the release asset for your OS/arch from GitHub, extracts it, and replaces the running executable in place. + +With `--check`, `lstk` only reports whether a newer version is available and exits without downloading or installing anything. + +:::note +Set `LSTK_GITHUB_TOKEN` to send an authenticated GitHub request and avoid API rate limits during update checks. +It is optional; updates also work unauthenticated. +::: + +#### Update notification on start + +Separately from `lstk update`, `lstk` checks for a newer version when you run `lstk start` (the default command), using a short timeout that fails silently if GitHub is unreachable. + +In an interactive terminal, when an update is available `lstk` prints the new version and a release-notes link, then prompts: + +```text +Update lstk to latest version? +> Update now [U] + Remind me next time [R] + Skip this version [S] +``` + +- **Update now [U]**: downloads and applies the update, then asks you to re-run your command. +- **Remind me next time [R]**: does nothing; you are reminded on the next run. +- **Skip this version [S]**: records the version in `config.toml` so you are not prompted about it again. + +In non-interactive mode the notification is not a prompt — `lstk` emits a single note (`Update available: (run lstk update)`) and continues. + +When you choose **Skip this version**, `lstk` writes the skipped version under a `[cli]` table: + +```toml +[cli] +update_skipped_version = "0.5.0" +``` + +While this value matches the latest available version, the start-time update notification for that version is suppressed. +This key is managed automatically and is not intended to be edited by hand. + +### `completion` + +Generate shell completion scripts. + +```bash +lstk completion [bash|zsh|fish|powershell] +``` + +See [Shell completions](#shell-completions) for setup instructions. diff --git a/src/components/lstk/Configuration.mdx b/src/components/lstk/Configuration.mdx new file mode 100644 index 000000000..2757f29a7 --- /dev/null +++ b/src/components/lstk/Configuration.mdx @@ -0,0 +1,184 @@ +## Configuration + +`lstk` uses a TOML configuration file, created automatically on first run. + +### Config file search order + +`lstk` uses the first `config.toml` it finds in this order: + +1. `./.lstk/config.toml`: project-local config in the current directory. +2. `$HOME/.config/lstk/config.toml`: user config (created here if `$HOME/.config/` exists). +3. OS default: + - **macOS**: `$HOME/Library/Application Support/lstk/config.toml` + - **Windows**: `%AppData%\lstk\config.toml` + - **Linux**: `$XDG_CONFIG_HOME/lstk/config.toml` or `$HOME/.config/lstk/config.toml` + +On first run, the config is created at path #2 if `$HOME/.config/` already exists; otherwise at the OS default (#3). + +To see the active config file path: + +```bash +lstk config path +``` + +To use a specific config file: + +```bash +lstk --config /path/to/config.toml start +``` + +### Default configuration + +The default `config.toml` created on first run: + +```toml +[[containers]] +type = "aws" # Emulator type. Supported: "aws", "snowflake", "azure" +tag = "latest" # Docker image tag, e.g. "latest", "2026.4" +port = "4566" # Host port the emulator will be accessible on +# image = "" # Full image override (e.g. an internal mirror or offline image) +# volume = "" # Host directory for persistent state (default: OS cache dir) +# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see Volumes) +# env = [] # Named environment profiles to apply (see [env.*] sections below) +# snapshot = "" # Snapshot REF to auto-load after start (AWS only) +``` + +### Config field reference + +| Field | Type | Default | Description | +|:-----------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------| +| `type` | string | `"aws"` | Emulator type. One of `"aws"`, `"snowflake"`, `"azure"`. Run a single `[[containers]]` block at a time. See [Emulator types](#emulator-types). | +| `tag` | string | `"latest"` | Docker image tag (`"latest"`, `"2026.4"`, etc.). Useful for pinning a specific version. Zero-padded months (`"2026.04"`) are normalized to `"2026.4"`. | +| `port` | string | `"4566"` | Host port the emulator listens on (1–65535). The in-container port is always `4566`. | +| `image` | string | (default) | Full image reference that overrides the default Docker Hub image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, `tag` is ignored; otherwise `tag` (or `latest`) is appended. | +| `volume` | string | (OS cache) | Host directory for persistent emulator state. Defaults to `/lstk/volume/`. See also `volumes`. | +| `volumes` | string[] | `[]` | Docker-style `"host:container[:ro]"` bind mounts (e.g. init hooks). May also carry the persistence mount (target `/var/lib/localstack`). See [Volume mounts](#volume-mounts). | +| `env` | string[] | `[]` | List of named environment profiles to inject into the container (see below). | +| `snapshot` | string | `""` | Snapshot REF (e.g. `pod:my-baseline` or a local path) to auto-load after the emulator starts. AWS emulator only. | + +:::note +There is no `update_prompt` config key. +`lstk` always checks for available updates on startup. +Once you choose to skip a version, `lstk` records it under the `[cli]` table as `update_skipped_version` and stops prompting for that version. +This value is written automatically and is not meant to be hand-edited (see [`update`](#update)). +::: + +### Emulator types + +`lstk` can run more than one kind of emulator. +The `type` field in your `config.toml` selects which one: + +| Type | Docker image | Description | +|:------------|:------------------------------|:-------------------------------------| +| `aws` | `localstack/localstack-pro` | LocalStack AWS emulator (default). | +| `snowflake` | `localstack/snowflake` | LocalStack Snowflake emulator. | +| `azure` | `localstack/localstack-azure` | LocalStack Azure emulator. | + +On the first interactive run, `lstk` prompts you to pick an emulator (`a` for AWS, `s` for Snowflake, `z` for Azure) and writes your choice to `config.toml`. +In non-interactive mode the default `aws` emulator is used if no config file is found. + +Lifecycle commands operate on the emulators defined in your `config.toml`. +Run a single `[[containers]]` block at a time; the AWS-specific commands (`status` resources, `aws`, `reset`, `setup aws`) require an `aws` emulator to be configured. + +:::note +The AWS emulator's license is validated by `lstk` before the container starts. +The Snowflake and Azure emulators validate their own license inside the container at startup, so `lstk` skips its pre-flight license check for them. +If your license does not include the selected emulator, the container exits and `lstk` reports the missing entitlement. +::: + +### Passing environment variables to the container + +Define reusable environment profiles under `[env.]` and reference them in your container config: + +```toml +[[containers]] +type = "aws" +tag = "latest" +port = "4566" +env = ["debug", "ci"] + +[env.debug] +DEBUG = "1" +ENFORCE_IAM = "1" +PERSISTENCE = "1" + +[env.ci] +SERVICES = "s3,sqs" +EAGER_SERVICE_LOADING = "1" +``` + +When `lstk start` runs, the key-value pairs from each referenced profile are injected as environment variables into the LocalStack container. +Keys are uppercased automatically. + +:::note +If you reference an `env` profile name that doesn't exist in your config, `lstk` returns an error: `environment "..." referenced in container config not found`. +::: + +In addition to your custom profiles, `lstk` always injects several variables into the container. +See [Container-injected variables](#container-injected-variables) for the full list. + +### Custom container image + +By default the emulator image is pulled from Docker Hub (`localstack/localstack-pro`, `localstack/snowflake`, or `localstack/localstack-azure` depending on `type`). +Set `image` on a container block to override it — for example, to pull from an internal-registry mirror or to run a locally loaded image in an air-gapped environment: + +```toml +[[containers]] +type = "aws" +image = "registry.internal.example.com/localstack/localstack-pro" +tag = "2026.4" +``` + +If `image` already carries a tag (e.g. `...:2026.4`), the separate `tag` field is ignored; otherwise `tag` (or `latest`) is appended. +See [Offline and enterprise environments](#offline-and-enterprise-environments) for how `lstk` falls back to a locally present image when a pull fails. + +### Volume mounts + +Beyond the single persistence directory set by `volume`, a container block can declare arbitrary Docker-style bind mounts with `volumes`. +Each entry is a `"host:container[:ro]"` spec — useful, for example, for mounting init scripts into `/etc/localstack/init/{boot,start,ready,shutdown}.d`, or any other read-only data your setup needs: + +```toml +[[containers]] +type = "aws" +port = "4566" +volumes = [ + "./init:/etc/localstack/init/ready.d:ro", + "./data:/var/lib/localstack", +] +``` + +- A `volumes` entry whose container target is `/var/lib/localstack` sets the persistence directory (the same mount `volume` configures); this is what [`lstk volume path`](#volume) and [`lstk volume clear`](#volume) resolve. +- Relative host sources and a leading `~/` are resolved against the config file's directory. This differs from the legacy `volume` field, whose value is passed to Docker verbatim. +- Setting the persistence directory through both `volume` and a `volumes` entry with a different source is a validation error. + +`volume` and `volumes` overlap only for the persistence mount: `volume` can *only* set the persistence directory, while `volumes` is a superset that can also express init hooks and other mounts. + +### Using a project-local config + +Place a `.lstk/config.toml` in your project directory. +When you run `lstk` from that directory, the local config takes precedence over the global one. +This lets each project pin its own emulator type, image tag, and environment profiles. + +For example, a project that targets the Snowflake emulator can keep its own config: + +```toml +# .lstk/config.toml +[[containers]] +type = "snowflake" +port = "4566" +``` + +An AWS project might instead pin a specific image tag and enable a debug profile: + +```toml +# .lstk/config.toml +[[containers]] +type = "aws" +tag = "2026.4" +port = "4566" +env = ["dev"] + +[env.dev] +DEBUG = "1" +PERSISTENCE = "1" +``` diff --git a/src/components/lstk/EnvironmentAndLogging.mdx b/src/components/lstk/EnvironmentAndLogging.mdx new file mode 100644 index 000000000..db719a874 --- /dev/null +++ b/src/components/lstk/EnvironmentAndLogging.mdx @@ -0,0 +1,76 @@ +## Environment variables + +The following environment variables configure `lstk` itself (not the LocalStack container): + +| Variable | Description | +|:-----------------------------|:-----------------------------------------------------------------------------------------------------------------| +| `LOCALSTACK_AUTH_TOKEN` | Auth token for non-interactive runs or to skip browser login. Used when no keyring token is stored. | +| `LOCALSTACK_HOST` | Override the host (and optional port) used when resolving and printing the emulator endpoint, and when writing the AWS CLI profile. Bypasses the `localhost.localstack.cloud` DNS probe. | +| `LOCALSTACK_DISABLE_EVENTS` | Set to `1` to disable anonymous telemetry event reporting. | +| `DOCKER_HOST` | Override the Docker daemon socket (e.g. `unix:///home/user/.colima/default/docker.sock`). | +| `LSTK_KEYRING` | Set to `file` to force file-based token storage instead of the system keyring. | +| `LSTK_OTEL` | Set to `1` to enable OpenTelemetry trace export (disabled by default). See [OpenTelemetry tracing](#opentelemetry-tracing). | +| `LSTK_GITHUB_TOKEN` | Optional GitHub token used when checking for or downloading `lstk` updates (raises GitHub API rate limits). | +| `LSTK_API_ENDPOINT` | Override the LocalStack platform API base URL. Default: `https://api.localstack.cloud`. | +| `LSTK_WEB_APP_URL` | Override the LocalStack Web Application URL used for browser login. Default: `https://app.localstack.cloud`. | + +When `DOCKER_HOST` is not set, `lstk` tries the default Docker socket and then probes common alternatives (Colima at `~/.colima/default/docker.sock` or `~/.config/colima/default/docker.sock`, OrbStack at `~/.orbstack/run/docker.sock`). + +When `LSTK_OTEL` is enabled, the standard `OTEL_EXPORTER_OTLP_*` environment variables are honored by the OpenTelemetry SDK. + +### Container-injected variables + +`lstk` injects several environment variables into the LocalStack container on every start, in addition to any profiles you configure: + +| Variable | Default value | Description | +|:----------------------------|:----------------------------------------------|:-----------------------------------------------| +| `LOCALSTACK_AUTH_TOKEN` | (your resolved token) | Passed from the CLI to activate the license. | +| `GATEWAY_LISTEN` | `:4566,:443` | Ports the emulator binds inside the container. | +| `MAIN_CONTAINER_NAME` | `localstack-` (e.g. `localstack-aws`) | Container name for internal references, derived from the configured `type`. | +| `LOCALSTACK_HOST` | `localhost.localstack.cloud:` | Hostname/port the emulator advertises. | +| `LOCALSTACK_PERSISTENCE` | `1` (only with `--persist`) | Enables state persistence across restarts. | +| `LOCALSTACK_CLIENT_NAME` | `lstk` | Identifies the client that started the emulator. | +| `LOCALSTACK_CLIENT_VERSION`| (the `lstk` version) | Version of the client that started the emulator. | + +When a Docker socket is detected it is bind-mounted into the container and `DOCKER_HOST=unix:///var/run/docker.sock` is injected so the emulator can spawn its own containers. +`lstk` also forwards host environment variables matching `CI` and `LOCALSTACK_*` (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token resolved by `lstk`). + +The container also gets port mappings for `4566`, `443`, and the service port range `4510-4559`. + +:::note +`GATEWAY_LISTEN` is read from the container's resolved environment (set it via an `[env.*]` profile), not hardcoded. +Beyond controlling which ports the emulator binds, its host part sets the host publish IP for all published ports: a value like `GATEWAY_LISTEN = "0.0.0.0:4566,0.0.0.0:443"` exposes the emulator beyond loopback (e.g. on a remote host), whereas the default binds to `127.0.0.1` only. +::: + +## OpenTelemetry tracing + +`lstk` can export traces of its own command execution over OTLP/HTTP. +Tracing is **disabled by default**. +Enable it with: + +```bash +LSTK_OTEL=1 lstk start +``` + +When enabled, every command is wrapped in a span (e.g. `lstk.start`) recording the exit code and any error. +`lstk` does not hardcode an export target, so the OpenTelemetry Go SDK reads the standard `OTEL_EXPORTER_OTLP_*` environment variables automatically (default target: OTLP/HTTP at `localhost:4318`). +You need an OTLP-compatible backend running to receive the traces. + +## Logging + +`lstk` writes its own diagnostic logs to `lstk.log` in the same directory as the active config file. +This is separate from the LocalStack container logs (which you view with `lstk logs`). + +- The log file is created automatically and appended to across runs. +- When the file exceeds **1 MB**, it is cleared on the next run. +- Use `lstk config path` to find the config directory; `lstk.log` sits alongside `config.toml`. + +## Offline and enterprise environments + +There is no `--offline` flag. Instead, `lstk` degrades gracefully when common enterprise blockers (Docker Hub unreachable, a proxy/TLS interceptor, or an unreachable license server) prevent an internet request: + +- **Image pull**: if the image pull fails but the image is already present locally, `lstk` warns and uses the local image instead of failing. In interactive mode you can also press Esc to abort an in-progress pull and fall back to the local image. +- **License pre-flight**: when the pinned image is already present locally, `lstk` skips its pre-flight license check so a fully offline start is not blocked; the emulator validates the license itself once it starts. When a check does run, a definitive server rejection (e.g. HTTP 403/400) is still fatal, but a transport-level failure (offline, proxy, or certificate error) is treated as non-fatal and the emulator validates the license instead. The pre-flight is also skipped — with a warning — when the license server does not recognize the image *tag format* (for example a `dev` nightly or a custom internal-mirror tag): that is not a verdict on the license, so `lstk` defers to the emulator's own startup check rather than blocking the start. +- **Telemetry and update checks** are best-effort and fail silently when offline. + +Pair this behavior with a custom [`image`](#custom-container-image) that points at an internal-registry mirror or a locally loaded image to run `lstk` in an air-gapped environment. diff --git a/src/components/lstk/FaqCommon.mdx b/src/components/lstk/FaqCommon.mdx new file mode 100644 index 000000000..4e734563d --- /dev/null +++ b/src/components/lstk/FaqCommon.mdx @@ -0,0 +1,31 @@ +### Can I use `lstk` with Docker Compose? + +No. `lstk` manages its own Docker container directly. +If you use a `docker-compose.yml` to run LocalStack, you do not need `lstk`, and vice versa. +Do not mix `lstk start` with a Docker Compose setup; they are separate, independent methods. + +For Docker Compose configuration, see the [Docker Compose installation guide](/aws/getting-started/installation/#docker-compose). + +### Which Docker image does `lstk` use? + +It depends on the emulator type configured in your `config.toml`. +The AWS emulator uses `localstack/localstack-pro`, the Snowflake emulator uses `localstack/snowflake`, and the Azure emulator uses `localstack/localstack-azure`. +All require a valid auth token (including the free Hobby tier). +See [Emulator types](#emulator-types). + +### How do I pass configuration options like `DEBUG` or `PERSISTENCE` to the container? + +Use environment profiles in your `config.toml`. +Define the variables under an `[env.]` section and reference that name in the `env` list of your container config. +See [Passing environment variables to the container](#passing-environment-variables-to-the-container) for details. + +### How do I pin a specific LocalStack version? + +Set the `tag` field in your `config.toml` to a specific version tag: + +```toml +[[containers]] +type = "aws" +tag = "2026.4" +port = "4566" +``` diff --git a/src/components/lstk/GlobalOptionsAndOutput.mdx b/src/components/lstk/GlobalOptionsAndOutput.mdx new file mode 100644 index 000000000..6dca5f2c8 --- /dev/null +++ b/src/components/lstk/GlobalOptionsAndOutput.mdx @@ -0,0 +1,101 @@ +## Global options + +These options are available for all commands: + +| Option | Description | +|:--------------------|:---------------------------------------------------------------------------| +| `--config ` | Path to a specific TOML config file | +| `--non-interactive` | Disable the interactive TUI, use plain output | +| `--json` | Emit a single machine-readable JSON envelope on stdout instead of human-oriented output. Supported by `stop`, `reset`, and `update`; any other command rejects it. See [Structured output](#structured-output). | +| `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) | +| `--snapshot ` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run) | +| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`) | +| `-v`, `--version` | Print the version and exit | +| `-h`, `--help` | Print help and exit | + +## Interactive and non-interactive mode + +`lstk` automatically selects its output mode: + +- **Interactive mode** (TUI): used when both stdin and stdout are connected to a terminal. + Commands like `start`, `stop`, `restart`, `status`, `login`, `update`, and the confirmation prompts of `reset`/`volume clear` display a Bubble Tea-powered terminal UI. +- **Non-interactive mode** (plain text): used when the output is piped, redirected, or running in CI. + Force this in a TTY with `--non-interactive`. + +```bash +# Force plain output even in an interactive terminal +lstk --non-interactive start +``` + +:::note +`lstk login` requires an interactive terminal; if you need to authenticate in CI, set `LOCALSTACK_AUTH_TOKEN` instead. +Commands that mutate state without prompting in CI (`reset`, `volume clear`) require `--force`. +`lstk setup aws` works non-interactively — it writes the profile with defaults and needs `--force` only to overwrite a conflicting `localstack` profile. +::: + +## Structured output + +The global `--json` flag makes a command emit a single, machine-readable JSON object on stdout instead of human-oriented text, for scripting and CI. +JSON support is being rolled out per command: `stop`, `reset`, and `update` accept `--json`. +Any other command rejects it with an error envelope (`error.code: NOT_JSON_CAPABLE`) rather than silently printing plain text. + +Every JSON-capable command writes **exactly one** JSON object with the following envelope shape: + +```json +{ + "schemaVersion": 1, + "command": "stop", + "status": "ok", + "data": { + "emulators": [ + { "type": "aws", "name": "localstack-aws", "wasRunning": true } + ] + }, + "warnings": [], + "error": null +} +``` + +| Field | Type | Description | +|:----------------|:----------------|:-----------------------------------------------------------------------------------------------------| +| `schemaVersion` | integer | Wire-format version of the envelope, currently always `1`. Check it once before parsing. | +| `command` | string | The command that produced the envelope (e.g. `"stop"`, `"reset"`). | +| `status` | string | `"ok"` or `"error"` — branch on this first. | +| `data` | object or `null`| Command-specific result. Non-null when `status` is `"ok"`, `null` when it is `"error"`. | +| `warnings` | array | Non-fatal notices, always present (empty array when there are none). Each entry is `{ "code", "message" }`. | +| `error` | object or `null`| The machine-readable failure. Non-null when `status` is `"error"`, `null` otherwise. | + +When `status` is `"error"`, the `error` object carries a stable `code` (e.g. `EMULATOR_NOT_RUNNING`, `CONFIRMATION_REQUIRED`, `RUNTIME_UNAVAILABLE`), a coarse `category`, a human-readable `message` (informational only — branch on `code`, not `message`), and a `retryable` boolean: + +```json +{ + "schemaVersion": 1, + "command": "reset", + "status": "error", + "data": null, + "warnings": [], + "error": { + "code": "CONFIRMATION_REQUIRED", + "category": "USAGE", + "message": "reset requires confirmation; use --force to skip in non-interactive mode", + "retryable": false + } +} +``` + +### Exit codes + +For a full enumeration, read `error.code` from the envelope; the process exit code carries only the two most common, mechanically-remediable failures: + +| Exit code | Meaning | +|:----------|:--------------------------------------------------------------------------------------------| +| `0` | `status: "ok"`. | +| `1` | `status: "error"` for any code other than the two below. | +| `2` | A Cobra-level usage error that occurred before `--json` could be recognized (plain-text error on stderr, not an envelope). | +| `3` | `error.code == "CONFIRMATION_REQUIRED"` (re-run with `--force`). | +| `4` | `error.code == "AUTH_REQUIRED"` (run `lstk login` or set `LOCALSTACK_AUTH_TOKEN`). | + +:::note +`--json` implies non-interactive behavior: no TUI and no prompts. +Combining it with a destructive command that would otherwise prompt (`reset`) still requires `--force`, which surfaces as `CONFIRMATION_REQUIRED` (exit code `3`) when omitted. +::: diff --git a/src/components/lstk/Installation.mdx b/src/components/lstk/Installation.mdx new file mode 100644 index 000000000..5b0057159 --- /dev/null +++ b/src/components/lstk/Installation.mdx @@ -0,0 +1,48 @@ +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +## Installation + + + + +```bash +brew install localstack/tap/lstk +``` + +Homebrew also installs shell completions for bash, zsh, and fish automatically. + + + + +```bash +npm install -g @localstack/lstk +``` + + + + +Download the binary for your platform from [GitHub Releases](https://github.com/localstack/lstk/releases), extract it, and place it on your `PATH`. + + + + +Verify the installation: + +```bash +lstk --version +``` + +### Updating + +`lstk` can update itself. +It detects how it was originally installed (Homebrew, npm, or binary) and uses the matching update method: + +```bash +# Check for updates without installing +lstk update --check + +# Update to the latest version +lstk update +``` + +See the [`update`](#update) command for details, including the start-time update notification. diff --git a/src/components/lstk/LifecycleCommands.mdx b/src/components/lstk/LifecycleCommands.mdx new file mode 100644 index 000000000..07459de0e --- /dev/null +++ b/src/components/lstk/LifecycleCommands.mdx @@ -0,0 +1,191 @@ +export const AwsOnly = ({ emulator, children }) => (emulator === 'aws' ? children : null); + +`lstk` uses a flat command structure. +Running `lstk` with no command is equivalent to `lstk start`. + +### `start` + +Start the LocalStack emulator. +Launches the TUI in interactive terminals and prints plain output otherwise. +`lstk start` launches the emulator defined in the first `[[containers]]` entry of the resolved `config.toml` (not necessarily AWS). + +```bash +lstk start +lstk start --persist +lstk start --non-interactive +``` + +| Option | Description | +|:--------------------|:-----------------------------------------------------------------------------| +| `--persist` | Persist emulator state across restarts (sets `LOCALSTACK_PERSISTENCE=1` in the container) | +| `--non-interactive` | Disable the interactive TUI and use plain output | + + + +On the **AWS emulator**, `start` also accepts: + +| Option | Description | +|:--------------------|:-----------------------------------------------------------------------------| +| `--snapshot ` | Auto-load this snapshot after the emulator starts, overriding the configured `snapshot` for one run | +| `--no-snapshot` | Skip auto-loading the configured `snapshot` for this run | + + + +`lstk start` forwards host environment variables prefixed with `LOCALSTACK_` to the emulator (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token `lstk` resolved). See [Container-injected variables](#container-injected-variables). + +By default the emulator starts with a fresh state on every run. +Pass `--persist` to keep data across restarts: `lstk` injects `LOCALSTACK_PERSISTENCE=1` into the container so state is written to the mounted [`volume`](#config-field-reference) and reloaded on the next start. +When persistence is active, the AWS emulator's startup summary includes a `• Persistence: Enabled` line. + +```bash +# Start with persistent state +lstk start --persist +``` + +:::note +`--persist` is a flag on `start` (and the bare `lstk` command) and on [`restart`](#restart). +For finer-grained control, you can also set `PERSISTENCE = "1"` in an environment profile (see [Passing environment variables to the container](#passing-environment-variables-to-the-container)). +::: + + + +#### Auto-loading a snapshot on start + +For the **AWS emulator**, you can have `lstk` load a snapshot automatically every time it starts the emulator. +Set the `snapshot` field on the container block to any load REF (a `pod:` Cloud Pod or a local path): + +```toml +[[containers]] +type = "aws" +port = "4566" +snapshot = "pod:my-baseline" +``` + +The snapshot is loaded only when the emulator is **freshly started** this run; if it is already running, the auto-load is skipped. +Override it for a single run with `--snapshot REF`, or skip it entirely with `--no-snapshot`: + +```bash +# Start and load a different snapshot for this run only +lstk start --snapshot pod:other-baseline + +# Start without loading the configured snapshot +lstk start --no-snapshot +``` + +The `snapshot` field is only read on start; [`snapshot save`](#snapshot-save) never writes it back into your config. + + + +### `stop` + +Stop the running LocalStack emulator. +Stops every emulator container defined in the resolved `config.toml` (the `[[containers]]` entries), with a 30-second stop timeout per container. + +```bash +lstk stop +lstk stop --non-interactive +``` + +`stop` fails fast if the Docker runtime is not healthy (for example, Docker is not running), or if a configured emulator is not currently running (`LocalStack is not running`). +In an interactive terminal it shows an animated "Stopping LocalStack..." spinner and a styled confirmation; in non-interactive mode it prints the same progress and result as plain text. + +`stop` supports [`--json`](#structured-output): the `data` payload lists each configured emulator and whether it `wasRunning`. + +### `restart` + +Stop and restart the LocalStack emulator. +Performs a stop of the running emulator followed by a fresh start, using the same auth, config, and Docker settings as [`start`](#start). +Launches the TUI in interactive terminals and prints plain output otherwise. + +```bash +lstk restart +lstk restart --persist +``` + +| Option | Description | +|:-------------|:--------------------------------------------| +| `--persist` | Persist emulator state across the restart | + +By default, emulator state is **not** retained across the restart and the container starts clean. +Pass `--persist` to keep the emulator's state so it survives the restart. + +### `status` + +Show the status of a running emulator and its deployed resources. +Before contacting the emulator, `lstk` checks that the Docker runtime is healthy; if it is not, the command reports `runtime not healthy` and exits with a non-zero status. + +```bash +lstk status +lstk --non-interactive status +``` + +For each emulator configured in your `config.toml` (the `[[containers]]` entries), `status` reports whether it is running and, if so, prints an instance summary: + +```text +LocalStack AWS Emulator is running +• Endpoint: localhost:4566 +• Persistence: Enabled +• Container: localstack-aws +• Version: 4.0.0 +• Uptime: 1h 12m 4s +``` + +- **Endpoint** is the live `host:port`, queried from Docker, so it stays correct even if the configured `port` was changed while the container kept running. +- **Persistence** appears only for the AWS emulator and only when persistence is enabled. +- **Uptime** is computed from the container's start time and is omitted if it cannot be determined. + +If an emulator is not running, `status` prints an error and exits non-zero without checking the remaining emulators: + +```text +LocalStack AWS Emulator is not running + + Start LocalStack: lstk + See help: lstk -h +``` + + + +For the **AWS emulator**, `status` additionally lists deployed resources. +When resources exist it prints a summary line followed by a table; when none exist it prints `No resources deployed`. + +```text +~ 3 resources · 2 services + +Service Resource Region Account +S3 my-bucket us-east-1 000000000000 +SQS my-queue us-east-1 000000000000 +``` + + + +In an interactive terminal the output is rendered through the TUI; in non-interactive mode (or with `--non-interactive`) the same content is printed as plain text, with the resource table shown at full width when stdout is not a TTY. +The Snowflake and Azure emulators show the instance summary only and never report resources. + +### `logs` + +Show or stream emulator logs. + +```bash +lstk logs [options] +``` + +| Option | Description | +|:------------|:-----------------------------------------| +| `--follow`, `-f` | Stream logs in real-time. Without this flag, `lstk` prints the currently available logs and exits. | +| `--verbose`, `-v` | Show all logs without filtering. By default, `lstk` drops noisy lines (internal request logs, provider chatter); `--verbose` shows every line verbatim. | + +By default, `lstk logs` reads from the first configured emulator container and applies a noise filter. +In an interactive terminal, lines are color-coded by log level (`DEBUG`, `INFO`, `WARN`, `ERROR`); in non-interactive mode, raw log lines are written to stdout. + +Example: + +```bash +# Print current filtered logs and exit +lstk logs + +# Stream filtered logs in real-time +lstk logs --follow + +# Stream all logs without filtering +lstk logs --follow --verbose +``` diff --git a/src/components/lstk/QuickStart.mdx b/src/components/lstk/QuickStart.mdx new file mode 100644 index 000000000..d3e912c7b --- /dev/null +++ b/src/components/lstk/QuickStart.mdx @@ -0,0 +1,19 @@ +## Quick start + +```bash +lstk +``` + +Running `lstk` without arguments performs the full startup sequence: authenticates you automatically, pulls the latest image if needed, and starts the LocalStack container. +In an interactive terminal it launches the TUI; in a non-interactive environment it prints plain text output. + +On the very first interactive run, `lstk` prompts you to pick which emulator to run (AWS, Snowflake, or Azure) and writes your choice to `config.toml`. +See [Emulator types](#emulator-types) for the available options. + +For CI or headless environments, set `LOCALSTACK_AUTH_TOKEN` and use `--non-interactive`: + +```bash +LOCALSTACK_AUTH_TOKEN= lstk --non-interactive +``` + +CI environments require a CI Auth Token; a personal Developer Auth Token cannot be used there. diff --git a/src/components/lstk/ShellCompletions.mdx b/src/components/lstk/ShellCompletions.mdx new file mode 100644 index 000000000..465319852 --- /dev/null +++ b/src/components/lstk/ShellCompletions.mdx @@ -0,0 +1,52 @@ +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +## Shell completions + +`lstk` includes completion scripts for bash, zsh, fish, and powershell. +If you installed via Homebrew, completions are set up automatically. + +For manual setup: + + + + +```bash +# Load in current session +source <(lstk completion bash) + +# Persist (Linux) +lstk completion bash > /etc/bash_completion.d/lstk + +# Persist (macOS with Homebrew) +lstk completion bash > $(brew --prefix)/etc/bash_completion.d/lstk +``` + + + + +```bash +# Load in current session +source <(lstk completion zsh) + +# Persist (Linux) +lstk completion zsh > "${fpath[1]}/_lstk" + +# Persist (macOS with Homebrew) +lstk completion zsh > $(brew --prefix)/share/zsh/site-functions/_lstk +``` + + + + +```bash +# Load in current session +lstk completion fish | source + +# Persist +lstk completion fish > ~/.config/fish/completions/lstk.fish +``` + + + + +Restart your shell after persisting completions. diff --git a/src/components/lstk/SnapshotCommands.mdx b/src/components/lstk/SnapshotCommands.mdx new file mode 100644 index 000000000..d2a2ba268 --- /dev/null +++ b/src/components/lstk/SnapshotCommands.mdx @@ -0,0 +1,158 @@ +### `snapshot` + +Manage emulator snapshots. +A snapshot captures the running emulator's state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or in your own S3 bucket. +The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`. + +:::note +Snapshots are best supported on the **AWS emulator**. +`snapshot save`/`load` (and the `save`/`load` aliases) also work for the Snowflake and Azure emulators, but their snapshot support is experimental and not fully tested — `lstk` prints a warning such as `Snapshot support for the snowflake emulator is experimental and not fully tested.` +`reset` remains **AWS-only** and errors out with `reset is only supported for the AWS emulator` otherwise. +::: + +#### `snapshot save` + +Save a snapshot of the running emulator's state. +The emulator must already be running; this command does **not** auto-start it. + +```bash +# Auto-named snapshot file in the current directory +lstk snapshot save + +# Save to a specific local path +lstk snapshot save ./my-snapshot + +# Save to a Cloud Pod on the LocalStack platform (requires auth) +lstk snapshot save pod:my-baseline + +# Save to your own S3 bucket (pod name is auto-generated if omitted) +lstk snapshot save my-pod s3://my-bucket/prefix +``` + +The optional `[destination]` argument takes one of these forms: + +| Destination | Description | +|:--------------------------------|:------------------------------------------------------------------------------------------------| +| (omitted) | Auto-generates a timestamped snapshot file in the current directory (`./snapshot--.snapshot`). | +| local path | Writes a snapshot archive to that path. The `.snapshot` extension is forced. | +| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. | +| ` s3://bucket/prefix` | Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See [S3 remotes](#s3-remotes). | + +Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not. + +| Option | Description | +|:--------------------|:----------------------------------------------------------------------------------------------| +| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` destinations). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +#### `snapshot load` + +Load a snapshot into the emulator, **auto-starting it first** if it is not already running. + +```bash +# Load a local snapshot by path or name +lstk snapshot load my-baseline +lstk snapshot load ./checkpoint + +# Load from a Cloud Pod (requires auth) +lstk snapshot load pod:my-baseline + +# Load from your own S3 bucket (pod name is required) +lstk snapshot load my-pod s3://my-bucket/prefix + +# Control how the snapshot merges with running state +lstk snapshot load pod:my-baseline --merge=overwrite +``` + +The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod. +To load from S3, pass the pod name followed by an `s3://bucket/prefix` location (see [S3 remotes](#s3-remotes)). + +| Option | Description | +|:---------------------|:--------------------------------------------------------------------------------------------------------| +| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. | +| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` sources). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap. +- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state. +- `service-merge`: the snapshot wins per resource; non-overlapping resources are combined. + +The aliases behave identically: + +```bash +lstk save pod:my-baseline +lstk load ./checkpoint +``` + +#### `snapshot list` + +List the Cloud Pod snapshots available on the LocalStack platform. +By default, only snapshots you created are listed; pass `--all` to include every snapshot in your organization. +This subcommand operates on Cloud Pods, so it requires authentication. + +```bash +# Snapshots you created +lstk snapshot list + +# Every snapshot in your organization +lstk snapshot list --all + +# List snapshots in your own S3 bucket (requires a running emulator) +lstk snapshot list s3://my-bucket/prefix +``` + +Passing an `s3://bucket/prefix` location lists snapshots stored in your own S3 bucket instead of the platform (see [S3 remotes](#s3-remotes)). Unlike the platform listing, this queries the emulator, so it requires a running emulator. + +| Option | Description | +|:-------------------|:-------------------------------------------------------------| +| `--all` | List all snapshots in your organization, not just your own. | +| `--profile ` | AWS profile to read S3 credentials from (used only with an `s3://` location). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +#### `snapshot remove` + +Delete a Cloud Pod snapshot from the LocalStack platform. +Only cloud snapshots (the `pod:` prefix) can be removed; local snapshots are plain files you delete yourself. +This operation cannot be undone. + +```bash +lstk snapshot remove pod:my-baseline + +# Skip the confirmation prompt (required in non-interactive mode) +lstk snapshot remove pod:my-baseline --force +``` + +The required `REF` argument must be a `pod:` Cloud Pod reference. + +| Option | Description | +|:----------|:------------------------------------------------------------------------| +| `--force` | Skip the confirmation prompt. Required when running non-interactively. | + +#### `snapshot show` + +Show metadata for a single Cloud Pod snapshot on the LocalStack platform: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). +This subcommand is cloud-only and requires authentication. + +```bash +lstk snapshot show pod:my-baseline +``` + +The required `REF` argument must be a `pod:` Cloud Pod reference. + +#### S3 remotes + +`snapshot save`, `load`, and `list` can target a snapshot stored in your **own S3 bucket** by passing an `s3://bucket/prefix` location. +The pod name (the snapshot's identity within the bucket) is a positional separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`. + +```bash +lstk snapshot save my-pod s3://my-bucket/prefix +lstk snapshot load my-pod s3://my-bucket/prefix +lstk snapshot list s3://my-bucket/prefix +``` + +Credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (plus optional `AWS_SESSION_TOKEN`) environment variables, otherwise the profile named by `AWS_PROFILE`. +Only static credentials are supported (no SSO, assume-role, or `credential_process`), and credentials must never be embedded in the URL. + +`lstk` runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo. +Because the transfer is performed by the emulator (not the CLI), S3 remotes require a **running emulator**, and `list s3://…` in particular queries the emulator rather than the platform API. + +:::note +`remove` and `show` do not support S3; they operate on Cloud Pods only. +::: diff --git a/src/components/lstk/TroubleshootingCommon.mdx b/src/components/lstk/TroubleshootingCommon.mdx new file mode 100644 index 000000000..eddf1ec8f --- /dev/null +++ b/src/components/lstk/TroubleshootingCommon.mdx @@ -0,0 +1,97 @@ +### Port 443 already in use + +By default, LocalStack binds to both port `4566` and port `443` inside the container (controlled by the `GATEWAY_LISTEN` variable). +On some systems, particularly Windows with Hyper-V, IIS, or VPN software, port 443 may already be in use. + +**Symptoms:** + +```text +failed to start LocalStack: Error response from daemon: ports are not available: +exposing port TCP 127.0.0.1:443 -> 127.0.0.1:0: listen tcp4 127.0.0.1:443: bind: +address already in use +``` + +**Fix:** Override `GATEWAY_LISTEN` to bind only to port 4566: + +```toml +[[containers]] +type = "aws" +tag = "latest" +port = "4566" +env = ["nossl"] + +[env.nossl] +GATEWAY_LISTEN = "0.0.0.0:4566" +``` + +This tells the container to skip the port 443 binding entirely. + +### Docker is not running + +`lstk` requires a running Docker daemon. +If Docker is not reachable, you will see an error like: + +```text +Error: runtime not healthy +``` + +**Fix:** Start Docker Desktop (macOS/Windows) or the Docker daemon (`sudo systemctl start docker` on Linux). +If you use Colima or OrbStack, make sure the VM is running. +You can also point `lstk` at a custom socket with `DOCKER_HOST`. + +### Authentication required in non-interactive mode + +When running without a TTY (e.g. in CI), `lstk` cannot open a browser for login. +If no token is found in the keyring or environment, it fails: + +```text +authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive mode +``` + +**Fix:** Set the `LOCALSTACK_AUTH_TOKEN` environment variable before running `lstk`: + +```bash +export LOCALSTACK_AUTH_TOKEN= +lstk --non-interactive start +``` + +You can find your auth token on the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). + +### License validation failed + +If your auth token is invalid, expired, or not linked to an active license, the LocalStack container exits with a license error: + +```text +The license activation failed for the following reason: +No credentials were found in the environment. +``` + +**Fix:** + +- Verify your token is valid at the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). +- Make sure the token is set correctly, either via `lstk login` or the `LOCALSTACK_AUTH_TOKEN` environment variable. +- If a stale keyring token is interfering, run `lstk logout` first and then set `LOCALSTACK_AUTH_TOKEN`. + +### Image pull failed + +If `lstk` cannot pull the Docker image, check your network connection and Docker configuration. +On corporate networks, you may need to configure Docker's proxy settings, see [How do I configure LocalStack to use my corporate HTTP and HTTPS proxy?](/aws/getting-started/faq/#how-do-i-configure-localstack-to-use-my-corporate-http-and-https-proxy). + +### Unknown environment profile + +If your container config references an `env` profile that doesn't exist, `lstk` returns: + +```text +environment "myprofile" referenced in container config not found +``` + +**Fix:** Make sure the profile name in the `env` list matches an `[env.]` section in your `config.toml`: + +```toml +[[containers]] +type = "aws" +env = ["myprofile"] # must match the section name below + +[env.myprofile] +DEBUG = "1" +``` diff --git a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx index ad98dd415..349cd403f 100644 --- a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx +++ b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx @@ -7,7 +7,18 @@ sidebar: tags: ['Hobby'] --- -import { Tabs, TabItem } from '@astrojs/starlight/components'; +import Installation from '@/components/lstk/Installation.mdx'; +import QuickStart from '@/components/lstk/QuickStart.mdx'; +import Authentication from '@/components/lstk/Authentication.mdx'; +import Configuration from '@/components/lstk/Configuration.mdx'; +import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; +import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; +import CommonCommands from '@/components/lstk/CommonCommands.mdx'; +import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; +import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; +import ShellCompletions from '@/components/lstk/ShellCompletions.mdx'; +import FaqCommon from '@/components/lstk/FaqCommon.mdx'; +import TroubleshootingCommon from '@/components/lstk/TroubleshootingCommon.mdx'; ## Introduction @@ -15,485 +26,27 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting. `lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status. -It can also save and load emulator state (as local snapshots or Cloud Pods) reset running state, run AWS CLI commands against the emulator, and manage the on-disk volume. +It can also save and load emulator state (as local snapshots or Cloud Pods), reset running state, run AWS CLI commands against the emulator, and manage the on-disk volume. Running `lstk` with no arguments takes you through the entire startup flow automatically. -`lstk` also proxies developer tools so they run directly against LocalStack: the AWS CLI (`lstk aws`), the Azure CLI (`lstk az`), Terraform (`lstk terraform`), the AWS CDK (`lstk cdk`), and the AWS SAM CLI (`lstk sam`). +`lstk` also proxies developer tools so they run directly against the AWS emulator: the AWS CLI (`lstk aws`), Terraform (`lstk terraform`), the AWS CDK (`lstk cdk`), and the AWS SAM CLI (`lstk sam`). ## Prerequisites - [Docker](https://docs.docker.com/get-docker/) installed and running. -- A [LocalStack account](https://www.localstack.cloud/pricing) with a [license](/aws/getting-started/auth-token/#managing-your-license), and `lstk` handles authentication for you (see [Authentication](#authentication)). +- A [LocalStack account](https://www.localstack.cloud/pricing) with a [license](/aws/getting-started/auth-token/#license-assignment), and `lstk` handles authentication for you (see [Authentication](#authentication)). -## Installation + - - + -```bash -brew install localstack/tap/lstk -``` - -Homebrew also installs shell completions for bash, zsh, and fish automatically. - - - - -```bash -npm install -g @localstack/lstk -``` - - - - -Download the binary for your platform from [GitHub Releases](https://github.com/localstack/lstk/releases), extract it, and place it on your `PATH`. - - - - -Verify the installation: - -```bash -lstk --version -``` - -### Updating - -`lstk` can update itself. -It detects how it was originally installed (Homebrew, npm, or binary) and uses the matching update method: - -```bash -# Check for updates without installing -lstk update --check - -# Update to the latest version -lstk update -``` - -See the [`update`](#update) command for details, including the start-time update notification. - -## Quick start - -```bash -lstk -``` - -Running `lstk` without arguments performs the full startup sequence: authenticates you automatically, pulls the latest image if needed, and starts the LocalStack container. -In an interactive terminal it launches the TUI; in a non-interactive environment it prints plain text output. - -On the very first interactive run, `lstk` prompts you to pick which emulator to run (AWS, Snowflake, or Azure) and writes your choice to `config.toml`. -See [Emulator types](#emulator-types) for the available options. - -For CI or headless environments, set `LOCALSTACK_AUTH_TOKEN` and use `--non-interactive`: - -```bash -LOCALSTACK_AUTH_TOKEN= lstk --non-interactive -``` - -CI environments require a CI Auth Token; a personal Developer Auth Token cannot be used there. - -## Authentication - -`lstk` resolves your auth token in the following order: - -1. **System keyring**: a token stored by a previous `lstk login`. -2. **`LOCALSTACK_AUTH_TOKEN` environment variable**: used only when the keyring has no token. -3. **Browser login**: triggered automatically in interactive mode when neither of the above provides a token. - -:::caution -The keyring token takes precedence over `LOCALSTACK_AUTH_TOKEN`. -If you set or change the environment variable but a keyring token already exists, the environment variable is ignored. -Run `lstk logout` to clear the stored keyring token first. -::: - -### Logging in - -```bash -lstk login -``` - -Opens a browser window for authentication and stores the resulting token in your system keyring. -This command requires an interactive terminal. -See the [`login`](#login) command for the full flow and the endpoints it uses. - -### Logging out - -```bash -lstk logout -``` - -Removes the stored credentials from the system keyring and the file-based fallback, and clears the cached license. -`logout` cannot clear a token supplied via `LOCALSTACK_AUTH_TOKEN`; if you authenticated that way, unset the variable instead. -See the [`logout`](#logout) command for the full behavior. - -### File-based token storage - -On systems where the system keyring is unavailable, `lstk` automatically falls back to storing the token in a file (`/auth-token`, mode `0600`). -You can force file-based storage by setting: - -```bash -export LSTK_KEYRING=file -``` - -## Configuration - -`lstk` uses a TOML configuration file, created automatically on first run. - -### Config file search order - -`lstk` uses the first `config.toml` it finds in this order: - -1. `./.lstk/config.toml`: project-local config in the current directory. -2. `$HOME/.config/lstk/config.toml`: user config (created here if `$HOME/.config/` exists). -3. OS default: - - **macOS**: `$HOME/Library/Application Support/lstk/config.toml` - - **Windows**: `%AppData%\lstk\config.toml` - - **Linux**: `$XDG_CONFIG_HOME/lstk/config.toml` or `$HOME/.config/lstk/config.toml` - -On first run, the config is created at path #2 if `$HOME/.config/` already exists; otherwise at the OS default (#3). - -To see the active config file path: - -```bash -lstk config path -``` + -To use a specific config file: - -```bash -lstk --config /path/to/config.toml start -``` - -### Default configuration - -The default `config.toml` created on first run: - -```toml -[[containers]] -type = "aws" # Emulator type. Supported: "aws", "snowflake", "azure" -tag = "latest" # Docker image tag, e.g. "latest", "2026.4" -port = "4566" # Host port the emulator will be accessible on -# image = "" # Full image override (e.g. an internal mirror or offline image) -# volume = "" # Host directory for persistent state (default: OS cache dir) -# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see Volumes) -# env = [] # Named environment profiles to apply (see [env.*] sections below) -# snapshot = "" # Snapshot REF to auto-load after start (AWS only) -``` - -### Config field reference - -| Field | Type | Default | Description | -|:-----------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------| -| `type` | string | `"aws"` | Emulator type. One of `"aws"`, `"snowflake"`, `"azure"`. Run a single `[[containers]]` block at a time. See [Emulator types](#emulator-types). | -| `tag` | string | `"latest"` | Docker image tag (`"latest"`, `"2026.4"`, etc.). Useful for pinning a specific version. Zero-padded months (`"2026.04"`) are normalized to `"2026.4"`. | -| `port` | string | `"4566"` | Host port the emulator listens on (1–65535). The in-container port is always `4566`. | -| `image` | string | (default) | Full image reference that overrides the default Docker Hub image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, `tag` is ignored; otherwise `tag` (or `latest`) is appended. | -| `volume` | string | (OS cache) | Host directory for persistent emulator state. Defaults to `/lstk/volume/`. See also `volumes`. | -| `volumes` | string[] | `[]` | Docker-style `"host:container[:ro]"` bind mounts (e.g. init hooks). May also carry the persistence mount (target `/var/lib/localstack`). See [Volume mounts](#volume-mounts). | -| `env` | string[] | `[]` | List of named environment profiles to inject into the container (see below). | -| `snapshot` | string | `""` | Snapshot REF (e.g. `pod:my-baseline` or a local path) to auto-load after the emulator starts. AWS emulator only. See [Auto-loading a snapshot on start](#auto-loading-a-snapshot-on-start). | - -:::note -There is no `update_prompt` config key. -`lstk` always checks for available updates on startup. -Once you choose to skip a version, `lstk` records it under the `[cli]` table as `update_skipped_version` and stops prompting for that version. -This value is written automatically and is not meant to be hand-edited (see [`update`](#update)). -::: - -### Emulator types - -`lstk` can run more than one kind of emulator. -The `type` field in your `config.toml` selects which one: - -| Type | Docker image | Description | -|:------------|:------------------------------|:-------------------------------------| -| `aws` | `localstack/localstack-pro` | LocalStack AWS emulator (default). | -| `snowflake` | `localstack/snowflake` | LocalStack Snowflake emulator. | -| `azure` | `localstack/localstack-azure` | LocalStack Azure emulator. | - -On the first interactive run, `lstk` prompts you to pick an emulator (`a` for AWS, `s` for Snowflake, `z` for Azure) and writes your choice to `config.toml`. -In non-interactive mode the default `aws` emulator is used if no config file is found. - -Lifecycle commands operate on the emulators defined in your `config.toml`. -Run a single `[[containers]]` block at a time; the AWS-specific commands (`status` resources, `aws`, `reset`, `setup aws`) require an `aws` emulator to be configured. - -:::note -The AWS emulator's license is validated by `lstk` before the container starts. -The Snowflake and Azure emulators validate their own license inside the container at startup, so `lstk` skips its pre-flight license check for them. -If your license does not include the selected emulator, the container exits and `lstk` reports the missing entitlement. -::: - -### Passing environment variables to the container - -Define reusable environment profiles under `[env.]` and reference them in your container config: - -```toml -[[containers]] -type = "aws" -tag = "latest" -port = "4566" -env = ["debug", "ci"] - -[env.debug] -DEBUG = "1" -ENFORCE_IAM = "1" -PERSISTENCE = "1" - -[env.ci] -SERVICES = "s3,sqs" -EAGER_SERVICE_LOADING = "1" -``` - -When `lstk start` runs, the key-value pairs from each referenced profile are injected as environment variables into the LocalStack container. -Keys are uppercased automatically. - -:::note -If you reference an `env` profile name that doesn't exist in your config, `lstk` returns an error: `environment "..." referenced in container config not found`. -::: - -In addition to your custom profiles, `lstk` always injects several variables into the container. -See [Container-injected variables](#container-injected-variables) for the full list. - -### Custom container image - -By default the emulator image is pulled from Docker Hub (`localstack/localstack-pro`, `localstack/snowflake`, or `localstack/localstack-azure` depending on `type`). -Set `image` on a container block to override it — for example, to pull from an internal-registry mirror or to run a locally loaded image in an air-gapped environment: - -```toml -[[containers]] -type = "aws" -image = "registry.internal.example.com/localstack/localstack-pro" -tag = "2026.4" -``` - -If `image` already carries a tag (e.g. `...:2026.4`), the separate `tag` field is ignored; otherwise `tag` (or `latest`) is appended. -See [Offline and enterprise environments](#offline-and-enterprise-environments) for how `lstk` falls back to a locally present image when a pull fails. - -### Volume mounts - -Beyond the single persistence directory set by `volume`, a container block can declare arbitrary Docker-style bind mounts with `volumes`. -Each entry is a `"host:container[:ro]"` spec — useful, for example, for mounting a [Snowflake init hook](/snowflake/capabilities/init-hooks/) script into `/etc/localstack/init/{boot,start,ready,shutdown}.d`: - -```toml -[[containers]] -type = "snowflake" -port = "4566" -volumes = [ - "./test.sf.sql:/etc/localstack/init/ready.d/test.sf.sql", - "./data:/var/lib/localstack", -] -``` - -- A `volumes` entry whose container target is `/var/lib/localstack` sets the persistence directory (the same mount `volume` configures); this is what [`lstk volume path`](#volume) and [`lstk volume clear`](#volume) resolve. -- Relative host sources and a leading `~/` are resolved against the config file's directory. This differs from the legacy `volume` field, whose value is passed to Docker verbatim. -- Setting the persistence directory through both `volume` and a `volumes` entry with a different source is a validation error. - -`volume` and `volumes` overlap only for the persistence mount: `volume` can *only* set the persistence directory, while `volumes` is a superset that can also express init hooks and other mounts. - -### Using a project-local config - -Place a `.lstk/config.toml` in your project directory. -When you run `lstk` from that directory, the local config takes precedence over the global one. -This lets each project pin its own emulator type, image tag, and environment profiles. - -For example, a project that targets the Snowflake emulator can keep its own config: - -```toml -# .lstk/config.toml -[[containers]] -type = "snowflake" -port = "4566" -``` - -An AWS project might instead pin a specific image tag and enable a debug profile: - -```toml -# .lstk/config.toml -[[containers]] -type = "aws" -tag = "2026.4" -port = "4566" -env = ["dev"] - -[env.dev] -DEBUG = "1" -PERSISTENCE = "1" -``` + ## Commands -`lstk` uses a flat command structure. -Running `lstk` with no command is equivalent to `lstk start`. - -### `start` - -Start the LocalStack emulator. -Launches the TUI in interactive terminals and prints plain output otherwise. -`lstk start` launches the emulator defined in the first `[[containers]]` entry of the resolved `config.toml` (not necessarily AWS). - -```bash -lstk start -lstk start --persist -lstk start --non-interactive -``` - -| Option | Description | -|:--------------------|:-----------------------------------------------------------------------------| -| `--persist` | Persist emulator state across restarts (sets `LOCALSTACK_PERSISTENCE=1` in the container) | -| `--snapshot ` | Auto-load this snapshot after the emulator starts, overriding the configured `snapshot` for one run (AWS only) | -| `--no-snapshot` | Skip auto-loading the configured `snapshot` for this run | -| `--non-interactive` | Disable the interactive TUI and use plain output | - -`lstk start` forwards host environment variables prefixed with `LOCALSTACK_` to the emulator (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token `lstk` resolved). See [Container-injected variables](#container-injected-variables). - -By default the emulator starts with a fresh state on every run. -Pass `--persist` to keep data across restarts: `lstk` injects `LOCALSTACK_PERSISTENCE=1` into the container so state is written to the mounted [`volume`](#config-field-reference) and reloaded on the next start. -When persistence is active, the AWS emulator's startup summary includes a `• Persistence: Enabled` line. - -```bash -# Start with persistent state -lstk start --persist -``` - -:::note -`--persist` is a flag on `start` (and the bare `lstk` command) and on [`restart`](#restart). -For finer-grained control, you can also set `PERSISTENCE = "1"` in an environment profile (see [Passing environment variables to the container](#passing-environment-variables-to-the-container)). -::: - -#### Auto-loading a snapshot on start - -For the **AWS emulator**, you can have `lstk` load a snapshot automatically every time it starts the emulator. -Set the `snapshot` field on the container block to any load REF (a `pod:` Cloud Pod or a local path): - -```toml -[[containers]] -type = "aws" -port = "4566" -snapshot = "pod:my-baseline" -``` - -The snapshot is loaded only when the emulator is **freshly started** this run; if it is already running, the auto-load is skipped. -Override it for a single run with `--snapshot REF`, or skip it entirely with `--no-snapshot`: - -```bash -# Start and load a different snapshot for this run only -lstk start --snapshot pod:other-baseline - -# Start without loading the configured snapshot -lstk start --no-snapshot -``` - -The `snapshot` field is only read on start; [`snapshot save`](#snapshot-save) never writes it back into your config. - -### `stop` - -Stop the running LocalStack emulator. -Stops every emulator container defined in the resolved `config.toml` (the `[[containers]]` entries), with a 30-second stop timeout per container. - -```bash -lstk stop -lstk stop --non-interactive -``` - -`stop` fails fast if the Docker runtime is not healthy (for example, Docker is not running), or if a configured emulator is not currently running (`LocalStack is not running`). -In an interactive terminal it shows an animated "Stopping LocalStack..." spinner and a styled confirmation; in non-interactive mode it prints the same progress and result as plain text. - -`stop` supports [`--json`](#structured-output): the `data` payload lists each configured emulator and whether it `wasRunning`. - -### `restart` - -Stop and restart the LocalStack emulator. -Performs a stop of the running emulator followed by a fresh start, using the same auth, config, and Docker settings as [`start`](#start). -Launches the TUI in interactive terminals and prints plain output otherwise. - -```bash -lstk restart -lstk restart --persist -``` - -| Option | Description | -|:-------------|:-------------------------------------------| -| `--persist` | Persist emulator state across the restart | - -By default, emulator state is **not** retained across the restart and the container starts clean. -Pass `--persist` to keep the emulator's state so it survives the restart. - -### `status` - -Show the status of a running emulator and its deployed resources. -Before contacting the emulator, `lstk` checks that the Docker runtime is healthy; if it is not, the command reports `runtime not healthy` and exits with a non-zero status. - -```bash -lstk status -lstk --non-interactive status -``` - -For each emulator configured in your `config.toml` (the `[[containers]]` entries), `status` reports whether it is running and, if so, prints an instance summary: - -```text -LocalStack AWS Emulator is running -• Endpoint: localhost:4566 -• Persistence: Enabled -• Container: localstack-aws -• Version: 4.0.0 -• Uptime: 1h 12m 4s -``` - -- **Endpoint** is the live `host:port`, queried from Docker, so it stays correct even if the configured `port` was changed while the container kept running. -- **Persistence** appears only for the AWS emulator and only when persistence is enabled. -- **Uptime** is computed from the container's start time and is omitted if it cannot be determined. - -If an emulator is not running, `status` prints an error and exits non-zero without checking the remaining emulators: - -```text -LocalStack AWS Emulator is not running - - Start LocalStack: lstk - See help: lstk -h -``` - -For the **AWS emulator**, `status` additionally lists deployed resources. -When resources exist it prints a summary line followed by a table; when none exist it prints `No resources deployed`. - -```text -~ 3 resources · 2 services - -Service Resource Region Account -S3 my-bucket us-east-1 000000000000 -SQS my-queue us-east-1 000000000000 -``` - -In an interactive terminal the output is rendered through the TUI; in non-interactive mode (or with `--non-interactive`) the same content is printed as plain text, with the resource table shown at full width when stdout is not a TTY. -The Snowflake and Azure emulators show the instance summary only and never report resources. - -### `logs` - -Show or stream emulator logs. - -```bash -lstk logs [options] -``` - -| Option | Description | -|:------------|:-----------------------------------------| -| `--follow`, `-f` | Stream logs in real-time. Without this flag, `lstk` prints the currently available logs and exits. | -| `--verbose`, `-v` | Show all logs without filtering. By default, `lstk` drops noisy lines (internal request logs, provider chatter); `--verbose` shows every line verbatim. | - -By default, `lstk logs` reads from the first configured emulator container and applies a noise filter. -In an interactive terminal, lines are color-coded by log level (`DEBUG`, `INFO`, `WARN`, `ERROR`); in non-interactive mode, raw log lines are written to stdout. - -Example: - -```bash -# Print current filtered logs and exit -lstk logs - -# Stream filtered logs in real-time -lstk logs --follow - -# Stream all logs without filtering -lstk logs --follow --verbose -``` + ### `aws` @@ -518,7 +71,7 @@ Everything after `lstk aws` is forwarded verbatim to the host `aws` binary, incl The exit code and `stdout`/`stderr` of the underlying `aws` process are passed through unchanged, so piping and interactive subcommands work as expected. | Option | Description | -|:--------------------|:--------------------------------------------------------------------------------------------------| +|:--------------------|:----------------------------------------------------------------------------------------------------| | `--non-interactive` | Suppress the loading spinner. Unlike other commands, this flag is stripped before invoking `aws` (not forwarded). | :::note @@ -533,7 +86,7 @@ The AWS emulator must already be running (`lstk start`), Docker must be healthy, - **Profile mode**: if a complete `localstack` profile exists in both `~/.aws/config` and `~/.aws/credentials`, `lstk` appends `--profile localstack` and lets `aws` read the region, credentials, and endpoint from that profile. - **Profile-less mode**: if the profile is not present, `lstk` runs `aws` with `AWS_ACCESS_KEY_ID=test`, `AWS_SECRET_ACCESS_KEY=test`, and `AWS_DEFAULT_REGION=us-east-1` injected only when those variables are not already set in your environment. In this mode it also prints an informational note: `No AWS profile found, run 'lstk setup aws'`. -Run [`lstk setup aws`](#setup) to create the `localstack` profile for use with the AWS CLI and SDKs. +Run [`lstk setup aws`](#setup-aws) to create the `localstack` profile for use with the AWS CLI and SDKs. #### Endpoint resolution @@ -541,51 +94,11 @@ By default, `lstk` probes whether `localhost.localstack.cloud` resolves to `127. Set [`LOCALSTACK_HOST`](#environment-variables) to override the host:port used to reach LocalStack and skip the DNS probe. The port comes from the AWS container's `port` in `config.toml` (default `4566`). -### `az` - -Run Azure CLI commands against the running LocalStack Azure emulator. -`lstk az` runs `az` with an isolated `AZURE_CONFIG_DIR` in which a custom Azure cloud is registered against LocalStack's endpoints, so your global `~/.azure` configuration is left untouched and plain `az` keeps talking to real Azure. - -Run [`lstk setup azure`](#setup-azure) once before using this mode. -Everything after `lstk az` is forwarded verbatim to the host `az` binary, and its exit code and output are passed through unchanged. - -```bash -lstk az group list -lstk az storage account list -``` - -The Azure CLI has no `--endpoint-url`/`--profile` equivalent, so the isolation relies entirely on the dedicated config directory prepared by `setup azure`. - -#### Global interception (optional) - -If a script must invoke plain `az` (not `lstk az`), you can redirect your **global** `~/.azure` to LocalStack instead: - -```bash -# Point global 'az' at the LocalStack Azure emulator -lstk az start-interception - -# Switch back to real Azure -lstk az stop-interception -``` - -`start-interception` registers and activates the `LocalStack` cloud in your global Azure configuration so every `az` invocation targets LocalStack until you stop it. -`stop-interception` switches the active cloud back to `AzureCloud` (override with `--cloud `) and re-enables instance discovery, but only when `LocalStack` is still the active cloud, to avoid clobbering an unrelated selection. - -:::caution -Interception changes global state that affects every `az` command in any terminal. -Use the isolated `lstk az ` mode unless you specifically need plain `az` to target LocalStack. -::: - ### `terraform` Run Terraform against LocalStack, using LocalStack endpoints as AWS provider overrides. `lstk terraform` (alias `lstk tf`) generates a provider-override file and forwards your arguments to the real `terraform` binary. -:::note -`lstk terraform` currently targets the AWS emulator only. -To use Terraform with the other emulators, see the relevant emulator docs. -::: - ```bash lstk terraform init lstk terraform --region us-west-2 plan @@ -595,7 +108,7 @@ lstk tf apply lstk-specific flags must appear **before** the Terraform action: | Option | Default | Description | -|:------------------|:---------------------|:---------------------------------------| +|:------------------|:---------------------|:-----------------------------------------| | `--region ` | `us-east-1` | Deployment region. | | `--account ` | `test` | Target AWS account id (12 digits). | @@ -634,168 +147,11 @@ Compared with `samlocal`, image/container-based Lambda (ECR) deploys and nested ::: :::note -Like `lstk aws`, the `az`, `terraform`, `cdk`, and `sam` proxies do not start the emulator — start it first with `lstk start`. +Like `lstk aws`, the `terraform`, `cdk`, and `sam` proxies do not start the emulator — start it first with `lstk start`. Each requires the corresponding third-party CLI to be installed and on your `PATH`. ::: -### `snapshot` - -Manage emulator snapshots. -A snapshot captures the running emulator's state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or in your own S3 bucket. -The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`. - -:::note -Snapshots are best supported on the **AWS emulator**. -`snapshot save`/`load` (and the `save`/`load` aliases) also work for the Snowflake and Azure emulators, but their snapshot support is experimental and not fully tested — `lstk` prints a warning such as `Snapshot support for the snowflake emulator is experimental and not fully tested.` -[`reset`](#reset) remains **AWS-only** and errors out with `reset is only supported for the AWS emulator` otherwise. -::: - -#### `snapshot save` - -Save a snapshot of the running emulator's state. -The emulator must already be running; this command does **not** auto-start it. - -```bash -# Auto-named snapshot file in the current directory -lstk snapshot save - -# Save to a specific local path -lstk snapshot save ./my-snapshot - -# Save to a Cloud Pod on the LocalStack platform (requires auth) -lstk snapshot save pod:my-baseline - -# Save to your own S3 bucket (pod name is auto-generated if omitted) -lstk snapshot save my-pod s3://my-bucket/prefix -``` - -The optional `[destination]` argument takes one of these forms: - -| Destination | Description | -|:--------------------------------|:------------------------------------------------------------------------------------------------| -| (omitted) | Auto-generates a timestamped snapshot file in the current directory (`./snapshot--.snapshot`). | -| local path | Writes a snapshot archive to that path. The `.snapshot` extension is forced. | -| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. | -| ` s3://bucket/prefix` | Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See [S3 remotes](#s3-remotes). | - -Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not. - -| Option | Description | -|:--------------------|:----------------------------------------------------------------------------------------------| -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` destinations). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot load` - -Load a snapshot into the emulator, **auto-starting it first** if it is not already running. - -```bash -# Load a local snapshot by path or name -lstk snapshot load my-baseline -lstk snapshot load ./checkpoint - -# Load from a Cloud Pod (requires auth) -lstk snapshot load pod:my-baseline - -# Load from your own S3 bucket (pod name is required) -lstk snapshot load my-pod s3://my-bucket/prefix - -# Control how the snapshot merges with running state -lstk snapshot load pod:my-baseline --merge=overwrite -``` - -The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod. -To load from S3, pass the pod name followed by an `s3://bucket/prefix` location (see [S3 remotes](#s3-remotes)). - -| Option | Description | -|:---------------------|:--------------------------------------------------------------------------------------------------------| -| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. | -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` sources). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap. -- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state. -- `service-merge`: the snapshot wins per resource; non-overlapping resources are combined. - -The aliases behave identically: - -```bash -lstk save pod:my-baseline -lstk load ./checkpoint -``` - -#### `snapshot list` - -List the Cloud Pod snapshots available on the LocalStack platform. -By default, only snapshots you created are listed; pass `--all` to include every snapshot in your organization. -This subcommand operates on Cloud Pods, so it requires authentication. - -```bash -# Snapshots you created -lstk snapshot list - -# Every snapshot in your organization -lstk snapshot list --all - -# List snapshots in your own S3 bucket (requires a running emulator) -lstk snapshot list s3://my-bucket/prefix -``` - -Passing an `s3://bucket/prefix` location lists snapshots stored in your own S3 bucket instead of the platform (see [S3 remotes](#s3-remotes)). Unlike the platform listing, this queries the emulator, so it requires a running emulator. - -| Option | Description | -|:-------------------|:-------------------------------------------------------------| -| `--all` | List all snapshots in your organization, not just your own. | -| `--profile ` | AWS profile to read S3 credentials from (used only with an `s3://` location). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot remove` - -Delete a Cloud Pod snapshot from the LocalStack platform. -Only cloud snapshots (the `pod:` prefix) can be removed; local snapshots are plain files you delete yourself. -This operation cannot be undone. - -```bash -lstk snapshot remove pod:my-baseline - -# Skip the confirmation prompt (required in non-interactive mode) -lstk snapshot remove pod:my-baseline --force -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -| Option | Description | -|:----------|:----------------------------------------------------------------------| -| `--force` | Skip the confirmation prompt. Required when running non-interactively. | - -#### `snapshot show` - -Show metadata for a single Cloud Pod snapshot on the LocalStack platform: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). -This subcommand is cloud-only and requires authentication. - -```bash -lstk snapshot show pod:my-baseline -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -#### S3 remotes - -`snapshot save`, `load`, and `list` can target a snapshot stored in your **own S3 bucket** by passing an `s3://bucket/prefix` location. -The pod name (the snapshot's identity within the bucket) is a positional separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`. - -```bash -lstk snapshot save my-pod s3://my-bucket/prefix -lstk snapshot load my-pod s3://my-bucket/prefix -lstk snapshot list s3://my-bucket/prefix -``` - -Credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (plus optional `AWS_SESSION_TOKEN`) environment variables, otherwise the profile named by `AWS_PROFILE`. -Only static credentials are supported (no SSO, assume-role, or `credential_process`), and credentials must never be embedded in the URL. - -`lstk` runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo. -Because the transfer is performed by the emulator (not the CLI), S3 remotes require a **running emulator**, and `list s3://…` in particular queries the emulator rather than the platform API. - -:::note -`remove` and `show` do not support S3; they operate on Cloud Pods only. -::: + ### `reset` @@ -808,7 +164,7 @@ lstk reset --force ``` | Option | Description | -|:----------|:----------------------------------------------------------------| +|:----------|:-------------------------------------------------------------------| | `--force` | Skip the confirmation prompt. Required in non-interactive mode. | In interactive mode, `reset` prompts for confirmation before clearing state. @@ -826,138 +182,15 @@ It does **not** wipe the on-disk volume (certificates, persistence data, cached To clear that, stop the emulator and run [`lstk volume clear`](#volume). ::: -### `volume` - -Manage the emulator volume: the host directory that holds persistent state such as certificates, downloaded tools, and persistence data. - -```bash -lstk volume path -lstk volume clear [options] -``` - -#### `volume path` - -Prints the resolved volume directory for every emulator in your config, one per line. -With the default config (a single `aws` emulator) it prints one path. -Each path is the container's configured `volume` value, or the default OS cache location if `volume` is unset (`~/Library/Caches/lstk/volume/localstack-aws` on macOS, `~/.cache/lstk/volume/localstack-aws` on Linux). - -```bash -# Print the volume directory for each configured emulator -lstk volume path -``` - -#### `volume clear` - -Removes all data from the emulator volume directory, resetting cached state. -It operates on all configured emulators by default, or a single one with `--type`. -Before clearing, it lists each target as `: ()`. - -| Option | Description | -|:----------------|:-----------------------------------------| -| `--force` | Skip the confirmation prompt | -| `--type ` | Clear only the emulator of this type | - -```bash -# Clear all configured emulator volumes (prompts for confirmation) -lstk volume clear - -# Clear only the AWS emulator volume -lstk volume clear --type aws - -# Skip the confirmation prompt -lstk volume clear --force - -# Clear without prompting in a non-interactive environment -lstk volume clear --type snowflake --force -``` - -In an interactive terminal, `lstk volume clear` prompts `Clear volume data? This cannot be undone` before deleting anything; choosing **NO** or pressing Ctrl+C cancels with no changes. -In non-interactive mode, `--force` is required, otherwise the command fails with `volume clear requires confirmation; use --force to skip in non-interactive mode`. - -:::caution -If the volume contains files owned by `root` (created by Docker), clearing fails with a permission error. -Re-run with elevated privileges: - -```bash -sudo lstk volume clear -``` -::: - -### `login` - -Authenticate with LocalStack via a browser-based device authorization flow and store the resulting credential in your system keyring. -This command requires an interactive terminal. - -```bash -lstk login -``` - -`lstk` opens your default browser to the LocalStack Web Application, shows a one-time code, and waits for you to approve the request. -If the browser cannot open automatically, `lstk` prints the URL to visit manually. -On success it stores the **license token** returned by the platform (not the raw browser bearer token). - -If you are already authenticated — either `LOCALSTACK_AUTH_TOKEN` is set or a token already exists in storage — `login` prints `You're already logged in` and exits without starting a new flow. - -In non-interactive mode (piped output, CI, or `--non-interactive`), `login` fails with `login requires an interactive terminal`. -The `--config ` flag selects which `config.toml` is loaded, which affects `keyring`, `web_app_url`, and `api_endpoint` resolution. - -:::note -If you approve the request in the browser only *after* pressing a key in the terminal, `lstk` reports `auth request not confirmed - please complete the authentication in your browser`. -Re-run `lstk login` and approve in the browser before continuing. -::: - -The credential is written to the system keyring (service `lstk`, key `lstk.auth-token`). -When the keyring is unavailable — or `LSTK_KEYRING=file` is set — `lstk` stores it in a file at `/auth-token` (mode `0600`) instead. - -Endpoints used by the flow can be overridden via config or environment: - -| Config key | Env var | Default | Description | -|:---------------|:--------------------|:-------------------------------|:-----------------------------------------------------------------------------| -| `keyring` | `LSTK_KEYRING` | (system keyring) | Set to `file` to force file-based token storage instead of the OS keyring. | -| `web_app_url` | `LSTK_WEB_APP_URL` | `https://app.localstack.cloud` | Base URL used to build the browser authorization link. | -| `api_endpoint` | `LSTK_API_ENDPOINT` | `https://api.localstack.cloud` | LocalStack platform API endpoint used for the device flow and license token. | - -```bash -# Force file-based token storage during login -LSTK_KEYRING=file lstk login - -# Use a specific config file -lstk --config ./.lstk/config.toml login -``` - -### `logout` - -Remove stored authentication credentials. - -```bash -lstk logout -lstk logout --non-interactive -``` - -`logout` deletes the auth token from your system keyring (falling back to the file-based token at `/auth-token` when the keyring is unavailable or `LSTK_KEYRING=file` is set) and removes the cached license file. -On success it prints `Logged out successfully`. - -The outcome depends on how you are authenticated: - -| Situation | Behavior | -|:----------|:---------| -| A token is stored (from `lstk login`) | The token is deleted from the keyring and file fallback, the cached license is removed, and `lstk` prints `Logged out successfully`. | -| No stored token, but `LOCALSTACK_AUTH_TOKEN` is set | Nothing is deleted. `lstk` prints a note that you are authenticated via the environment variable and to unset it to log out. | -| No stored token and no `LOCALSTACK_AUTH_TOKEN` | `lstk` prints `Not currently logged in` and exits successfully. | - -:::note -`logout` never clears the `LOCALSTACK_AUTH_TOKEN` environment variable, and it does not stop running emulators. -If a LocalStack emulator is still running after logout, `lstk` prints a note reminding you it is running in the background; run `lstk stop` to stop it. -::: + ### `setup` Set up CLI integration for an emulator type. -`lstk setup` is a grouping command with no action of its own; the work is done by its subcommands, `setup aws` and `setup azure`. +`lstk setup` is a grouping command with no action of its own; on the AWS emulator, the work is done by its subcommand `setup aws`. ```bash lstk setup aws -lstk setup azure ``` #### `setup aws` @@ -970,7 +203,7 @@ lstk setup aws --force ``` | Option | Description | -|:----------|:-----------------------------------------------------------------------------------------| +|:----------|:----------------------------------------------------------------------------------------------| | `--force` | Overwrite an existing `localstack` profile whose values differ, and skip the confirmation prompt. | On an interactive terminal it prompts (Y/n) before making changes. @@ -1008,488 +241,24 @@ If the `localstack` profile is already configured correctly, `lstk` reports `Loc The former `lstk config profile` command has been removed; use `lstk setup aws`. ::: -#### `setup azure` - -Prepare an isolated Azure CLI configuration directory that routes [`lstk az`](#az) commands to the LocalStack Azure emulator. -Your global `~/.azure` configuration is left untouched. - -```bash -lstk setup azure -# alias: -lstk setup az -``` - -`setup azure` registers a custom Azure cloud (`LocalStack`) whose endpoints point at the LocalStack Azure emulator, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login — all inside a dedicated config directory under the `lstk` config dir (via `AZURE_CONFIG_DIR`). -It requires the `az` CLI to be installed and a running LocalStack Azure emulator. - -To instead redirect your **global** `az` (so existing scripts run unmodified against LocalStack), see [`lstk az start-interception`](#az). - -### `config` - -Manage CLI configuration. -`config` has no behavior of its own; run it with a subcommand. - -#### `config path` - -Print the resolved path to the active `config.toml`. - -```bash -lstk config path -``` - -This subcommand is read-only: it never creates or initializes a config file. -If `--config ` is set, it prints that path verbatim. -Otherwise it prints the already-loaded config path, the first existing config in the search order, or the path where a config would be created on first run. - -### `update` - -Check for and apply updates to the `lstk` CLI itself. -`lstk` auto-detects how it was installed (Homebrew, npm, or direct binary) and updates using that same method. -Development builds (version `dev`) are skipped, and updates are checked against the latest [GitHub release](https://github.com/localstack/lstk/releases/latest). - -```bash -lstk update [options] -``` - -| Option | Description | -|:--------------------|:-------------------------------------------------------------| -| `--check` | Check for updates without installing them | -| `--non-interactive` | Use plain output instead of the TUI (update logic unchanged) | -| `--json` | Emit the result as a JSON envelope (see [Structured output](#structured-output)). With `--check`, `data` reports `currentVersion`/`latestVersion`/`updateAvailable`; after an applied update, `updatedVersion`/`updated`/`method`. | - -Examples: - -```bash -# Check for updates without installing -lstk update --check - -# Update to the latest version -lstk update - -# Update with plain (non-TUI) output -lstk update --non-interactive -``` - -By install method: - -- **Homebrew** (binary under a `Caskroom` path): runs `brew upgrade localstack/tap/lstk`. -- **npm** (binary under `node_modules`): runs `npm install -g @localstack/lstk@latest`. -- **Binary** (anything else): downloads the release asset for your OS/arch from GitHub, extracts it, and replaces the running executable in place. - -With `--check`, `lstk` only reports whether a newer version is available and exits without downloading or installing anything. - -:::note -Set `LSTK_GITHUB_TOKEN` to send an authenticated GitHub request and avoid API rate limits during update checks. -It is optional; updates also work unauthenticated. -::: - -#### Update notification on start - -Separately from `lstk update`, `lstk` checks for a newer version when you run `lstk start` (the default command), using a short timeout that fails silently if GitHub is unreachable. - -In an interactive terminal, when an update is available `lstk` prints the new version and a release-notes link, then prompts: - -```text -Update lstk to latest version? -> Update now [U] - Remind me next time [R] - Skip this version [S] -``` - -- **Update now [U]**: downloads and applies the update, then asks you to re-run your command. -- **Remind me next time [R]**: does nothing; you are reminded on the next run. -- **Skip this version [S]**: records the version in `config.toml` so you are not prompted about it again. - -In non-interactive mode the notification is not a prompt — `lstk` emits a single note (`Update available: (run lstk update)`) and continues. - -When you choose **Skip this version**, `lstk` writes the skipped version under a `[cli]` table: - -```toml -[cli] -update_skipped_version = "0.5.0" -``` - -While this value matches the latest available version, the start-time update notification for that version is suppressed. -This key is managed automatically and is not intended to be edited by hand. - -### `completion` - -Generate shell completion scripts. - -```bash -lstk completion [bash|zsh|fish|powershell] -``` - -See [Shell completions](#shell-completions) for setup instructions. - -## Global options - -These options are available for all commands: - -| Option | Description | -|:--------------------|:---------------------------------------------------------------------------| -| `--config ` | Path to a specific TOML config file | -| `--non-interactive` | Disable the interactive TUI, use plain output | -| `--json` | Emit a single machine-readable JSON envelope on stdout instead of human-oriented output. Supported by `stop`, `reset`, and `update`; any other command rejects it. See [Structured output](#structured-output). | -| `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) | -| `--snapshot ` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run) | -| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`) | -| `-v`, `--version` | Print the version and exit | -| `-h`, `--help` | Print help and exit | - -## Interactive and non-interactive mode - -`lstk` automatically selects its output mode: - -- **Interactive mode** (TUI): used when both stdin and stdout are connected to a terminal. - Commands like `start`, `stop`, `restart`, `status`, `login`, `update`, and the confirmation prompts of `reset`/`volume clear` display a Bubble Tea-powered terminal UI. -- **Non-interactive mode** (plain text): used when the output is piped, redirected, or running in CI. - Force this in a TTY with `--non-interactive`. - -```bash -# Force plain output even in an interactive terminal -lstk --non-interactive start -``` - -:::note -`lstk login` requires an interactive terminal; if you need to authenticate in CI, set `LOCALSTACK_AUTH_TOKEN` instead. -Commands that mutate state without prompting in CI (`reset`, `volume clear`) require `--force`. -`lstk setup aws` works non-interactively — it writes the profile with defaults and needs `--force` only to overwrite a conflicting `localstack` profile. -::: - -## Structured output - -The global `--json` flag makes a command emit a single, machine-readable JSON object on stdout instead of human-oriented text, for scripting and CI. -JSON support is being rolled out per command: `stop`, `reset`, and `update` accept `--json`. -Any other command rejects it with an error envelope (`error.code: NOT_JSON_CAPABLE`) rather than silently printing plain text. - -Every JSON-capable command writes **exactly one** JSON object with the following envelope shape: - -```json -{ - "schemaVersion": 1, - "command": "stop", - "status": "ok", - "data": { - "emulators": [ - { "type": "aws", "name": "localstack-aws", "wasRunning": true } - ] - }, - "warnings": [], - "error": null -} -``` - -| Field | Type | Description | -|:----------------|:----------------|:-----------------------------------------------------------------------------------------------------| -| `schemaVersion` | integer | Wire-format version of the envelope, currently always `1`. Check it once before parsing. | -| `command` | string | The command that produced the envelope (e.g. `"stop"`, `"reset"`). | -| `status` | string | `"ok"` or `"error"` — branch on this first. | -| `data` | object or `null`| Command-specific result. Non-null when `status` is `"ok"`, `null` when it is `"error"`. | -| `warnings` | array | Non-fatal notices, always present (empty array when there are none). Each entry is `{ "code", "message" }`. | -| `error` | object or `null`| The machine-readable failure. Non-null when `status` is `"error"`, `null` otherwise. | - -When `status` is `"error"`, the `error` object carries a stable `code` (e.g. `EMULATOR_NOT_RUNNING`, `CONFIRMATION_REQUIRED`, `RUNTIME_UNAVAILABLE`), a coarse `category`, a human-readable `message` (informational only — branch on `code`, not `message`), and a `retryable` boolean: - -```json -{ - "schemaVersion": 1, - "command": "reset", - "status": "error", - "data": null, - "warnings": [], - "error": { - "code": "CONFIRMATION_REQUIRED", - "category": "USAGE", - "message": "reset requires confirmation; use --force to skip in non-interactive mode", - "retryable": false - } -} -``` - -### Exit codes - -For a full enumeration, read `error.code` from the envelope; the process exit code carries only the two most common, mechanically-remediable failures: - -| Exit code | Meaning | -|:----------|:--------------------------------------------------------------------------------------------| -| `0` | `status: "ok"`. | -| `1` | `status: "error"` for any code other than the two below. | -| `2` | A Cobra-level usage error that occurred before `--json` could be recognized (plain-text error on stderr, not an envelope). | -| `3` | `error.code == "CONFIRMATION_REQUIRED"` (re-run with `--force`). | -| `4` | `error.code == "AUTH_REQUIRED"` (run `lstk login` or set `LOCALSTACK_AUTH_TOKEN`). | - -:::note -`--json` implies non-interactive behavior: no TUI and no prompts. -Combining it with a destructive command that would otherwise prompt (`reset`) still requires `--force`, which surfaces as `CONFIRMATION_REQUIRED` (exit code `3`) when omitted. -::: - -## Environment variables - -The following environment variables configure `lstk` itself (not the LocalStack container): - -| Variable | Description | -|:-----------------------------|:-----------------------------------------------------------------------------------------------------------------| -| `LOCALSTACK_AUTH_TOKEN` | Auth token for non-interactive runs or to skip browser login. Used when no keyring token is stored. | -| `LOCALSTACK_HOST` | Override the host (and optional port) used when resolving and printing the emulator endpoint, and when writing the AWS CLI profile. Bypasses the `localhost.localstack.cloud` DNS probe. | -| `LOCALSTACK_DISABLE_EVENTS` | Set to `1` to disable anonymous telemetry event reporting. | -| `DOCKER_HOST` | Override the Docker daemon socket (e.g. `unix:///home/user/.colima/default/docker.sock`). | -| `LSTK_KEYRING` | Set to `file` to force file-based token storage instead of the system keyring. | -| `LSTK_OTEL` | Set to `1` to enable OpenTelemetry trace export (disabled by default). See [OpenTelemetry tracing](#opentelemetry-tracing). | -| `LSTK_GITHUB_TOKEN` | Optional GitHub token used when checking for or downloading `lstk` updates (raises GitHub API rate limits). | -| `LSTK_API_ENDPOINT` | Override the LocalStack platform API base URL. Default: `https://api.localstack.cloud`. | -| `LSTK_WEB_APP_URL` | Override the LocalStack Web Application URL used for browser login. Default: `https://app.localstack.cloud`. | - -When `DOCKER_HOST` is not set, `lstk` tries the default Docker socket and then probes common alternatives (Colima at `~/.colima/default/docker.sock` or `~/.config/colima/default/docker.sock`, OrbStack at `~/.orbstack/run/docker.sock`). - -When `LSTK_OTEL` is enabled, the standard `OTEL_EXPORTER_OTLP_*` environment variables are honored by the OpenTelemetry SDK. - -### Container-injected variables - -`lstk` injects several environment variables into the LocalStack container on every start, in addition to any profiles you configure: - -| Variable | Default value | Description | -|:---------------------------|:---------------------------------------------|:---------------------------------------------| -| `LOCALSTACK_AUTH_TOKEN` | (your resolved token) | Passed from the CLI to activate the license. | -| `GATEWAY_LISTEN` | `:4566,:443` | Ports the emulator binds inside the container. | -| `MAIN_CONTAINER_NAME` | `localstack-aws` | Container name for internal references. | -| `LOCALSTACK_HOST` | `localhost.localstack.cloud:` | Hostname/port the emulator advertises. | -| `LOCALSTACK_PERSISTENCE` | `1` (only with `--persist`) | Enables state persistence across restarts. | -| `LOCALSTACK_CLIENT_NAME` | `lstk` | Identifies the client that started the emulator. | -| `LOCALSTACK_CLIENT_VERSION`| (the `lstk` version) | Version of the client that started the emulator. | - -When a Docker socket is detected it is bind-mounted into the container and `DOCKER_HOST=unix:///var/run/docker.sock` is injected so the emulator can spawn its own containers. -`lstk` also forwards host environment variables matching `CI` and `LOCALSTACK_*` (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token resolved by `lstk`). - -The container also gets port mappings for `4566`, `443`, and the service port range `4510-4559`. - -:::note -`GATEWAY_LISTEN` is read from the container's resolved environment (set it via an `[env.*]` profile), not hardcoded. -Beyond controlling which ports the emulator binds, its host part sets the host publish IP for all published ports: a value like `GATEWAY_LISTEN = "0.0.0.0:4566,0.0.0.0:443"` exposes the emulator beyond loopback (e.g. on a remote host), whereas the default binds to `127.0.0.1` only. -::: - -## OpenTelemetry tracing - -`lstk` can export traces of its own command execution over OTLP/HTTP. -Tracing is **disabled by default**. -Enable it with: - -```bash -LSTK_OTEL=1 lstk start -``` - -When enabled, every command is wrapped in a span (e.g. `lstk.start`) recording the exit code and any error. -`lstk` does not hardcode an export target, so the OpenTelemetry Go SDK reads the standard `OTEL_EXPORTER_OTLP_*` environment variables automatically (default target: OTLP/HTTP at `localhost:4318`). -You need an OTLP-compatible backend running to receive the traces. - -## Logging - -`lstk` writes its own diagnostic logs to `lstk.log` in the same directory as the active config file. -This is separate from the LocalStack container logs (which you view with `lstk logs`). - -- The log file is created automatically and appended to across runs. -- When the file exceeds **1 MB**, it is cleared on the next run. -- Use `lstk config path` to find the config directory; `lstk.log` sits alongside `config.toml`. - -## Offline and enterprise environments - -There is no `--offline` flag. Instead, `lstk` degrades gracefully when common enterprise blockers (Docker Hub unreachable, a proxy/TLS interceptor, or an unreachable license server) prevent an internet request: + -- **Image pull**: if the image pull fails but the image is already present locally, `lstk` warns and uses the local image instead of failing. In interactive mode you can also press Esc to abort an in-progress pull and fall back to the local image. -- **License pre-flight**: when the pinned image is already present locally, `lstk` skips its pre-flight license check so a fully offline start is not blocked; the emulator validates the license itself once it starts. When a check does run, a definitive server rejection (e.g. HTTP 403/400) is still fatal, but a transport-level failure (offline, proxy, or certificate error) is treated as non-fatal and the emulator validates the license instead. The pre-flight is also skipped — with a warning — when the license server does not recognize the image *tag format* (for example a `dev` nightly or a custom internal-mirror tag): that is not a verdict on the license, so `lstk` defers to the emulator's own startup check rather than blocking the start. -- **Telemetry and update checks** are best-effort and fail silently when offline. + -Pair this behavior with a custom [`image`](#custom-container-image) that points at an internal-registry mirror or a locally loaded image to run `lstk` in an air-gapped environment. - -## Shell completions - -`lstk` includes completion scripts for bash, zsh, fish, and powershell. -If you installed via Homebrew, completions are set up automatically. - -For manual setup: - - - - -```bash -# Load in current session -source <(lstk completion bash) - -# Persist (Linux) -lstk completion bash > /etc/bash_completion.d/lstk - -# Persist (macOS with Homebrew) -lstk completion bash > $(brew --prefix)/etc/bash_completion.d/lstk -``` - - - - -```bash -# Load in current session -source <(lstk completion zsh) - -# Persist (Linux) -lstk completion zsh > "${fpath[1]}/_lstk" - -# Persist (macOS with Homebrew) -lstk completion zsh > $(brew --prefix)/share/zsh/site-functions/_lstk -``` - - - - -```bash -# Load in current session -lstk completion fish | source - -# Persist -lstk completion fish > ~/.config/fish/completions/lstk.fish -``` - - - - -Restart your shell after persisting completions. + ## FAQ -### Can I use `lstk` with Docker Compose? - -No. `lstk` manages its own Docker container directly. -If you use a `docker-compose.yml` to run LocalStack, you do not need `lstk`, and vice versa. -Do not mix `lstk start` with a Docker Compose setup; they are separate, independent methods. - -For Docker Compose configuration, see the [Docker Compose installation guide](/aws/getting-started/installation/#docker-compose). - -### Which Docker image does `lstk` use? - -It depends on the emulator type configured in your `config.toml`. -The AWS emulator uses `localstack/localstack-pro`, the Snowflake emulator uses `localstack/snowflake`, and the Azure emulator uses `localstack/localstack-azure`. -All require a valid auth token (including the free Hobby tier). -See [Emulator types](#emulator-types). - -### How do I pass configuration options like `DEBUG` or `PERSISTENCE` to the container? - -Use environment profiles in your `config.toml`. -Define the variables under an `[env.]` section and reference that name in the `env` list of your container config. -See [Passing environment variables to the container](#passing-environment-variables-to-the-container) for details. + ### How do I save and restore emulator state? Use [`lstk snapshot save`](#snapshot) to capture the running AWS emulator's state to a local file or a Cloud Pod, and [`lstk snapshot load`](#snapshot) (or the `lstk save` / `lstk load` aliases) to restore it. To drop in-memory state without writing a snapshot, use [`lstk reset`](#reset). -### How do I pin a specific LocalStack version? - -Set the `tag` field in your `config.toml` to a specific version tag: - -```toml -[[containers]] -type = "aws" -tag = "2026.4" -port = "4566" -``` - ## Troubleshooting -### Port 443 already in use - -By default, LocalStack binds to both port `4566` and port `443` inside the container (controlled by the `GATEWAY_LISTEN` variable). -On some systems, particularly Windows with Hyper-V, IIS, or VPN software, port 443 may already be in use. - -**Symptoms:** - -```text -failed to start LocalStack: Error response from daemon: ports are not available: -exposing port TCP 127.0.0.1:443 -> 127.0.0.1:0: listen tcp4 127.0.0.1:443: bind: -address already in use -``` - -**Fix:** Override `GATEWAY_LISTEN` to bind only to port 4566: - -```toml -[[containers]] -type = "aws" -tag = "latest" -port = "4566" -env = ["nossl"] - -[env.nossl] -GATEWAY_LISTEN = "0.0.0.0:4566" -``` - -This tells the container to skip the port 443 binding entirely. - -### Docker is not running - -`lstk` requires a running Docker daemon. -If Docker is not reachable, you will see an error like: - -```text -Error: runtime not healthy -``` - -**Fix:** Start Docker Desktop (macOS/Windows) or the Docker daemon (`sudo systemctl start docker` on Linux). -If you use Colima or OrbStack, make sure the VM is running. -You can also point `lstk` at a custom socket with `DOCKER_HOST`. - -### Authentication required in non-interactive mode - -When running without a TTY (e.g. in CI), `lstk` cannot open a browser for login. -If no token is found in the keyring or environment, it fails: - -```text -authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive mode -``` - -**Fix:** Set the `LOCALSTACK_AUTH_TOKEN` environment variable before running `lstk`: - -```bash -export LOCALSTACK_AUTH_TOKEN= -lstk --non-interactive start -``` - -You can find your auth token on the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). - -### License validation failed - -If your auth token is invalid, expired, or not linked to an active license, the LocalStack container exits with a license error: - -```text -The license activation failed for the following reason: -No credentials were found in the environment. -``` - -**Fix:** - -- Verify your token is valid at the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). -- Make sure the token is set correctly, either via `lstk login` or the `LOCALSTACK_AUTH_TOKEN` environment variable. -- If a stale keyring token is interfering, run `lstk logout` first and then set `LOCALSTACK_AUTH_TOKEN`. - -### Image pull failed - -If `lstk` cannot pull the Docker image, check your network connection and Docker configuration. -On corporate networks, you may need to configure Docker's proxy settings, see [How do I configure LocalStack to use my corporate HTTP and HTTPS proxy?](/aws/getting-started/faq/#how-do-i-configure-localstack-to-use-my-corporate-http-and-https-proxy). - -### Unknown environment profile - -If your container config references an `env` profile that doesn't exist, `lstk` returns: - -```text -environment "myprofile" referenced in container config not found -``` - -**Fix:** Make sure the profile name in the `env` list matches an `[env.]` section in your `config.toml`: - -```toml -[[containers]] -type = "aws" -env = ["myprofile"] # must match the section name below - -[env.myprofile] -DEBUG = "1" -``` + ### Getting help diff --git a/src/content/docs/azure/developer-tools/lstk.mdx b/src/content/docs/azure/developer-tools/lstk.mdx index 5a9be4ccb..fca4ce749 100644 --- a/src/content/docs/azure/developer-tools/lstk.mdx +++ b/src/content/docs/azure/developer-tools/lstk.mdx @@ -2,9 +2,22 @@ title: lstk CLI description: Reference guide for lstk, the modern CLI for managing LocalStack, with installation, configuration, commands, and troubleshooting. template: doc +sidebar: + order: 10 --- -import { Tabs, TabItem } from '@astrojs/starlight/components'; +import Installation from '@/components/lstk/Installation.mdx'; +import QuickStart from '@/components/lstk/QuickStart.mdx'; +import Authentication from '@/components/lstk/Authentication.mdx'; +import Configuration from '@/components/lstk/Configuration.mdx'; +import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; +import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; +import CommonCommands from '@/components/lstk/CommonCommands.mdx'; +import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; +import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; +import ShellCompletions from '@/components/lstk/ShellCompletions.mdx'; +import FaqCommon from '@/components/lstk/FaqCommon.mdx'; +import TroubleshootingCommon from '@/components/lstk/TroubleshootingCommon.mdx'; ## Introduction @@ -12,529 +25,27 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting. `lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status. -It can also save and load emulator state (as local snapshots or Cloud Pods) reset running state, run AWS CLI commands against the emulator, and manage the on-disk volume. +It can also save and load emulator state (as local snapshots or Cloud Pods) and manage the on-disk volume. Running `lstk` with no arguments takes you through the entire startup flow automatically. -`lstk` also proxies developer tools so they run directly against LocalStack: the AWS CLI (`lstk aws`), the Azure CLI (`lstk az`), Terraform (`lstk terraform`), the AWS CDK (`lstk cdk`), and the AWS SAM CLI (`lstk sam`). +`lstk` also proxies the Azure CLI (`lstk az`) so it runs directly against the Azure emulator. ## Prerequisites - [Docker](https://docs.docker.com/get-docker/) installed and running. - A [LocalStack account](https://www.localstack.cloud/pricing) with a [license](/azure/getting-started/auth-token/#managing-your-license), and `lstk` handles authentication for you (see [Authentication](#authentication)). -## Installation + - - + -```bash -brew install localstack/tap/lstk -``` - -Homebrew also installs shell completions for bash, zsh, and fish automatically. - - - - -```bash -npm install -g @localstack/lstk -``` - - - - -Download the binary for your platform from [GitHub Releases](https://github.com/localstack/lstk/releases), extract it, and place it on your `PATH`. - - - - -Verify the installation: - -```bash -lstk --version -``` - -### Updating - -`lstk` can update itself. -It detects how it was originally installed (Homebrew, npm, or binary) and uses the matching update method: - -```bash -# Check for updates without installing -lstk update --check - -# Update to the latest version -lstk update -``` - -See the [`update`](#update) command for details, including the start-time update notification. - -## Quick start - -```bash -lstk -``` - -Running `lstk` without arguments performs the full startup sequence: authenticates you automatically, pulls the latest image if needed, and starts the LocalStack container. -In an interactive terminal it launches the TUI; in a non-interactive environment it prints plain text output. - -On the very first interactive run, `lstk` prompts you to pick which emulator to run (AWS, Snowflake, or Azure) and writes your choice to `config.toml`. -See [Emulator types](#emulator-types) for the available options. - -For CI or headless environments, set `LOCALSTACK_AUTH_TOKEN` and use `--non-interactive`: - -```bash -LOCALSTACK_AUTH_TOKEN= lstk --non-interactive -``` - -CI environments require a CI Auth Token; a personal Developer Auth Token cannot be used there. - -## Authentication - -`lstk` resolves your auth token in the following order: - -1. **System keyring**: a token stored by a previous `lstk login`. -2. **`LOCALSTACK_AUTH_TOKEN` environment variable**: used only when the keyring has no token. -3. **Browser login**: triggered automatically in interactive mode when neither of the above provides a token. - -:::caution -The keyring token takes precedence over `LOCALSTACK_AUTH_TOKEN`. -If you set or change the environment variable but a keyring token already exists, the environment variable is ignored. -Run `lstk logout` to clear the stored keyring token first. -::: - -### Logging in - -```bash -lstk login -``` - -Opens a browser window for authentication and stores the resulting token in your system keyring. -This command requires an interactive terminal. -See the [`login`](#login) command for the full flow and the endpoints it uses. - -### Logging out - -```bash -lstk logout -``` - -Removes the stored credentials from the system keyring and the file-based fallback, and clears the cached license. -`logout` cannot clear a token supplied via `LOCALSTACK_AUTH_TOKEN`; if you authenticated that way, unset the variable instead. -See the [`logout`](#logout) command for the full behavior. - -### File-based token storage - -On systems where the system keyring is unavailable, `lstk` automatically falls back to storing the token in a file (`/auth-token`, mode `0600`). -You can force file-based storage by setting: - -```bash -export LSTK_KEYRING=file -``` - -## Configuration - -`lstk` uses a TOML configuration file, created automatically on first run. - -### Config file search order - -`lstk` uses the first `config.toml` it finds in this order: - -1. `./.lstk/config.toml`: project-local config in the current directory. -2. `$HOME/.config/lstk/config.toml`: user config (created here if `$HOME/.config/` exists). -3. OS default: - - **macOS**: `$HOME/Library/Application Support/lstk/config.toml` - - **Windows**: `%AppData%\lstk\config.toml` - - **Linux**: `$XDG_CONFIG_HOME/lstk/config.toml` or `$HOME/.config/lstk/config.toml` - -On first run, the config is created at path #2 if `$HOME/.config/` already exists; otherwise at the OS default (#3). - -To see the active config file path: - -```bash -lstk config path -``` - -To use a specific config file: + -```bash -lstk --config /path/to/config.toml start -``` - -### Default configuration - -The default `config.toml` created on first run: - -```toml -[[containers]] -type = "aws" # Emulator type. Supported: "aws", "snowflake", "azure" -tag = "latest" # Docker image tag, e.g. "latest", "2026.4" -port = "4566" # Host port the emulator will be accessible on -# image = "" # Full image override (e.g. an internal mirror or offline image) -# volume = "" # Host directory for persistent state (default: OS cache dir) -# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see Volumes) -# env = [] # Named environment profiles to apply (see [env.*] sections below) -# snapshot = "" # Snapshot REF to auto-load after start (AWS only) -``` - -### Config field reference - -| Field | Type | Default | Description | -|:-----------|:---------|:-----------|:-----------------------------------------------------------------------------------------------------| -| `type` | string | `"aws"` | Emulator type. One of `"aws"`, `"snowflake"`, `"azure"`. Run a single `[[containers]]` block at a time. See [Emulator types](#emulator-types). | -| `tag` | string | `"latest"` | Docker image tag (`"latest"`, `"2026.4"`, etc.). Useful for pinning a specific version. Zero-padded months (`"2026.04"`) are normalized to `"2026.4"`. | -| `port` | string | `"4566"` | Host port the emulator listens on (1–65535). The in-container port is always `4566`. | -| `image` | string | (default) | Full image reference that overrides the default Docker Hub image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, `tag` is ignored; otherwise `tag` (or `latest`) is appended. | -| `volume` | string | (OS cache) | Host directory for persistent emulator state. Defaults to `/lstk/volume/`. See also `volumes`. | -| `volumes` | string[] | `[]` | Docker-style `"host:container[:ro]"` bind mounts (e.g. init hooks). May also carry the persistence mount (target `/var/lib/localstack`). See [Volume mounts](#volume-mounts). | -| `env` | string[] | `[]` | List of named environment profiles to inject into the container (see below). | -| `snapshot` | string | `""` | Snapshot REF (e.g. `pod:my-baseline` or a local path) to auto-load after the emulator starts. AWS emulator only. See [Auto-loading a snapshot on start](#auto-loading-a-snapshot-on-start). | - -:::note -There is no `update_prompt` config key. -`lstk` always checks for available updates on startup. -Once you choose to skip a version, `lstk` records it under the `[cli]` table as `update_skipped_version` and stops prompting for that version. -This value is written automatically and is not meant to be hand-edited (see [`update`](#update)). -::: - -### Emulator types - -`lstk` can run more than one kind of emulator. -The `type` field in your `config.toml` selects which one: - -| Type | Docker image | Description | -|:------------|:------------------------------|:-------------------------------------| -| `aws` | `localstack/localstack-pro` | LocalStack AWS emulator (default). | -| `snowflake` | `localstack/snowflake` | LocalStack Snowflake emulator. | -| `azure` | `localstack/localstack-azure` | LocalStack Azure emulator. | - -On the first interactive run, `lstk` prompts you to pick an emulator (`a` for AWS, `s` for Snowflake, `z` for Azure) and writes your choice to `config.toml`. -In non-interactive mode the default `aws` emulator is used if no config file is found. - -Lifecycle commands operate on the emulators defined in your `config.toml`. -Run a single `[[containers]]` block at a time; the AWS-specific commands (`status` resources, `aws`, `reset`, `setup aws`) require an `aws` emulator to be configured. - -:::note -The AWS emulator's license is validated by `lstk` before the container starts. -The Snowflake and Azure emulators validate their own license inside the container at startup, so `lstk` skips its pre-flight license check for them. -If your license does not include the selected emulator, the container exits and `lstk` reports the missing entitlement. -::: - -### Passing environment variables to the container - -Define reusable environment profiles under `[env.]` and reference them in your container config: - -```toml -[[containers]] -type = "aws" -tag = "latest" -port = "4566" -env = ["debug", "ci"] - -[env.debug] -DEBUG = "1" -ENFORCE_IAM = "1" -PERSISTENCE = "1" - -[env.ci] -SERVICES = "s3,sqs" -EAGER_SERVICE_LOADING = "1" -``` - -When `lstk start` runs, the key-value pairs from each referenced profile are injected as environment variables into the LocalStack container. -Keys are uppercased automatically. - -:::note -If you reference an `env` profile name that doesn't exist in your config, `lstk` returns an error: `environment "..." referenced in container config not found`. -::: - -In addition to your custom profiles, `lstk` always injects several variables into the container. -See [Container-injected variables](#container-injected-variables) for the full list. - -### Custom container image - -By default the emulator image is pulled from Docker Hub (`localstack/localstack-pro`, `localstack/snowflake`, or `localstack/localstack-azure` depending on `type`). -Set `image` on a container block to override it — for example, to pull from an internal-registry mirror or to run a locally loaded image in an air-gapped environment: - -```toml -[[containers]] -type = "aws" -image = "registry.internal.example.com/localstack/localstack-pro" -tag = "2026.4" -``` - -If `image` already carries a tag (e.g. `...:2026.4`), the separate `tag` field is ignored; otherwise `tag` (or `latest`) is appended. -See [Offline and enterprise environments](#offline-and-enterprise-environments) for how `lstk` falls back to a locally present image when a pull fails. - -### Volume mounts - -Beyond the single persistence directory set by `volume`, a container block can declare arbitrary Docker-style bind mounts with `volumes`. -Each entry is a `"host:container[:ro]"` spec — useful, for example, for mounting Snowflake init hooks into `/etc/localstack/init/{boot,start,ready,shutdown}.d`: - -```toml -[[containers]] -type = "snowflake" -port = "4566" -volumes = [ - "./init:/etc/localstack/init/ready.d:ro", - "./data:/var/lib/localstack", -] -``` - -- A `volumes` entry whose container target is `/var/lib/localstack` sets the persistence directory (the same mount `volume` configures); this is what [`lstk volume path`](#volume) and [`lstk volume clear`](#volume) resolve. -- Relative host sources and a leading `~/` are resolved against the config file's directory. This differs from the legacy `volume` field, whose value is passed to Docker verbatim. -- Setting the persistence directory through both `volume` and a `volumes` entry with a different source is a validation error. - -`volume` and `volumes` overlap only for the persistence mount: `volume` can *only* set the persistence directory, while `volumes` is a superset that can also express init hooks and other mounts. - -### Using a project-local config - -Place a `.lstk/config.toml` in your project directory. -When you run `lstk` from that directory, the local config takes precedence over the global one. -This lets each project pin its own emulator type, image tag, and environment profiles. - -For example, a project that targets the Snowflake emulator can keep its own config: - -```toml -# .lstk/config.toml -[[containers]] -type = "snowflake" -port = "4566" -``` - -An AWS project might instead pin a specific image tag and enable a debug profile: - -```toml -# .lstk/config.toml -[[containers]] -type = "aws" -tag = "2026.4" -port = "4566" -env = ["dev"] - -[env.dev] -DEBUG = "1" -PERSISTENCE = "1" -``` + ## Commands -`lstk` uses a flat command structure. -Running `lstk` with no command is equivalent to `lstk start`. - -### `start` - -Start the LocalStack emulator. -Launches the TUI in interactive terminals and prints plain output otherwise. -`lstk start` launches the emulator defined in the first `[[containers]]` entry of the resolved `config.toml` (not necessarily AWS). - -```bash -lstk start -lstk start --persist -lstk start --non-interactive -``` - -| Option | Description | -|:--------------------|:-------------------------------------------------------------------------------| -| `--persist` | Persist emulator state across restarts (sets `LOCALSTACK_PERSISTENCE=1` in the container) | -| `--snapshot ` | Auto-load this snapshot after the emulator starts, overriding the configured `snapshot` for one run (AWS only) | -| `--no-snapshot` | Skip auto-loading the configured `snapshot` for this run | -| `--non-interactive` | Disable the interactive TUI and use plain output | - -`lstk start` forwards host environment variables prefixed with `LOCALSTACK_` to the emulator (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token `lstk` resolved). See [Container-injected variables](#container-injected-variables). - -By default the emulator starts with a fresh state on every run. -Pass `--persist` to keep data across restarts: `lstk` injects `LOCALSTACK_PERSISTENCE=1` into the container so state is written to the mounted [`volume`](#config-field-reference) and reloaded on the next start. -When persistence is active, the AWS emulator's startup summary includes a `• Persistence: Enabled` line. - -```bash -# Start with persistent state -lstk start --persist -``` - -:::note -`--persist` is a flag on `start` (and the bare `lstk` command) and on [`restart`](#restart). -For finer-grained control, you can also set `PERSISTENCE = "1"` in an environment profile (see [Passing environment variables to the container](#passing-environment-variables-to-the-container)). -::: - -#### Auto-loading a snapshot on start - -For the **AWS emulator**, you can have `lstk` load a snapshot automatically every time it starts the emulator. -Set the `snapshot` field on the container block to any load REF (a `pod:` Cloud Pod or a local path): - -```toml -[[containers]] -type = "aws" -port = "4566" -snapshot = "pod:my-baseline" -``` - -The snapshot is loaded only when the emulator is **freshly started** this run; if it is already running, the auto-load is skipped. -Override it for a single run with `--snapshot REF`, or skip it entirely with `--no-snapshot`: - -```bash -# Start and load a different snapshot for this run only -lstk start --snapshot pod:other-baseline - -# Start without loading the configured snapshot -lstk start --no-snapshot -``` - -The `snapshot` field is only read on start; [`snapshot save`](#snapshot-save) never writes it back into your config. - -### `stop` - -Stop the running LocalStack emulator. -Stops every emulator container defined in the resolved `config.toml` (the `[[containers]]` entries), with a 30-second stop timeout per container. - -```bash -lstk stop -lstk stop --non-interactive -``` - -`stop` fails fast if the Docker runtime is not healthy (for example, Docker is not running), or if a configured emulator is not currently running (`LocalStack is not running`). -In an interactive terminal it shows an animated "Stopping LocalStack..." spinner and a styled confirmation; in non-interactive mode it prints the same progress and result as plain text. - -### `restart` - -Stop and restart the LocalStack emulator. -Performs a stop of the running emulator followed by a fresh start, using the same auth, config, and Docker settings as [`start`](#start). -Launches the TUI in interactive terminals and prints plain output otherwise. - -```bash -lstk restart -lstk restart --persist -``` - -| Option | Description | -|:-------------|:--------------------------------------------| -| `--persist` | Persist emulator state across the restart | - -By default, emulator state is **not** retained across the restart and the container starts clean. -Pass `--persist` to keep the emulator's state so it survives the restart. - -### `status` - -Show the status of a running emulator and its deployed resources. -Before contacting the emulator, `lstk` checks that the Docker runtime is healthy; if it is not, the command reports `runtime not healthy` and exits with a non-zero status. - -```bash -lstk status -lstk --non-interactive status -``` - -For each emulator configured in your `config.toml` (the `[[containers]]` entries), `status` reports whether it is running and, if so, prints an instance summary: - -```text -LocalStack AWS Emulator is running -• Endpoint: localhost:4566 -• Persistence: Enabled -• Container: localstack-aws -• Version: 4.0.0 -• Uptime: 1h 12m 4s -``` - -- **Endpoint** is the live `host:port`, queried from Docker, so it stays correct even if the configured `port` was changed while the container kept running. -- **Persistence** appears only for the AWS emulator and only when persistence is enabled. -- **Uptime** is computed from the container's start time and is omitted if it cannot be determined. - -If an emulator is not running, `status` prints an error and exits non-zero without checking the remaining emulators: - -```text -LocalStack AWS Emulator is not running - - Start LocalStack: lstk - See help: lstk -h -``` - -For the **AWS emulator**, `status` additionally lists deployed resources. -When resources exist it prints a summary line followed by a table; when none exist it prints `No resources deployed`. - -```text -~ 3 resources · 2 services - -Service Resource Region Account -S3 my-bucket us-east-1 000000000000 -SQS my-queue us-east-1 000000000000 -``` - -In an interactive terminal the output is rendered through the TUI; in non-interactive mode (or with `--non-interactive`) the same content is printed as plain text, with the resource table shown at full width when stdout is not a TTY. -The Snowflake and Azure emulators show the instance summary only and never report resources. - -### `logs` - -Show or stream emulator logs. - -```bash -lstk logs [options] -``` - -| Option | Description | -|:------------|:-----------------------------------------| -| `--follow`, `-f` | Stream logs in real-time. Without this flag, `lstk` prints the currently available logs and exits. | -| `--verbose`, `-v` | Show all logs without filtering. By default, `lstk` drops noisy lines (internal request logs, provider chatter); `--verbose` shows every line verbatim. | - -By default, `lstk logs` reads from the first configured emulator container and applies a noise filter. -In an interactive terminal, lines are color-coded by log level (`DEBUG`, `INFO`, `WARN`, `ERROR`); in non-interactive mode, raw log lines are written to stdout. - -Example: - -```bash -# Print current filtered logs and exit -lstk logs - -# Stream filtered logs in real-time -lstk logs --follow - -# Stream all logs without filtering -lstk logs --follow --verbose -``` - -### `aws` - -Run AWS CLI commands against the running LocalStack emulator. -`lstk aws` proxies your host `aws` CLI with the endpoint, credentials, and region pre-configured, so you don't have to pass `--endpoint-url` or set test credentials yourself. - -```bash -lstk aws s3 ls -lstk aws sqs list-queues -lstk aws s3 mb s3://my-bucket -``` - -It is equivalent to running: - -```bash -aws --endpoint-url http://localhost:4566 -``` - -with `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_DEFAULT_REGION` set automatically. - -Everything after `lstk aws` is forwarded verbatim to the host `aws` binary, including AWS CLI flags such as `--region` or `--output`. -The exit code and `stdout`/`stderr` of the underlying `aws` process are passed through unchanged, so piping and interactive subcommands work as expected. - -| Option | Description | -|:--------------------|:----------------------------------------------------------------------------------------------------| -| `--non-interactive` | Suppress the loading spinner. Unlike other commands, this flag is stripped before invoking `aws` (not forwarded). | - -:::note -`lstk aws` does not start the emulator. -The AWS emulator must already be running (`lstk start`), Docker must be healthy, and the host `aws` CLI must be installed and on your `PATH`. -::: - -#### Credentials and region - -`lstk aws` injects credentials in one of two ways: - -- **Profile mode**: if a complete `localstack` profile exists in both `~/.aws/config` and `~/.aws/credentials`, `lstk` appends `--profile localstack` and lets `aws` read the region, credentials, and endpoint from that profile. -- **Profile-less mode**: if the profile is not present, `lstk` runs `aws` with `AWS_ACCESS_KEY_ID=test`, `AWS_SECRET_ACCESS_KEY=test`, and `AWS_DEFAULT_REGION=us-east-1` injected only when those variables are not already set in your environment. In this mode it also prints an informational note: `No AWS profile found, run 'lstk setup aws'`. - -Run [`lstk setup aws`](#setup) to create the `localstack` profile for use with the AWS CLI and SDKs. - -#### Endpoint resolution - -By default, `lstk` probes whether `localhost.localstack.cloud` resolves to `127.0.0.1` and uses `localhost.localstack.cloud:` if so, otherwise it falls back to `127.0.0.1:`. -Set [`LOCALSTACK_HOST`](#environment-variables) to override the host:port used to reach LocalStack and skip the DNS probe. -The port comes from the AWS container's `port` in `config.toml` (default `4566`). + ### `az` @@ -571,852 +82,54 @@ Interception changes global state that affects every `az` command in any termina Use the isolated `lstk az ` mode unless you specifically need plain `az` to target LocalStack. ::: -### `terraform` - -Run Terraform against LocalStack, using LocalStack endpoints as AWS provider overrides. -`lstk terraform` (alias `lstk tf`) generates a provider-override file and forwards your arguments to the real `terraform` binary. - :::note -`lstk terraform` currently targets the AWS emulator only. -To use Terraform with the other emulators, see the relevant emulator docs. +Like the other CLI proxies, `lstk az` does not start the emulator — start it first with `lstk start`. +It requires the `az` CLI to be installed and on your `PATH`. ::: -```bash -lstk terraform init -lstk terraform --region us-west-2 plan -lstk tf apply -``` - -lstk-specific flags must appear **before** the Terraform action: + -| Option | Default | Description | -|:------------------|:---------------------|:-----------------------------------------| -| `--region ` | `us-east-1` | Deployment region. | -| `--account ` | `test` | Target AWS account id (12 digits). | + -Relevant environment variables: `AWS_ENDPOINT_URL` (override the auto-resolved endpoint), `LSTK_TF_CMD` (binary to invoke, e.g. `tofu`; default `terraform`), `LSTK_TF_OVERRIDE_FILE_NAME` (override file name; default `localstack_providers_override.tf`), `LSTK_TF_DRY_RUN` (generate the override file but do not run Terraform), `AWS_REGION` (fallback for `--region`), and `AWS_ACCESS_KEY_ID` (fallback for `--account`). - -### `cdk` - -Run the AWS CDK against LocalStack. -Requires the AWS CDK CLI version `2.177.0` or newer on your `PATH`. - -```bash -lstk cdk bootstrap -lstk cdk --region us-west-2 deploy -lstk cdk synth -``` - -The only lstk-specific flag (before the CDK action) is `--region ` (default `us-east-1`); CDK always targets the default LocalStack account `000000000000`, so there is no `--account` flag. -Relevant environment variables: `AWS_ENDPOINT_URL`, `AWS_ENDPOINT_URL_S3`, `LSTK_CDK_CMD` (default `cdk`), and `AWS_REGION`. - -### `sam` +### `setup` -Run the AWS SAM CLI against LocalStack. -Requires the AWS SAM CLI version `1.95.0` or newer on your `PATH` (older versions ignore `AWS_ENDPOINT_URL` and would target real AWS). +Set up CLI integration for an emulator type. +`lstk setup` is a grouping command with no action of its own; on the Azure emulator, the work is done by its subcommand `setup azure`. ```bash -lstk sam build -lstk sam --region us-west-2 deploy -lstk sam validate +lstk setup azure ``` -lstk-specific flags (before the SAM action): `--region ` (default `us-east-1`) and `--account ` (12 digits, default `000000000000`). -Relevant environment variables: `AWS_ENDPOINT_URL`, `AWS_ENDPOINT_URL_S3`, `LSTK_SAM_CMD` (default `sam`), `AWS_REGION` (fallback for `--region`), and `AWS_ACCESS_KEY_ID` (fallback for `--account`). - -:::note -Compared with `samlocal`, image/container-based Lambda (ECR) deploys and nested CloudFormation stacks are not supported; use `samlocal` for those workflows. -::: - -:::note -Like `lstk aws`, the `az`, `terraform`, `cdk`, and `sam` proxies do not start the emulator — start it first with `lstk start`. -Each requires the corresponding third-party CLI to be installed and on your `PATH`. -::: - -### `snapshot` - -Manage emulator snapshots. -A snapshot captures the running emulator's state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or in your own S3 bucket. -The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`. - -:::note -Snapshots are best supported on the **AWS emulator**. -`snapshot save`/`load` (and the `save`/`load` aliases) also work for the Snowflake and Azure emulators, but their snapshot support is experimental and not fully tested — `lstk` prints a warning such as `Snapshot support for the snowflake emulator is experimental and not fully tested.` -[`reset`](#reset) remains **AWS-only** and errors out with `reset is only supported for the AWS emulator` otherwise. -::: - -#### `snapshot save` +#### `setup azure` -Save a snapshot of the running emulator's state. -The emulator must already be running; this command does **not** auto-start it. +Prepare an isolated Azure CLI configuration directory that routes [`lstk az`](#az) commands to the LocalStack Azure emulator. +Your global `~/.azure` configuration is left untouched. ```bash -# Auto-named snapshot file in the current directory -lstk snapshot save - -# Save to a specific local path -lstk snapshot save ./my-snapshot - -# Save to a Cloud Pod on the LocalStack platform (requires auth) -lstk snapshot save pod:my-baseline - -# Save to your own S3 bucket (pod name is auto-generated if omitted) -lstk snapshot save my-pod s3://my-bucket/prefix +lstk setup azure +# alias: +lstk setup az ``` -The optional `[destination]` argument takes one of these forms: - -| Destination | Description | -|:--------------------------------|:---------------------------------------------------------------------------------------------------| -| (omitted) | Auto-generates a timestamped snapshot file in the current directory (`./snapshot--.snapshot`). | -| local path | Writes a snapshot archive to that path. The `.snapshot` extension is forced. | -| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. | -| ` s3://bucket/prefix` | Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See [S3 remotes](#s3-remotes). | - -Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not. - -| Option | Description | -|:--------------------|:--------------------------------------------------------------------------------------------------| -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` destinations). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot load` - -Load a snapshot into the emulator, **auto-starting it first** if it is not already running. - -```bash -# Load a local snapshot by path or name -lstk snapshot load my-baseline -lstk snapshot load ./checkpoint - -# Load from a Cloud Pod (requires auth) -lstk snapshot load pod:my-baseline - -# Load from your own S3 bucket (pod name is required) -lstk snapshot load my-pod s3://my-bucket/prefix +`setup azure` registers a custom Azure cloud (`LocalStack`) whose endpoints point at the LocalStack Azure emulator, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login — all inside a dedicated config directory under the `lstk` config dir (via `AZURE_CONFIG_DIR`). +It requires the `az` CLI to be installed and a running LocalStack Azure emulator. -# Control how the snapshot merges with running state -lstk snapshot load pod:my-baseline --merge=overwrite -``` +To instead redirect your **global** `az` (so existing scripts run unmodified against LocalStack), see [`lstk az start-interception`](#az). -The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod. -To load from S3, pass the pod name followed by an `s3://bucket/prefix` location (see [S3 remotes](#s3-remotes)). + -| Option | Description | -|:---------------------|:--------------------------------------------------------------------------------------------------------| -| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. | -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` sources). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + -- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap. -- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state. -- `service-merge`: the snapshot wins per resource; non-overlapping resources are combined. + -The aliases behave identically: +## FAQ -```bash -lstk save pod:my-baseline -lstk load ./checkpoint -``` + -#### `snapshot list` +## Troubleshooting -List the Cloud Pod snapshots available on the LocalStack platform. -By default, only snapshots you created are listed; pass `--all` to include every snapshot in your organization. -This subcommand operates on Cloud Pods, so it requires authentication. - -```bash -# Snapshots you created -lstk snapshot list - -# Every snapshot in your organization -lstk snapshot list --all - -# List snapshots in your own S3 bucket (requires a running emulator) -lstk snapshot list s3://my-bucket/prefix -``` - -Passing an `s3://bucket/prefix` location lists snapshots stored in your own S3 bucket instead of the platform (see [S3 remotes](#s3-remotes)). Unlike the platform listing, this queries the emulator, so it requires a running emulator. - -| Option | Description | -|:--------------------|:----------------------------------------------------------------| -| `--all` | List all snapshots in your organization, not just your own. | -| `--profile ` | AWS profile to read S3 credentials from (used only with an `s3://` location). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot remove` - -Delete a Cloud Pod snapshot from the LocalStack platform. -Only cloud snapshots (the `pod:` prefix) can be removed; local snapshots are plain files you delete yourself. -This operation cannot be undone. - -```bash -lstk snapshot remove pod:my-baseline - -# Skip the confirmation prompt (required in non-interactive mode) -lstk snapshot remove pod:my-baseline --force -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -| Option | Description | -|:----------|:------------------------------------------------------------------------| -| `--force` | Skip the confirmation prompt. Required when running non-interactively. | - -#### `snapshot show` - -Show metadata for a single Cloud Pod snapshot on the LocalStack platform: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). -This subcommand is cloud-only and requires authentication. - -```bash -lstk snapshot show pod:my-baseline -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -#### S3 remotes - -`snapshot save`, `load`, and `list` can target a snapshot stored in your **own S3 bucket** by passing an `s3://bucket/prefix` location. -The pod name (the snapshot's identity within the bucket) is a positional separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`. - -```bash -lstk snapshot save my-pod s3://my-bucket/prefix -lstk snapshot load my-pod s3://my-bucket/prefix -lstk snapshot list s3://my-bucket/prefix -``` - -Credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (plus optional `AWS_SESSION_TOKEN`) environment variables, otherwise the profile named by `AWS_PROFILE`. -Only static credentials are supported (no SSO, assume-role, or `credential_process`), and credentials must never be embedded in the URL. - -`lstk` runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo. -Because the transfer is performed by the emulator (not the CLI), S3 remotes require a **running emulator**, and `list s3://…` in particular queries the emulator rather than the platform API. - -:::note -`remove` and `show` do not support S3; they operate on Cloud Pods only. -::: - -### `reset` - -Discard the running AWS emulator's in-memory state (all created resources such as S3 buckets and Lambda functions are dropped). -The emulator **keeps running**; only its state is cleared. - -```bash -lstk reset -lstk reset --force -``` - -| Option | Description | -|:----------|:-------------------------------------------------------------------| -| `--force` | Skip the confirmation prompt. Required in non-interactive mode. | - -In interactive mode, `reset` prompts for confirmation before clearing state. -In non-interactive mode it fails unless `--force` is passed: - -```text -reset requires confirmation; use --force to skip in non-interactive mode -``` - -:::note -`reset` clears in-memory state only. -It does **not** wipe the on-disk volume (certificates, persistence data, cached tools). -To clear that, stop the emulator and run [`lstk volume clear`](#volume). -::: - -### `volume` - -Manage the emulator volume: the host directory that holds persistent state such as certificates, downloaded tools, and persistence data. - -```bash -lstk volume path -lstk volume clear [options] -``` - -#### `volume path` - -Prints the resolved volume directory for every emulator in your config, one per line. -With the default config (a single `aws` emulator) it prints one path. -Each path is the container's configured `volume` value, or the default OS cache location if `volume` is unset (`~/Library/Caches/lstk/volume/localstack-aws` on macOS, `~/.cache/lstk/volume/localstack-aws` on Linux). - -```bash -# Print the volume directory for each configured emulator -lstk volume path -``` - -#### `volume clear` - -Removes all data from the emulator volume directory, resetting cached state. -It operates on all configured emulators by default, or a single one with `--type`. -Before clearing, it lists each target as `: ()`. - -| Option | Description | -|:----------------|:-------------------------------------------| -| `--force` | Skip the confirmation prompt | -| `--type ` | Clear only the emulator of this type | - -```bash -# Clear all configured emulator volumes (prompts for confirmation) -lstk volume clear - -# Clear only the AWS emulator volume -lstk volume clear --type aws - -# Skip the confirmation prompt -lstk volume clear --force - -# Clear without prompting in a non-interactive environment -lstk volume clear --type snowflake --force -``` - -In an interactive terminal, `lstk volume clear` prompts `Clear volume data? This cannot be undone` before deleting anything; choosing **NO** or pressing Ctrl+C cancels with no changes. -In non-interactive mode, `--force` is required, otherwise the command fails with `volume clear requires confirmation; use --force to skip in non-interactive mode`. - -:::caution -If the volume contains files owned by `root` (created by Docker), clearing fails with a permission error. -Re-run with elevated privileges: - -```bash -sudo lstk volume clear -``` -::: - -### `login` - -Authenticate with LocalStack via a browser-based device authorization flow and store the resulting credential in your system keyring. -This command requires an interactive terminal. - -```bash -lstk login -``` - -`lstk` opens your default browser to the LocalStack Web Application, shows a one-time code, and waits for you to approve the request. -If the browser cannot open automatically, `lstk` prints the URL to visit manually. -On success it stores the **license token** returned by the platform (not the raw browser bearer token). - -If you are already authenticated — either `LOCALSTACK_AUTH_TOKEN` is set or a token already exists in storage — `login` prints `You're already logged in` and exits without starting a new flow. - -In non-interactive mode (piped output, CI, or `--non-interactive`), `login` fails with `login requires an interactive terminal`. -The `--config ` flag selects which `config.toml` is loaded, which affects `keyring`, `web_app_url`, and `api_endpoint` resolution. - -:::note -If you approve the request in the browser only *after* pressing a key in the terminal, `lstk` reports `auth request not confirmed - please complete the authentication in your browser`. -Re-run `lstk login` and approve in the browser before continuing. -::: - -The credential is written to the system keyring (service `lstk`, key `lstk.auth-token`). -When the keyring is unavailable — or `LSTK_KEYRING=file` is set — `lstk` stores it in a file at `/auth-token` (mode `0600`) instead. - -Endpoints used by the flow can be overridden via config or environment: - -| Config key | Env var | Default | Description | -|:---------------|:---------------------|:---------------------------------|:-----------------------------------------------------------------------------| -| `keyring` | `LSTK_KEYRING` | (system keyring) | Set to `file` to force file-based token storage instead of the OS keyring. | -| `web_app_url` | `LSTK_WEB_APP_URL` | `https://app.localstack.cloud` | Base URL used to build the browser authorization link. | -| `api_endpoint` | `LSTK_API_ENDPOINT` | `https://api.localstack.cloud` | LocalStack platform API endpoint used for the device flow and license token. | - -```bash -# Force file-based token storage during login -LSTK_KEYRING=file lstk login - -# Use a specific config file -lstk --config ./.lstk/config.toml login -``` - -### `logout` - -Remove stored authentication credentials. - -```bash -lstk logout -lstk logout --non-interactive -``` - -`logout` deletes the auth token from your system keyring (falling back to the file-based token at `/auth-token` when the keyring is unavailable or `LSTK_KEYRING=file` is set) and removes the cached license file. -On success it prints `Logged out successfully`. - -The outcome depends on how you are authenticated: - -| Situation | Behavior | -|:----------|:---------| -| A token is stored (from `lstk login`) | The token is deleted from the keyring and file fallback, the cached license is removed, and `lstk` prints `Logged out successfully`. | -| No stored token, but `LOCALSTACK_AUTH_TOKEN` is set | Nothing is deleted. `lstk` prints a note that you are authenticated via the environment variable and to unset it to log out. | -| No stored token and no `LOCALSTACK_AUTH_TOKEN` | `lstk` prints `Not currently logged in` and exits successfully. | - -:::note -`logout` never clears the `LOCALSTACK_AUTH_TOKEN` environment variable, and it does not stop running emulators. -If a LocalStack emulator is still running after logout, `lstk` prints a note reminding you it is running in the background; run `lstk stop` to stop it. -::: - -### `setup` - -Set up CLI integration for an emulator type. -`lstk setup` is a grouping command with no action of its own; the work is done by its subcommands, `setup aws` and `setup azure`. - -```bash -lstk setup aws -lstk setup azure -``` - -#### `setup aws` - -Create or update a `localstack` profile in `~/.aws/config` and `~/.aws/credentials` so the AWS CLI and SDKs can target LocalStack. - -```bash -lstk setup aws -lstk setup aws --force -``` - -| Option | Description | -|:----------|:----------------------------------------------------------------------------------------------| -| `--force` | Overwrite an existing `localstack` profile whose values differ, and skip the confirmation prompt. | - -On an interactive terminal it prompts (Y/n) before making changes. -In non-interactive mode (piped output, CI, or `--non-interactive`) it writes the profile with defaults without prompting and exits `0`; a failed write or check returns a non-zero exit code so automation notices. -Overwriting an existing `localstack` profile whose values differ requires `--force` (which also skips the interactive prompt); creating a fresh profile, completing a partial one, or leaving an already-correct profile in place never needs it. - -It writes the following profile (existing unrelated profiles are preserved): - -```ini -# ~/.aws/config -[profile localstack] -region = us-east-1 -output = json -endpoint_url = http://localhost.localstack.cloud:4566 - -# ~/.aws/credentials -[localstack] -aws_access_key_id = test -aws_secret_access_key = test -``` - -Afterwards, target LocalStack by passing `--profile localstack` or exporting `AWS_PROFILE`: - -```bash -export AWS_PROFILE=localstack -aws s3 ls -``` - -The endpoint host is resolved automatically: `lstk` probes `localhost.localstack.cloud` and uses it when it resolves to `127.0.0.1`, otherwise it falls back to `127.0.0.1`. -Set [`LOCALSTACK_HOST`](#environment-variables) to override the host and port written into the profile. -The port comes from your AWS emulator's configured `port` (default `4566`); if no `aws` emulator is configured, the command fails with `no aws emulator configured`. - -If the `localstack` profile is already configured correctly, `lstk` reports `LocalStack AWS profile is already configured.` and makes no changes. - -:::note -The former `lstk config profile` command has been removed; use `lstk setup aws`. -::: - -#### `setup azure` - -Prepare an isolated Azure CLI configuration directory that routes [`lstk az`](#az) commands to the LocalStack Azure emulator. -Your global `~/.azure` configuration is left untouched. - -```bash -lstk setup azure -# alias: -lstk setup az -``` - -`setup azure` registers a custom Azure cloud (`LocalStack`) whose endpoints point at the LocalStack Azure emulator, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login — all inside a dedicated config directory under the `lstk` config dir (via `AZURE_CONFIG_DIR`). -It requires the `az` CLI to be installed and a running LocalStack Azure emulator. - -To instead redirect your **global** `az` (so existing scripts run unmodified against LocalStack), see [`lstk az start-interception`](#az). - -### `config` - -Manage CLI configuration. -`config` has no behavior of its own; run it with a subcommand. - -#### `config path` - -Print the resolved path to the active `config.toml`. - -```bash -lstk config path -``` - -This subcommand is read-only: it never creates or initializes a config file. -If `--config ` is set, it prints that path verbatim. -Otherwise it prints the already-loaded config path, the first existing config in the search order, or the path where a config would be created on first run. - -### `update` - -Check for and apply updates to the `lstk` CLI itself. -`lstk` auto-detects how it was installed (Homebrew, npm, or direct binary) and updates using that same method. -Development builds (version `dev`) are skipped, and updates are checked against the latest [GitHub release](https://github.com/localstack/lstk/releases/latest). - -```bash -lstk update [options] -``` - -| Option | Description | -|:--------------------|:-----------------------------------------------------------------| -| `--check` | Check for updates without installing them | -| `--non-interactive` | Use plain output instead of the TUI (update logic unchanged) | - -Examples: - -```bash -# Check for updates without installing -lstk update --check - -# Update to the latest version -lstk update - -# Update with plain (non-TUI) output -lstk update --non-interactive -``` - -By install method: - -- **Homebrew** (binary under a `Caskroom` path): runs `brew upgrade localstack/tap/lstk`. -- **npm** (binary under `node_modules`): runs `npm install -g @localstack/lstk@latest`. -- **Binary** (anything else): downloads the release asset for your OS/arch from GitHub, extracts it, and replaces the running executable in place. - -With `--check`, `lstk` only reports whether a newer version is available and exits without downloading or installing anything. - -:::note -Set `LSTK_GITHUB_TOKEN` to send an authenticated GitHub request and avoid API rate limits during update checks. -It is optional; updates also work unauthenticated. -::: - -#### Update notification on start - -Separately from `lstk update`, `lstk` checks for a newer version when you run `lstk start` (the default command), using a short timeout that fails silently if GitHub is unreachable. - -In an interactive terminal, when an update is available `lstk` prints the new version and a release-notes link, then prompts: - -```text -Update lstk to latest version? -> Update now [U] - Remind me next time [R] - Skip this version [S] -``` - -- **Update now [U]**: downloads and applies the update, then asks you to re-run your command. -- **Remind me next time [R]**: does nothing; you are reminded on the next run. -- **Skip this version [S]**: records the version in `config.toml` so you are not prompted about it again. - -In non-interactive mode the notification is not a prompt — `lstk` emits a single note (`Update available: (run lstk update)`) and continues. - -When you choose **Skip this version**, `lstk` writes the skipped version under a `[cli]` table: - -```toml -[cli] -update_skipped_version = "0.5.0" -``` - -While this value matches the latest available version, the start-time update notification for that version is suppressed. -This key is managed automatically and is not intended to be edited by hand. - -### `completion` - -Generate shell completion scripts. - -```bash -lstk completion [bash|zsh|fish|powershell] -``` - -See [Shell completions](#shell-completions) for setup instructions. - -## Global options - -These options are available for all commands: - -| Option | Description | -|:--------------------|:---------------------------------------------------------------------------| -| `--config ` | Path to a specific TOML config file | -| `--non-interactive` | Disable the interactive TUI, use plain output | -| `--json` | Output in JSON format (only supported by some commands, e.g. the tool proxies) | -| `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) | -| `--snapshot ` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run) | -| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`) | -| `-v`, `--version` | Print the version and exit | -| `-h`, `--help` | Print help and exit | - -## Interactive and non-interactive mode - -`lstk` automatically selects its output mode: - -- **Interactive mode** (TUI): used when both stdin and stdout are connected to a terminal. - Commands like `start`, `stop`, `restart`, `status`, `login`, `update`, and the confirmation prompts of `reset`/`volume clear` display a Bubble Tea-powered terminal UI. -- **Non-interactive mode** (plain text): used when the output is piped, redirected, or running in CI. - Force this in a TTY with `--non-interactive`. - -```bash -# Force plain output even in an interactive terminal -lstk --non-interactive start -``` - -:::note -`lstk login` requires an interactive terminal; if you need to authenticate in CI, set `LOCALSTACK_AUTH_TOKEN` instead. -Commands that mutate state without prompting in CI (`reset`, `volume clear`) require `--force`. -`lstk setup aws` works non-interactively — it writes the profile with defaults and needs `--force` only to overwrite a conflicting `localstack` profile. -::: - -## Environment variables - -The following environment variables configure `lstk` itself (not the LocalStack container): - -| Variable | Description | -|:-------------------------------|:-----------------------------------------------------------------------------------------------------------------| -| `LOCALSTACK_AUTH_TOKEN` | Auth token for non-interactive runs or to skip browser login. Used when no keyring token is stored. | -| `LOCALSTACK_HOST` | Override the host (and optional port) used when resolving and printing the emulator endpoint, and when writing the AWS CLI profile. Bypasses the `localhost.localstack.cloud` DNS probe. | -| `LOCALSTACK_DISABLE_EVENTS` | Set to `1` to disable anonymous telemetry event reporting. | -| `DOCKER_HOST` | Override the Docker daemon socket (e.g. `unix:///home/user/.colima/default/docker.sock`). | -| `LSTK_KEYRING` | Set to `file` to force file-based token storage instead of the system keyring. | -| `LSTK_OTEL` | Set to `1` to enable OpenTelemetry trace export (disabled by default). See [OpenTelemetry tracing](#opentelemetry-tracing). | -| `LSTK_GITHUB_TOKEN` | Optional GitHub token used when checking for or downloading `lstk` updates (raises GitHub API rate limits). | -| `LSTK_API_ENDPOINT` | Override the LocalStack platform API base URL. Default: `https://api.localstack.cloud`. | -| `LSTK_WEB_APP_URL` | Override the LocalStack Web Application URL used for browser login. Default: `https://app.localstack.cloud`. | - -When `DOCKER_HOST` is not set, `lstk` tries the default Docker socket and then probes common alternatives (Colima at `~/.colima/default/docker.sock`, OrbStack at `~/.orbstack/run/docker.sock`). - -When `LSTK_OTEL` is enabled, the standard `OTEL_EXPORTER_OTLP_*` environment variables are honored by the OpenTelemetry SDK. - -### Container-injected variables - -`lstk` injects several environment variables into the LocalStack container on every start, in addition to any profiles you configure: - -| Variable | Default value | Description | -|:-----------------------------|:-------------------------------------------------|:------------------------------------------------| -| `LOCALSTACK_AUTH_TOKEN` | (your resolved token) | Passed from the CLI to activate the license. | -| `GATEWAY_LISTEN` | `:4566,:443` | Ports the emulator binds inside the container. | -| `MAIN_CONTAINER_NAME` | `localstack-aws` | Container name for internal references. | -| `LOCALSTACK_HOST` | `localhost.localstack.cloud:` | Hostname/port the emulator advertises. | -| `LOCALSTACK_PERSISTENCE` | `1` (only with `--persist`) | Enables state persistence across restarts. | -| `LOCALSTACK_CLIENT_NAME` | `lstk` | Identifies the client that started the emulator. | -| `LOCALSTACK_CLIENT_VERSION`| (the `lstk` version) | Version of the client that started the emulator. | - -When a Docker socket is detected it is bind-mounted into the container and `DOCKER_HOST=unix:///var/run/docker.sock` is injected so the emulator can spawn its own containers. -`lstk` also forwards host environment variables matching `CI` and `LOCALSTACK_*` (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token resolved by `lstk`). - -The container also gets port mappings for `4566`, `443`, and the service port range `4510-4559`. - -:::note -`GATEWAY_LISTEN` is read from the container's resolved environment (set it via an `[env.*]` profile), not hardcoded. -Beyond controlling which ports the emulator binds, its host part sets the host publish IP for all published ports: a value like `GATEWAY_LISTEN = "0.0.0.0:4566,0.0.0.0:443"` exposes the emulator beyond loopback (e.g. on a remote host), whereas the default binds to `127.0.0.1` only. -::: - -## OpenTelemetry tracing - -`lstk` can export traces of its own command execution over OTLP/HTTP. -Tracing is **disabled by default**. -Enable it with: - -```bash -LSTK_OTEL=1 lstk start -``` - -When enabled, every command is wrapped in a span (e.g. `lstk.start`) recording the exit code and any error. -`lstk` does not hardcode an export target, so the OpenTelemetry Go SDK reads the standard `OTEL_EXPORTER_OTLP_*` environment variables automatically (default target: OTLP/HTTP at `localhost:4318`). -You need an OTLP-compatible backend running to receive the traces. - -## Logging - -`lstk` writes its own diagnostic logs to `lstk.log` in the same directory as the active config file. -This is separate from the LocalStack container logs (which you view with `lstk logs`). - -- The log file is created automatically and appended to across runs. -- When the file exceeds **1 MB**, it is cleared on the next run. -- Use `lstk config path` to find the config directory; `lstk.log` sits alongside `config.toml`. - -## Offline and enterprise environments - -There is no `--offline` flag. Instead, `lstk` degrades gracefully when common enterprise blockers (Docker Hub unreachable, a proxy/TLS interceptor, or an unreachable license server) prevent an internet request: - -- **Image pull**: if the image pull fails but the image is already present locally, `lstk` warns and uses the local image instead of failing. In interactive mode you can also press Esc to abort an in-progress pull and fall back to the local image. -- **License pre-flight**: when the pinned image is already present locally, `lstk` skips its pre-flight license check so a fully offline start is not blocked; the container validates its own bundled license at startup. When a check does run, a definitive server rejection (e.g. HTTP 403/400) is still fatal, but a transport-level failure (offline, proxy, or certificate error) is treated as non-fatal and the container validates its own license instead. -- **Telemetry and update checks** are best-effort and fail silently when offline. - -Pair this behavior with a custom [`image`](#custom-container-image) that points at an internal-registry mirror or a locally loaded image to run `lstk` in an air-gapped environment. - -## Shell completions - -`lstk` includes completion scripts for bash, zsh, fish, and powershell. -If you installed via Homebrew, completions are set up automatically. - -For manual setup: - - - - -```bash -# Load in current session -source <(lstk completion bash) - -# Persist (Linux) -lstk completion bash > /etc/bash_completion.d/lstk - -# Persist (macOS with Homebrew) -lstk completion bash > $(brew --prefix)/etc/bash_completion.d/lstk -``` - - - - -```bash -# Load in current session -source <(lstk completion zsh) - -# Persist (Linux) -lstk completion zsh > "${fpath[1]}/_lstk" - -# Persist (macOS with Homebrew) -lstk completion zsh > $(brew --prefix)/share/zsh/site-functions/_lstk -``` - - - - -```bash -# Load in current session -lstk completion fish | source - -# Persist -lstk completion fish > ~/.config/fish/completions/lstk.fish -``` - - - - -Restart your shell after persisting completions. - -## FAQ - -### Can I use `lstk` with Docker Compose? - -No. `lstk` manages its own Docker container directly. -If you use a `docker-compose.yml` to run LocalStack, you do not need `lstk`, and vice versa. -Do not mix `lstk start` with a Docker Compose setup; they are separate, independent methods. - -For Docker Compose configuration, see the [Docker Compose installation guide](/aws/getting-started/installation/#docker-compose). - -### Which Docker image does `lstk` use? - -It depends on the emulator type configured in your `config.toml`. -The AWS emulator uses `localstack/localstack-pro`, the Snowflake emulator uses `localstack/snowflake`, and the Azure emulator uses `localstack/localstack-azure`. -All require a valid auth token (including the free Hobby tier). -See [Emulator types](#emulator-types). - -### How do I pass configuration options like `DEBUG` or `PERSISTENCE` to the container? - -Use environment profiles in your `config.toml`. -Define the variables under an `[env.]` section and reference that name in the `env` list of your container config. -See [Passing environment variables to the container](#passing-environment-variables-to-the-container) for details. - -### How do I save and restore emulator state? - -Use [`lstk snapshot save`](#snapshot) to capture the running AWS emulator's state to a local file or a Cloud Pod, and [`lstk snapshot load`](#snapshot) (or the `lstk save` / `lstk load` aliases) to restore it. -To drop in-memory state without writing a snapshot, use [`lstk reset`](#reset). - -### How do I pin a specific LocalStack version? - -Set the `tag` field in your `config.toml` to a specific version tag: - -```toml -[[containers]] -type = "aws" -tag = "2026.4" -port = "4566" -``` - -## Troubleshooting - -### Port 443 already in use - -By default, LocalStack binds to both port `4566` and port `443` inside the container (controlled by the `GATEWAY_LISTEN` variable). -On some systems, particularly Windows with Hyper-V, IIS, or VPN software, port 443 may already be in use. - -**Symptoms:** - -```text -failed to start LocalStack: Error response from daemon: ports are not available: -exposing port TCP 127.0.0.1:443 -> 127.0.0.1:0: listen tcp4 127.0.0.1:443: bind: -address already in use -``` - -**Fix:** Override `GATEWAY_LISTEN` to bind only to port 4566: - -```toml -[[containers]] -type = "aws" -tag = "latest" -port = "4566" -env = ["nossl"] - -[env.nossl] -GATEWAY_LISTEN = "0.0.0.0:4566" -``` - -This tells the container to skip the port 443 binding entirely. - -### Docker is not running - -`lstk` requires a running Docker daemon. -If Docker is not reachable, you will see an error like: - -```text -Error: runtime not healthy -``` - -**Fix:** Start Docker Desktop (macOS/Windows) or the Docker daemon (`sudo systemctl start docker` on Linux). -If you use Colima or OrbStack, make sure the VM is running. -You can also point `lstk` at a custom socket with `DOCKER_HOST`. - -### Authentication required in non-interactive mode - -When running without a TTY (e.g. in CI), `lstk` cannot open a browser for login. -If no token is found in the keyring or environment, it fails: - -```text -authentication required: set LOCALSTACK_AUTH_TOKEN or run in interactive mode -``` - -**Fix:** Set the `LOCALSTACK_AUTH_TOKEN` environment variable before running `lstk`: - -```bash -export LOCALSTACK_AUTH_TOKEN= -lstk --non-interactive start -``` - -You can find your auth token on the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). - -### License validation failed - -If your auth token is invalid, expired, or not linked to an active license, the LocalStack container exits with a license error: - -```text -The license activation failed for the following reason: -No credentials were found in the environment. -``` - -**Fix:** - -- Verify your token is valid at the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens). -- Make sure the token is set correctly, either via `lstk login` or the `LOCALSTACK_AUTH_TOKEN` environment variable. -- If a stale keyring token is interfering, run `lstk logout` first and then set `LOCALSTACK_AUTH_TOKEN`. - -### Image pull failed - -If `lstk` cannot pull the Docker image, check your network connection and Docker configuration. -On corporate networks, you may need to configure Docker's proxy settings, see [How do I configure LocalStack to use my corporate HTTP and HTTPS proxy?](/aws/getting-started/faq/#how-do-i-configure-localstack-to-use-my-corporate-http-and-https-proxy). - -### Unknown environment profile - -If your container config references an `env` profile that doesn't exist, `lstk` returns: - -```text -environment "myprofile" referenced in container config not found -``` - -**Fix:** Make sure the profile name in the `env` list matches an `[env.]` section in your `config.toml`: - -```toml -[[containers]] -type = "aws" -env = ["myprofile"] # must match the section name below - -[env.myprofile] -DEBUG = "1" -``` + ### Getting help -If the steps above don't resolve your issue, see [Get Help](/aws/help-support/get-help/) for the available support channels, including the support email and in-app chat. +If the steps above don't resolve your issue, see the [Get Help](/aws/help-support/get-help/) page for the available support channels, including the support email and in-app chat. diff --git a/src/content/docs/snowflake/developer-tools/lstk.mdx b/src/content/docs/snowflake/developer-tools/lstk.mdx new file mode 100644 index 000000000..d5f8e2581 --- /dev/null +++ b/src/content/docs/snowflake/developer-tools/lstk.mdx @@ -0,0 +1,70 @@ +--- +title: lstk CLI +description: Reference guide for lstk, the modern CLI for managing LocalStack, with installation, configuration, commands, and troubleshooting. +template: doc +sidebar: + order: 10 +--- + +import Installation from '@/components/lstk/Installation.mdx'; +import QuickStart from '@/components/lstk/QuickStart.mdx'; +import Authentication from '@/components/lstk/Authentication.mdx'; +import Configuration from '@/components/lstk/Configuration.mdx'; +import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; +import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; +import CommonCommands from '@/components/lstk/CommonCommands.mdx'; +import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; +import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; +import ShellCompletions from '@/components/lstk/ShellCompletions.mdx'; +import FaqCommon from '@/components/lstk/FaqCommon.mdx'; +import TroubleshootingCommon from '@/components/lstk/TroubleshootingCommon.mdx'; + +## Introduction + +`lstk` is a high-performance command-line interface for LocalStack, built in Go. +It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting. + +`lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status. +It can also save and load emulator state (as local snapshots or Cloud Pods) and manage the on-disk volume. +Running `lstk` with no arguments takes you through the entire startup flow automatically. + +`lstk` does not currently proxy a CLI tool specific to the Snowflake emulator — see [Commands](#commands) below for the lifecycle and snapshot management commands available. + +## Prerequisites + +- [Docker](https://docs.docker.com/get-docker/) installed and running. +- A [LocalStack account](https://www.localstack.cloud/pricing) with a [license](/snowflake/getting-started/auth-token/#managing-your-license), and `lstk` handles authentication for you (see [Authentication](#authentication)). + + + + + + + + + +## Commands + + + + + + + + + + + + + +## FAQ + + + +## Troubleshooting + + + +### Getting help + +If the steps above don't resolve your issue, see the [Get Help](/snowflake/help-support/get-help/) page for the available support channels, including the support email and in-app chat. diff --git a/src/lib/lstk-toc.ts b/src/lib/lstk-toc.ts new file mode 100644 index 000000000..3c3d6eb29 --- /dev/null +++ b/src/lib/lstk-toc.ts @@ -0,0 +1,149 @@ +import { readFileSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import GithubSlugger from 'github-slugger'; + +/** + * Pages that compose their content from shared .mdx components (see src/components/lstk/) + * don't get those components' headings picked up by Starlight's own per-file heading + * extraction, since it only looks at the page's own compiled AST. This walks a page's raw + * source, follows `` usages back to their imported .mdx file, and stitches + * their headings back into the flat list in document order so the right-hand nav is accurate. + */ + +const SRC_DIR = resolve(dirname(fileURLToPath(import.meta.url)), '..'); + +const IMPORT_RE = /^import\s+(\w+)\s+from\s+['"](@\/components\/[\w./-]+\.mdx)['"];?\s*$/; +const USAGE_RE = /^<([A-Z]\w*)(?:\s[^>]*)?\/>\s*$/; +const FENCE_RE = /^\s*(```|~~~)/; +const HEADING_RE = /^(#{1,6})\s+(.+?)\s*$/; + +export interface FlatHeading { + depth: number; + slug: string; + text: string; +} + +function cleanHeadingText(raw: string): string { + return raw + .replace(/`([^`]*)`/g, '$1') + .replace(/\*\*([^*]*)\*\*/g, '$1') + .replace(/\*([^*]*)\*/g, '$1') + .replace(/_([^_]*)_/g, '$1') + .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1') + .trim(); +} + +function resolveAliasPath(aliasPath: string): string { + return resolve(SRC_DIR, aliasPath.replace(/^@\//, '')); +} + +/** Extract just the headings from a source file, in order, with no import/usage resolution. */ +function extractHeadings(source: string): { depth: number; text: string }[] { + const headings: { depth: number; text: string }[] = []; + let inFence = false; + for (const line of source.split('\n')) { + if (FENCE_RE.test(line)) { + inFence = !inFence; + continue; + } + if (inFence) continue; + const match = HEADING_RE.exec(line); + if (match) headings.push({ depth: match[1].length, text: cleanHeadingText(match[2]) }); + } + return headings; +} + +/** Extract headings and component usages from a top-level page, resolving usages by line order. */ +function extractPageEvents(source: string) { + type Event = + | { line: number; type: 'heading'; depth: number; text: string } + | { line: number; type: 'usage'; path: string }; + + const events: Event[] = []; + const importMap = new Map(); + let inFence = false; + + const lines = source.split('\n'); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (FENCE_RE.test(line)) { + inFence = !inFence; + continue; + } + if (inFence) continue; + + const headingMatch = HEADING_RE.exec(line); + if (headingMatch) { + events.push({ line: i, type: 'heading', depth: headingMatch[1].length, text: cleanHeadingText(headingMatch[2]) }); + continue; + } + + const importMatch = IMPORT_RE.exec(line); + if (importMatch) { + importMap.set(importMatch[1], importMatch[2]); + continue; + } + + const usageMatch = USAGE_RE.exec(line); + if (usageMatch && importMap.has(usageMatch[1])) { + events.push({ line: i, type: 'usage', path: importMap.get(usageMatch[1])! }); + } + } + + return events; +} + +/** + * Build the flat, ordered heading list for a page that may import shared .mdx components, + * slugging each file's headings independently (a fresh Slugger per file) to match how Astro + * compiles and slugs each .mdx file on its own. + */ +export function buildFlatHeadings(pageFilePath: string): FlatHeading[] { + const pageSource = readFileSync(pageFilePath, 'utf-8'); + const events = extractPageEvents(pageSource); + + const flat: FlatHeading[] = []; + const pageSlugger = new GithubSlugger(); + + for (const event of events) { + if (event.type === 'heading') { + flat.push({ depth: event.depth, text: event.text, slug: pageSlugger.slug(event.text) }); + } else { + const componentPath = resolveAliasPath(event.path); + let componentSource: string; + try { + componentSource = readFileSync(componentPath, 'utf-8'); + } catch { + continue; + } + const componentSlugger = new GithubSlugger(); + for (const heading of extractHeadings(componentSource)) { + flat.push({ depth: heading.depth, text: heading.text, slug: componentSlugger.slug(heading.text) }); + } + } + } + + return flat; +} + +/** Mirrors Starlight's own generateToC() nesting algorithm (@astrojs/starlight/utils/generateToC). */ +export function injectHeadingsIntoToc( + tocItems: { depth: number; slug: string; text: string; children: unknown[] }[], + headings: FlatHeading[], + { minHeadingLevel, maxHeadingLevel }: { minHeadingLevel: number; maxHeadingLevel: number } +) { + function injectChild(items: any[], item: any): void { + const lastItem = items.at(-1); + if (!lastItem || lastItem.depth >= item.depth) { + items.push(item); + } else { + injectChild(lastItem.children, item); + } + } + + for (const heading of headings) { + if (heading.depth < minHeadingLevel || heading.depth > maxHeadingLevel) continue; + injectChild(tocItems, { ...heading, children: [] }); + } +} diff --git a/src/routeData.ts b/src/routeData.ts index 35fcd214e..570fe000a 100644 --- a/src/routeData.ts +++ b/src/routeData.ts @@ -1,4 +1,14 @@ +import { resolve } from 'node:path'; import { defineRouteMiddleware } from '@astrojs/starlight/route-data'; +import { buildFlatHeadings, injectHeadingsIntoToc } from './lib/lstk-toc'; + +// Pages under these paths compose their content from shared .mdx components (see +// src/components/lstk/), whose headings Starlight's own per-file extraction can't see. +const PAGES_WITH_SHARED_COMPONENT_HEADINGS = [ + /^\/aws\/developer-tools\/running-localstack\/lstk$/, + /^\/azure\/developer-tools\/lstk$/, + /^\/snowflake\/developer-tools\/lstk$/, +]; export const onRequest = defineRouteMiddleware((context) => { const locals = context.locals as typeof context.locals & { @@ -66,6 +76,15 @@ export const onRequest = defineRouteMiddleware((context) => { } } + if (starlightRoute.toc && PAGES_WITH_SHARED_COMPONENT_HEADINGS.some((match) => match.test(pathname))) { + const pageFilePath = resolve(process.cwd(), starlightRoute.entry.filePath); + const flatHeadings = buildFlatHeadings(pageFilePath); + const overview = starlightRoute.toc.items[0]; + const items = overview ? [overview] : []; + injectHeadingsIntoToc(items as any, flatHeadings, starlightRoute.toc); + starlightRoute.toc.items = items as typeof starlightRoute.toc.items; + } + const overviewItem = starlightRoute.toc?.items[0]; if (overviewItem) overviewItem.text = 'Back to top'; }); From eb6d2dbf9b928794bb77d19f04bcd427f19a1e90 Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Fri, 24 Jul 2026 11:01:55 -0400 Subject: [PATCH 2/2] Fix snapshot support details MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - **AWS page**: `snapshot` content inlined natively (it's no longer shared with anything, so the component was folded back in and deleted) — kept full Cloud Pods/S3/local support, dropped the inaccurate "also works experimentally on Snowflake/Azure" note. - **Azure page**: removed `snapshot`/`reset` entirely, added a short note pointing to `--persist` as the only state-retention option, and fixed the Introduction paragraph, which previously claimed Cloud Pod support. - **Snowflake page**: replaced the shared component with a native `snapshot` section scoped to local files only — no `pod:` refs, no S3 remotes, no `list`/`remove`/`show` (all Cloud-Pod-only) — kept the "experimental" warning since that's specifically about local save/load, and fixed its Introduction paragraph too. - Annotated the global `--snapshot`/`--no-snapshot` flags as AWS-only in `GlobalOptionsAndOutput.mdx` for consistency. --- .../lstk/GlobalOptionsAndOutput.mdx | 4 +- src/components/lstk/SnapshotCommands.mdx | 158 ----------------- .../running-localstack/lstk.mdx | 159 +++++++++++++++++- .../docs/azure/developer-tools/lstk.mdx | 7 +- .../docs/snowflake/developer-tools/lstk.mdx | 31 +++- 5 files changed, 191 insertions(+), 168 deletions(-) delete mode 100644 src/components/lstk/SnapshotCommands.mdx diff --git a/src/components/lstk/GlobalOptionsAndOutput.mdx b/src/components/lstk/GlobalOptionsAndOutput.mdx index 6dca5f2c8..32304932a 100644 --- a/src/components/lstk/GlobalOptionsAndOutput.mdx +++ b/src/components/lstk/GlobalOptionsAndOutput.mdx @@ -8,8 +8,8 @@ These options are available for all commands: | `--non-interactive` | Disable the interactive TUI, use plain output | | `--json` | Emit a single machine-readable JSON envelope on stdout instead of human-oriented output. Supported by `stop`, `reset`, and `update`; any other command rejects it. See [Structured output](#structured-output). | | `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) | -| `--snapshot ` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run) | -| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`) | +| `--snapshot ` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run). AWS emulator only. | +| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`). AWS emulator only. | | `-v`, `--version` | Print the version and exit | | `-h`, `--help` | Print help and exit | diff --git a/src/components/lstk/SnapshotCommands.mdx b/src/components/lstk/SnapshotCommands.mdx deleted file mode 100644 index d2a2ba268..000000000 --- a/src/components/lstk/SnapshotCommands.mdx +++ /dev/null @@ -1,158 +0,0 @@ -### `snapshot` - -Manage emulator snapshots. -A snapshot captures the running emulator's state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or in your own S3 bucket. -The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`. - -:::note -Snapshots are best supported on the **AWS emulator**. -`snapshot save`/`load` (and the `save`/`load` aliases) also work for the Snowflake and Azure emulators, but their snapshot support is experimental and not fully tested — `lstk` prints a warning such as `Snapshot support for the snowflake emulator is experimental and not fully tested.` -`reset` remains **AWS-only** and errors out with `reset is only supported for the AWS emulator` otherwise. -::: - -#### `snapshot save` - -Save a snapshot of the running emulator's state. -The emulator must already be running; this command does **not** auto-start it. - -```bash -# Auto-named snapshot file in the current directory -lstk snapshot save - -# Save to a specific local path -lstk snapshot save ./my-snapshot - -# Save to a Cloud Pod on the LocalStack platform (requires auth) -lstk snapshot save pod:my-baseline - -# Save to your own S3 bucket (pod name is auto-generated if omitted) -lstk snapshot save my-pod s3://my-bucket/prefix -``` - -The optional `[destination]` argument takes one of these forms: - -| Destination | Description | -|:--------------------------------|:------------------------------------------------------------------------------------------------| -| (omitted) | Auto-generates a timestamped snapshot file in the current directory (`./snapshot--.snapshot`). | -| local path | Writes a snapshot archive to that path. The `.snapshot` extension is forced. | -| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. | -| ` s3://bucket/prefix` | Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See [S3 remotes](#s3-remotes). | - -Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not. - -| Option | Description | -|:--------------------|:----------------------------------------------------------------------------------------------| -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` destinations). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot load` - -Load a snapshot into the emulator, **auto-starting it first** if it is not already running. - -```bash -# Load a local snapshot by path or name -lstk snapshot load my-baseline -lstk snapshot load ./checkpoint - -# Load from a Cloud Pod (requires auth) -lstk snapshot load pod:my-baseline - -# Load from your own S3 bucket (pod name is required) -lstk snapshot load my-pod s3://my-bucket/prefix - -# Control how the snapshot merges with running state -lstk snapshot load pod:my-baseline --merge=overwrite -``` - -The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod. -To load from S3, pass the pod name followed by an `s3://bucket/prefix` location (see [S3 remotes](#s3-remotes)). - -| Option | Description | -|:---------------------|:--------------------------------------------------------------------------------------------------------| -| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. | -| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` sources). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap. -- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state. -- `service-merge`: the snapshot wins per resource; non-overlapping resources are combined. - -The aliases behave identically: - -```bash -lstk save pod:my-baseline -lstk load ./checkpoint -``` - -#### `snapshot list` - -List the Cloud Pod snapshots available on the LocalStack platform. -By default, only snapshots you created are listed; pass `--all` to include every snapshot in your organization. -This subcommand operates on Cloud Pods, so it requires authentication. - -```bash -# Snapshots you created -lstk snapshot list - -# Every snapshot in your organization -lstk snapshot list --all - -# List snapshots in your own S3 bucket (requires a running emulator) -lstk snapshot list s3://my-bucket/prefix -``` - -Passing an `s3://bucket/prefix` location lists snapshots stored in your own S3 bucket instead of the platform (see [S3 remotes](#s3-remotes)). Unlike the platform listing, this queries the emulator, so it requires a running emulator. - -| Option | Description | -|:-------------------|:-------------------------------------------------------------| -| `--all` | List all snapshots in your organization, not just your own. | -| `--profile ` | AWS profile to read S3 credentials from (used only with an `s3://` location). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | - -#### `snapshot remove` - -Delete a Cloud Pod snapshot from the LocalStack platform. -Only cloud snapshots (the `pod:` prefix) can be removed; local snapshots are plain files you delete yourself. -This operation cannot be undone. - -```bash -lstk snapshot remove pod:my-baseline - -# Skip the confirmation prompt (required in non-interactive mode) -lstk snapshot remove pod:my-baseline --force -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -| Option | Description | -|:----------|:------------------------------------------------------------------------| -| `--force` | Skip the confirmation prompt. Required when running non-interactively. | - -#### `snapshot show` - -Show metadata for a single Cloud Pod snapshot on the LocalStack platform: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). -This subcommand is cloud-only and requires authentication. - -```bash -lstk snapshot show pod:my-baseline -``` - -The required `REF` argument must be a `pod:` Cloud Pod reference. - -#### S3 remotes - -`snapshot save`, `load`, and `list` can target a snapshot stored in your **own S3 bucket** by passing an `s3://bucket/prefix` location. -The pod name (the snapshot's identity within the bucket) is a positional separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`. - -```bash -lstk snapshot save my-pod s3://my-bucket/prefix -lstk snapshot load my-pod s3://my-bucket/prefix -lstk snapshot list s3://my-bucket/prefix -``` - -Credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (plus optional `AWS_SESSION_TOKEN`) environment variables, otherwise the profile named by `AWS_PROFILE`. -Only static credentials are supported (no SSO, assume-role, or `credential_process`), and credentials must never be embedded in the URL. - -`lstk` runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo. -Because the transfer is performed by the emulator (not the CLI), S3 remotes require a **running emulator**, and `list s3://…` in particular queries the emulator rather than the platform API. - -:::note -`remove` and `show` do not support S3; they operate on Cloud Pods only. -::: diff --git a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx index 349cd403f..e764850e8 100644 --- a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx +++ b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx @@ -12,7 +12,6 @@ import QuickStart from '@/components/lstk/QuickStart.mdx'; import Authentication from '@/components/lstk/Authentication.mdx'; import Configuration from '@/components/lstk/Configuration.mdx'; import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; -import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; import CommonCommands from '@/components/lstk/CommonCommands.mdx'; import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; @@ -151,7 +150,163 @@ Like `lstk aws`, the `terraform`, `cdk`, and `sam` proxies do not start the emul Each requires the corresponding third-party CLI to be installed and on your `PATH`. ::: - +### `snapshot` + +Manage emulator snapshots. +A snapshot captures the running AWS emulator's state, either as a local file on disk, as a Cloud Pod on the LocalStack platform, or in your own S3 bucket. +The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`. + +:::note +Cloud Pods and S3 remotes are **AWS-only**. Snapshots are not currently supported for the Snowflake or Azure emulators through `lstk`. +`reset` is also **AWS-only** and errors out with `reset is only supported for the AWS emulator` otherwise. +::: + +#### `snapshot save` + +Save a snapshot of the running emulator's state. +The emulator must already be running; this command does **not** auto-start it. + +```bash +# Auto-named snapshot file in the current directory +lstk snapshot save + +# Save to a specific local path +lstk snapshot save ./my-snapshot + +# Save to a Cloud Pod on the LocalStack platform (requires auth) +lstk snapshot save pod:my-baseline + +# Save to your own S3 bucket (pod name is auto-generated if omitted) +lstk snapshot save my-pod s3://my-bucket/prefix +``` + +The optional `[destination]` argument takes one of these forms: + +| Destination | Description | +|:--------------------------------|:------------------------------------------------------------------------------------------------| +| (omitted) | Auto-generates a timestamped snapshot file in the current directory (`./snapshot--.snapshot`). | +| local path | Writes a snapshot archive to that path. The `.snapshot` extension is forced. | +| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. | +| ` s3://bucket/prefix` | Saves to your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). See [S3 remotes](#s3-remotes). | + +Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not. + +| Option | Description | +|:--------------------|:----------------------------------------------------------------------------------------------| +| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` destinations). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +#### `snapshot load` + +Load a snapshot into the emulator, **auto-starting it first** if it is not already running. + +```bash +# Load a local snapshot by path or name +lstk snapshot load my-baseline +lstk snapshot load ./checkpoint + +# Load from a Cloud Pod (requires auth) +lstk snapshot load pod:my-baseline + +# Load from your own S3 bucket (pod name is required) +lstk snapshot load my-pod s3://my-bucket/prefix + +# Control how the snapshot merges with running state +lstk snapshot load pod:my-baseline --merge=overwrite +``` + +The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod. +To load from S3, pass the pod name followed by an `s3://bucket/prefix` location (see [S3 remotes](#s3-remotes)). + +| Option | Description | +|:---------------------|:--------------------------------------------------------------------------------------------------------| +| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. | +| `--profile ` | AWS profile to read S3 credentials from (used only for `s3://` sources). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap. +- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state. +- `service-merge`: the snapshot wins per resource; non-overlapping resources are combined. + +The aliases behave identically: + +```bash +lstk save pod:my-baseline +lstk load ./checkpoint +``` + +#### `snapshot list` + +List the Cloud Pod snapshots available on the LocalStack platform. +By default, only snapshots you created are listed; pass `--all` to include every snapshot in your organization. +This subcommand operates on Cloud Pods, so it requires authentication. + +```bash +# Snapshots you created +lstk snapshot list + +# Every snapshot in your organization +lstk snapshot list --all + +# List snapshots in your own S3 bucket (requires a running emulator) +lstk snapshot list s3://my-bucket/prefix +``` + +Passing an `s3://bucket/prefix` location lists snapshots stored in your own S3 bucket instead of the platform (see [S3 remotes](#s3-remotes)). Unlike the platform listing, this queries the emulator, so it requires a running emulator. + +| Option | Description | +|:-------------------|:-------------------------------------------------------------| +| `--all` | List all snapshots in your organization, not just your own. | +| `--profile ` | AWS profile to read S3 credentials from (used only with an `s3://` location). Defaults to `AWS_*` env vars, then `AWS_PROFILE`. | + +#### `snapshot remove` + +Delete a Cloud Pod snapshot from the LocalStack platform. +Only cloud snapshots (the `pod:` prefix) can be removed; local snapshots are plain files you delete yourself. +This operation cannot be undone. + +```bash +lstk snapshot remove pod:my-baseline + +# Skip the confirmation prompt (required in non-interactive mode) +lstk snapshot remove pod:my-baseline --force +``` + +The required `REF` argument must be a `pod:` Cloud Pod reference. + +| Option | Description | +|:----------|:------------------------------------------------------------------------| +| `--force` | Skip the confirmation prompt. Required when running non-interactively. | + +#### `snapshot show` + +Show metadata for a single Cloud Pod snapshot on the LocalStack platform: its name, created date, size, LocalStack version, message, the services it contains, and per-service resource counts (resource counts render only when the platform has them for that snapshot). +This subcommand is cloud-only and requires authentication. + +```bash +lstk snapshot show pod:my-baseline +``` + +The required `REF` argument must be a `pod:` Cloud Pod reference. + +#### S3 remotes + +`snapshot save`, `load`, and `list` can target a snapshot stored in your **own S3 bucket** by passing an `s3://bucket/prefix` location. +The pod name (the snapshot's identity within the bucket) is a positional separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`. + +```bash +lstk snapshot save my-pod s3://my-bucket/prefix +lstk snapshot load my-pod s3://my-bucket/prefix +lstk snapshot list s3://my-bucket/prefix +``` + +Credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (plus optional `AWS_SESSION_TOKEN`) environment variables, otherwise the profile named by `AWS_PROFILE`. +Only static credentials are supported (no SSO, assume-role, or `credential_process`), and credentials must never be embedded in the URL. + +`lstk` runs a pre-flight check that the target bucket exists and errors out rather than letting the emulator auto-create a bucket on a typo. +Because the transfer is performed by the emulator (not the CLI), S3 remotes require a **running emulator**, and `list s3://…` in particular queries the emulator rather than the platform API. + +:::note +`remove` and `show` do not support S3; they operate on Cloud Pods only. +::: ### `reset` diff --git a/src/content/docs/azure/developer-tools/lstk.mdx b/src/content/docs/azure/developer-tools/lstk.mdx index fca4ce749..df84ac0a4 100644 --- a/src/content/docs/azure/developer-tools/lstk.mdx +++ b/src/content/docs/azure/developer-tools/lstk.mdx @@ -11,7 +11,6 @@ import QuickStart from '@/components/lstk/QuickStart.mdx'; import Authentication from '@/components/lstk/Authentication.mdx'; import Configuration from '@/components/lstk/Configuration.mdx'; import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; -import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; import CommonCommands from '@/components/lstk/CommonCommands.mdx'; import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; @@ -25,7 +24,7 @@ import TroubleshootingCommon from '@/components/lstk/TroubleshootingCommon.mdx'; It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting. `lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status. -It can also save and load emulator state (as local snapshots or Cloud Pods) and manage the on-disk volume. +It can also persist emulator state across restarts and manage the on-disk volume. Running `lstk` with no arguments takes you through the entire startup flow automatically. `lstk` also proxies the Azure CLI (`lstk az`) so it runs directly against the Azure emulator. @@ -87,7 +86,9 @@ Like the other CLI proxies, `lstk az` does not start the emulator — start it f It requires the `az` CLI to be installed and on your `PATH`. ::: - +:::note +`lstk` does not currently support `snapshot` or `reset` for the Azure emulator — those commands are AWS-only. `lstk start --persist` is the only state-retention option available. +::: diff --git a/src/content/docs/snowflake/developer-tools/lstk.mdx b/src/content/docs/snowflake/developer-tools/lstk.mdx index d5f8e2581..d58bd2b3f 100644 --- a/src/content/docs/snowflake/developer-tools/lstk.mdx +++ b/src/content/docs/snowflake/developer-tools/lstk.mdx @@ -11,7 +11,6 @@ import QuickStart from '@/components/lstk/QuickStart.mdx'; import Authentication from '@/components/lstk/Authentication.mdx'; import Configuration from '@/components/lstk/Configuration.mdx'; import LifecycleCommands from '@/components/lstk/LifecycleCommands.mdx'; -import SnapshotCommands from '@/components/lstk/SnapshotCommands.mdx'; import CommonCommands from '@/components/lstk/CommonCommands.mdx'; import GlobalOptionsAndOutput from '@/components/lstk/GlobalOptionsAndOutput.mdx'; import EnvironmentAndLogging from '@/components/lstk/EnvironmentAndLogging.mdx'; @@ -25,7 +24,7 @@ import TroubleshootingCommon from '@/components/lstk/TroubleshootingCommon.mdx'; It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting. `lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status. -It can also save and load emulator state (as local snapshots or Cloud Pods) and manage the on-disk volume. +It can also save and load emulator state as local snapshot files and manage the on-disk volume. Running `lstk` with no arguments takes you through the entire startup flow automatically. `lstk` does not currently proxy a CLI tool specific to the Snowflake emulator — see [Commands](#commands) below for the lifecycle and snapshot management commands available. @@ -47,7 +46,33 @@ Running `lstk` with no arguments takes you through the entire startup flow autom - +### `snapshot` + +Save and restore the running Snowflake emulator's state as a local snapshot file. +Cloud Pods and S3 remotes are **AWS-only**; for Snowflake, `snapshot` only supports local files, and `reset` is not available at all. +The `snapshot` command groups two subcommands for this — `save` and `load` — also exposed as the top-level aliases `lstk save` and `lstk load`. + +:::note +Snapshot support for the Snowflake emulator is currently experimental. +::: + +```bash +# Auto-named snapshot file in the current directory +lstk snapshot save + +# Save to a specific local path +lstk snapshot save ./my-snapshot + +# Load a local snapshot by path or name +lstk snapshot load my-baseline +lstk snapshot load ./checkpoint + +# The aliases behave identically +lstk save ./checkpoint +lstk load ./checkpoint +``` + +`snapshot save` requires the emulator to already be running (it does **not** auto-start it); `snapshot load` auto-starts the emulator first if it isn't already running.