Get Gopherstack running locally in under two minutes and start using it as an AWS endpoint.
- AWS CLI v2 — for interacting with the mock services
- Go 1.21+ (for
go install) or a pre-built binary (see below) - Docker (optional, required for Lambda image-based functions only)
go install github.com/blackbirdworks/gopherstack@latestDownload the latest release for your platform from GitHub Releases:
# Linux / macOS (amd64)
curl -sSfL https://github.com/blackbirdworks/gopherstack/releases/latest/download/gopherstack_linux_amd64.tar.gz | tar xz
chmod +x gopherstack && mv gopherstack /usr/local/bin/
# macOS (Apple Silicon)
curl -sSfL https://github.com/blackbirdworks/gopherstack/releases/latest/download/gopherstack_darwin_arm64.tar.gz | tar xz
chmod +x gopherstack && mv gopherstack /usr/local/bin/docker run --rm -p 8000:8000 ghcr.io/blackbirdworks/gopherstack:latestSee docker.md for a full Docker Compose setup.
gopherstack
# INFO starting server addr=:8000 region=us-east-1The server is ready when you see the startup log. It listens on port 8000 by default.
# Verify it is running
gopherstack health
# OKGopherstack speaks the native AWS wire protocol — no SDK changes needed, just point the CLI at http://localhost:8000.
# S3
aws --endpoint-url http://localhost:8000 s3 mb s3://my-bucket
aws --endpoint-url http://localhost:8000 s3 cp README.md s3://my-bucket/
aws --endpoint-url http://localhost:8000 s3 ls s3://my-bucket/
# SQS
aws --endpoint-url http://localhost:8000 sqs create-queue --queue-name my-queue
aws --endpoint-url http://localhost:8000 sqs send-message \
--queue-url http://localhost:8000/000000000000/my-queue \
--message-body "hello"
# DynamoDB
aws --endpoint-url http://localhost:8000 dynamodb create-table \
--table-name Users \
--attribute-definitions AttributeName=UserId,AttributeType=S \
--key-schema AttributeName=UserId,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
# STS (always returns the mock account)
aws --endpoint-url http://localhost:8000 sts get-caller-identityInstall the awsgs wrapper to avoid repeating --endpoint-url on every command:
go install github.com/blackbirdworks/gopherstack/cmd/awsgs@latestThen replace aws with awsgs:
awsgs s3 mb s3://my-bucket
awsgs sqs create-queue --queue-name my-queue
awsgs dynamodb list-tablesawsgs injects --endpoint-url http://localhost:8000 automatically. Override the port with --awsgs-port or AWSGS_PORT:
awsgs --awsgs-port 9000 s3 ls
AWSGS_PORT=9000 awsgs dynamodb list-tablesAWS CLI uses AWS_ENDPOINT_URL (v2.13+) as a global endpoint override — no wrapper needed:
export AWS_ENDPOINT_URL=http://localhost:8000
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
aws s3 ls
aws dynamodb list-tablesA web dashboard is available at http://localhost:8000/dashboard for browsing S3 buckets, DynamoDB tables, queues, and service metrics.
All options can be set as CLI flags or environment variables:
| Flag | Env Var | Default | Description |
|---|---|---|---|
--port |
PORT |
8000 |
HTTP server port |
--region |
REGION |
us-east-1 |
Default AWS region |
--account-id |
ACCOUNT_ID |
000000000000 |
Mock AWS account ID |
--log-level |
LOG_LEVEL |
info |
Log level (debug, info, warn, error) |
--persist |
PERSIST |
false |
Enable snapshot persistence across restarts |
--data-dir |
GOPHERSTACK_DATA_DIR |
~/.gopherstack/data |
Persistence data directory |
--demo |
DEMO |
false |
Load demo data on startup |
--latency-ms |
LATENCY_MS |
0 |
Inject random latency per request (ms) |
--elasticache-engine |
ELASTICACHE_ENGINE |
embedded |
ElastiCache engine: embedded, stub, docker |
--opensearch-engine |
OPENSEARCH_ENGINE |
stub |
OpenSearch engine: stub, docker |
--dns-addr |
DNS_ADDR |
`` | Enable embedded DNS on this address (e.g. :10053) |
--dns-resolve-ip |
DNS_RESOLVE_IP |
127.0.0.1 |
IP synthetic hostnames resolve to |
Start with --persist (or PERSIST=true) to save state across restarts:
gopherstack --persistState is saved to ~/.gopherstack/data/ on macOS/Linux or /data/ in container environments. A debounced snapshot is taken 500 ms after each mutation.
A pod is a named series of full-emulator snapshots. Each save creates a new version (zip with manifest.json plus one JSON snapshot per service, the same data POST /_gopherstack/snapshot returns).
gopherstack pod save demo -m "seeded users" # new version, all services
gopherstack pod save demo --services s3,dynamodb # subset
gopherstack pod list
gopherstack pod versions demo
gopherstack pod inspect demo --version 1
gopherstack pod load demo # latest, strategy=overwrite
gopherstack pod load demo --version 1 --strategy service-merge
gopherstack pod delete demo --version 1 # omit --version to delete the pod
gopherstack --pod-autoload demo:1 # load at startup (name[:version])overwrite resets every service, then restores the pod; service-merge replaces only the services present in the pod and leaves the rest untouched. Account/region-level merge is not supported.
Pods live in <data-dir>/pods by default (--pod-dir). To use an S3-compatible remote set --pod-s3-bucket (plus --pod-s3-prefix, --pod-s3-endpoint, --pod-s3-region, --pod-s3-access-key/--pod-s3-secret-key, --pod-s3-path-style); with no endpoint it targets real AWS S3 using the default credential chain. The pod subcommands call a running instance (--endpoint, default http://localhost:8000).
HTTP API: GET /_gopherstack/pods, POST|GET|DELETE /_gopherstack/pods/{name} (POST body {"message","services"}; DELETE takes ?version=), GET /_gopherstack/pods/{name}/versions/{version|latest}, POST /_gopherstack/pods/{name}/load?version=&strategy=&services=.
- docker.md — Docker Compose setup for CI/CD
- migration.md — Migrating from LocalStack
- docs/services/ — Per-service documentation
- docs/architecture/ — Internals and advanced configuration