See your cloud, before you ship your cloud.
Install a local AWS cloud with one command on macOS, Linux or Windows, or run one Docker command. 73 AWS-compatible services on localhost:4566 and a web console for 60 services on localhost:8080 — free, no AWS account needed.
Goku was formerly Mimir. Upgrading an existing install? Your install, commands and data carry over.
The CLI installs natively on each platform and runs Goku in Docker for you — no docker commands to write. It installs the goku command, plus mimir, its former name, as a deprecated alias (details).
$ curl -fsSL https://tanuj24.github.io/goku/install.sh | sh
PS> irm https://tanuj24.github.io/goku/install.ps1 | iex
$ goku start
goku start downloads the image on first run, starts Goku and opens the web console at http://localhost:8080. Your AWS CLI, SDKs and apps talk to http://localhost:4566 — point them at it with one command.
| Command | What it does |
|---|---|
goku start | Downloads the image on first run, starts Goku and opens the console. |
goku status | Shows what's running — also for a Goku started another way. |
goku stop | Stops Goku. Everything is saved in your data folder. |
goku logs -f | Follows the container logs. |
goku update | Upgrades to the newest version. Your resources are preserved. |
goku update --cli | Updates the goku command itself, verified against its published checksums. |
goku data | Shows where your data lives and how big it is; goku data open opens the folder, goku data migrate moves an older install's volume into it. |
goku open | Opens the console, or a page in it: goku open sqs, goku open lambda my-fn. |
goku env | Prints the endpoint and credential variables for your AWS CLI and SDKs. |
goku doctor | Checks Docker, ports, saved state, curl and the backend's features, and whether the MCP endpoint answers. |
goku mcp | Goku's MCP server for AI assistants, on stdin and stdout. Starts Goku when it isn't running. |
goku mcp config | Prints the setup for Claude Code, Claude Desktop, Cursor, VS Code and Windsurf; goku mcp config cursor prints one. |
goku uninstall | Removes Goku and keeps your data folder; add --purge to delete it too. |
The CLI also drives a running Goku: goku services, goku ready, goku snapshot, goku chaos, goku iam and goku lambda debug. Run goku help <command> for the details.
goku env sets AWS_ENDPOINT_URL, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (test / test) and AWS_REGION, so the AWS CLI v2 and every AWS SDK talk to Goku with no code changes.
$ eval "$(goku env)"
PS> goku env --shell powershell | Invoke-Expression
Then aws s3 ls lists your local buckets. On macOS and Linux, eval "$(goku env --unset)" switches back to real AWS. To configure a tool by hand, use the endpoint http://localhost:4566, region us-east-1 and any local credentials such as test / test.
Next, create your first bucket, table, queue and function with the run AWS locally guide.
Goku serves an MCP server at http://localhost:8080/mcp, so AI assistants can work with your local AWS too, and nothing they change reaches real AWS. For Claude Code:
$ claude mcp add goku -- goku mcp
goku mcp starts Goku if it isn't running, and goku mcp config prints the setup for Claude Desktop, Cursor, VS Code and Windsurf. The MCP guide covers every client and the 25 tools.
Already have Docker? Run the image directly — it's the same image the CLI runs.
$ mkdir -p ~/.goku/data
docker run -d --name goku \
-p 8080:80 -p 4566:4566 -p 5500-5524:5500-5524 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.goku/data:/app/data \
-v /tmp/goku-glue:/tmp/goku-glue \
tanujsoni027/goku:latest
PS> New-Item -ItemType Directory -Force "$env:LOCALAPPDATA\Goku\data" | Out-Null
docker run -d --name goku `
-p 8080:80 -p 4566:4566 -p 5500-5524:5500-5524 `
-v /var/run/docker.sock:/var/run/docker.sock `
-v "$env:LOCALAPPDATA\Goku\data:/app/data" `
-v /tmp/goku-glue:/tmp/goku-glue `
tanujsoni027/goku:latest
The web console is at http://localhost:8080 and the AWS-compatible endpoint at http://localhost:4566. Add -e GOKU_SERVICES=all to start with every service subscribed, and -p 2000:2000/udp to send X-Ray segments from apps on your host.
/app/data, and the data of its engines too: RDS PostgreSQL databases, OpenSearch, MSK, ECR, DocumentDB, MemoryDB, Amazon MQ and Redshift. Stop Goku, update it or reset Docker, then start it with the same folder and you resume where you left off. Leave the -v for the folder out and Goku keeps its state in a goku-data Docker volume instead. RDS MySQL and MariaDB data stays in a Docker volume on macOS and Windows.Everything you created carries over. The easiest way is the CLI: install it (the commands above), then run
$ goku update
goku update stops your mimir container gracefully so it saves its state, moves that state into your data folder (~/.goku/data, or %LOCALAPPDATA%\Goku\data on Windows) and starts the newest Goku, now named goku and running tanujsoni027/goku, on the same ports. Your old mimir-data volume is kept as a backup. Engine data (databases, search domains, brokers, the ECR registry) moves into the folder by itself when each engine next starts.
Stop the old mimir container gracefully, copy its data into a folder, then start the new image on that folder as goku. docker cp works with every Mimir version, including early v3 builds that kept state only inside the container:
$ docker stop -t 60 mimir
mkdir -p ~/.goku/data
docker cp mimir:/app/data/. ~/.goku/data/
docker rm mimir
docker pull tanujsoni027/goku:latest
docker run -d --name goku \
-p 8080:80 -p 4566:4566 -p 5500-5524:5500-5524 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.goku/data:/app/data \
-v /tmp/goku-glue:/tmp/goku-glue \
tanujsoni027/goku:latest
On Windows, use "$env:LOCALAPPDATA\Goku\data" as the folder, as in the Docker commands above. Check that the folder holds your data (for example an s3 folder) before the docker rm; your mimir-data volume, if you have one, is left untouched as a backup. Starting the new image on an empty folder also works: it copies the state kept in the mimir-data volume into the folder by itself.
From Goku 4.0 on, the console tells you when a new version is out and updates itself with Update now.
Goku (formerly Mimir) is the same product with a new name, and every name is Goku now. Start using the goku names. The old names keep working for now, existing installs move over automatically, and the old names will be removed in a future release.
goku and mimir. Every example on this site uses goku.mimir command is deprecated and will be removed in a future release. Until then it keeps working: it runs goku and prints a short note on stderr asking you to switch. Set GOKU_NO_DEPRECATION_NOTICE=1 to silence the note.goku update (or Update now in the console) renames the mimir container to goku, moves it to the tanujsoni027/goku image and your state into the data folder, and keeps the mimir-data volume as a backup.MIMIR_* variable is still read, and Goku prints a note for each one, asking you to rename it to GOKU_*. When both are set, the GOKU_* one wins.| Before (Mimir) | Now (Goku) |
|---|---|
mimir start, mimir update, … | goku start, goku update, … |
Image tanujsoni027/mimir-aws | tanujsoni027/goku (the old name gets the same releases for now) |
Container mimir | goku: docker logs goku, docker exec goku … |
Volume mimir-data | The data folder ~/.goku/data (%LOCALAPPDATA%\Goku\data on Windows) |
MIMIR_CONSOLE_PORT, MIMIR_SERVICES, … | GOKU_CONSOLE_PORT, GOKU_SERVICES, … |
/_mimir/… API paths | /_goku/… |
*.mimir.local host names | *.goku.local |
CA file mimir-ca.pem | goku-ca.pem (the same CA: nothing to re-trust) |
Engine containers mimir-rds-…, mimir-ec2-… | goku-rds-…, goku-ec2-… |
Glue folder /tmp/mimir-glue | /tmp/goku-glue |
tanuj24.github.io/mimir, github.com/tanuj24/mimir | tanuj24.github.io/goku, github.com/tanuj24/goku |
From the console: when a new version is out, the console shows a banner; Update now downloads it and replaces the running Goku with the same ports, settings and data. If the new version doesn't come up healthy within 3 minutes, Goku rolls back to the version you had. The version menu in the top bar has Check for updates.
From a terminal: goku update updates Goku, and goku update --cli updates the CLI. The CLI mentions new versions at most once a day.
With plain Docker: stop the container gracefully, pull the new image and run the docker run command again with the same data folder:
$ docker stop -t 60 goku && docker rm goku
docker pull tanujsoni027/goku:latest
How update checks work: Goku downloads one small static file, releases.json, from this site. Nothing about you or your setup is sent. Set GOKU_UPDATE_CHECK=off to turn the checks off.
Stop Goku and copy the data folder; that is the whole backup. Copy it to another machine and start Goku there with the same folder to carry on. On Linux, engine folders belong to the users their engines run as, so copy them as root to keep their owners.
goku uninstall removes Goku — its container and only the engine containers of this installation — and keeps your data folder, so a later reinstall finds your resources intact. Add --purge to also delete the data folder.
Start with the built-in checkup — it checks Docker, ports, saved state, curl and the backend's features, and tells you what's missing:
$ goku doctor
Docker isn't running. Start Docker Desktop, wait until it reports that it is running, then run goku start again.
goku: command not found. The installer puts goku in /usr/local/bin, or in ~/.local/bin when it can't use sudo. Make sure that directory is on your PATH, or pick another one with GOKU_INSTALL_DIR when you install.
Permission denied on /var/run/docker.sock. Your user can't reach the Docker daemon. Add it to the docker group with sudo usermod -aG docker "$USER", then log out and back in.
goku: command not found. Without sudo, the installer uses ~/.local/bin. Add it to your PATH, or pick another directory with GOKU_INSTALL_DIR.
Docker isn't running. Start Docker Desktop and keep it on Linux containers (its default), then run goku start again.
goku is not recognized. Open a new PowerShell window after installing, so it picks up the updated PATH.
If something already uses port 8080 or 4566, pick other ports with GOKU_CONSOLE_PORT and GOKU_EDGE_PORT:
$ GOKU_CONSOLE_PORT=9090 GOKU_EDGE_PORT=4567 goku start
PS> $env:GOKU_CONSOLE_PORT = "9090"; $env:GOKU_EDGE_PORT = "4567"; goku start
Data endpoints live in a dedicated 5500–5659 range (RDS, ElastiCache and Neptune through the published 5500–5524 ports; the rest bind automatically), so they won't clash with a local Redis, Postgres or Elasticsearch.
Open an issue at github.com/tanuj24/goku/issues — include the output of goku doctor and goku logs.