From 30bf85a71a25523edf40b882cf94cbf0d73d8ecc Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Tue, 21 Jul 2026 00:46:34 +0200 Subject: [PATCH] DOC-359: Add lstk docs to Azure docs Add the lstk CLI reference doc under a new "Developer Tools" section in the Azure docs, mirroring the AWS and Snowflake copies. --- astro.config.mjs | 7 + .../docs/azure/developer-tools/lstk.mdx | 1422 +++++++++++++++++ 2 files changed, 1429 insertions(+) create mode 100644 src/content/docs/azure/developer-tools/lstk.mdx diff --git a/astro.config.mjs b/astro.config.mjs index 285a4a64..48619de6 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -863,6 +863,13 @@ export default defineConfig({ label: 'Local Azure Services', slug: 'azure/services', }, + { + label: 'Developer Tools', + collapsed: true, + items: [ + { autogenerate: { directory: 'azure/developer-tools' } }, + ], + }, { label: 'Integrations', collapsed: true, diff --git a/src/content/docs/azure/developer-tools/lstk.mdx b/src/content/docs/azure/developer-tools/lstk.mdx new file mode 100644 index 00000000..5a9be4cc --- /dev/null +++ b/src/content/docs/azure/developer-tools/lstk.mdx @@ -0,0 +1,1422 @@ +--- +title: lstk CLI +description: Reference guide for lstk, the modern CLI for managing LocalStack, with installation, configuration, commands, and troubleshooting. +template: doc +--- + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +## 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) 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`). + +## 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` + +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 +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` + +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). + +```bash +lstk sam build +lstk sam --region us-west-2 deploy +lstk sam validate +``` + +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` + +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` + +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.