Skip to content
cloudemu

Standalone Server

Run cloudemu as a long-lived server and point real SDK clients at it over the network

Run cloudemu as a real server and point any SDK — in any language — at it over the network. This is the out-of-process counterpart to the in-process SDK-Compatible Server: same wire protocols, but a long-lived process instead of a httptest.NewServer inside your test.

Use it for local development, a shared dev environment, or a test suite that runs out-of-process.

one long-lived process · stable ports

SDK clientany languagecloudemu servenetwork:4566aws:4568azure:4569gcp:4570k8s

Run it#

go install github.com/stackshy/cloudemu/v2/cmd/cloudemu@latest
cloudemu serve

Or straight from a checkout:

go run ./cmd/cloudemu serve

On start it prints the live endpoints:

cloudemu — standalone server
────────────────────────────
  AWS         http://127.0.0.1:4566
  Azure       https://127.0.0.1:4568   (self-signed TLS)
  GCP         http://127.0.0.1:4569
  Kubernetes  http://127.0.0.1:4570

Docker#

No Go toolchain needed — pull the published image (it runs serve --host 0.0.0.0):

docker run --rm -p 4566:4566 -p 4568:4568 -p 4569:4569 ghcr.io/stackshy/cloudemu:latest

Or bring up the whole emulated cloud with the example compose file:

docker compose up

Testcontainers (Go)#

Go test suites can start and stop the container automatically with the Testcontainers module — a separate module, so it doesn't add Docker deps to your app:

ctr, _ := cloudemu.Run(ctx)
defer ctr.Terminate(ctx)

endpoint, _ := ctr.AWSEndpoint(ctx) // point aws-sdk-go-v2 here
ctr.Reset(ctx)                      // clean slate between tests

Ports#

ProviderDefaultProtocolNotes
AWS4566HTTPsame port LocalStack uses
Azure4568HTTPSthe ARM SDK requires TLS
GCP4569HTTP
Kubernetes4570HTTPshared data-plane for EKS / AKS / GKE

Override any of them with --aws-port, --azure-port, --gcp-port, --k8s-port. Start a subset with --providers=aws,gcp, and bind an interface with --host 0.0.0.0 (the default 127.0.0.1 keeps it local-only).

Point your SDK at it#

AWS#

client := s3.NewFromConfig(cfg, func(o *s3.Options) {
    o.BaseEndpoint = aws.String("http://127.0.0.1:4566")
    o.UsePathStyle = true
})

Other languages: set AWS_ENDPOINT_URL=http://127.0.0.1:4566 (or --endpoint-url on the CLI). Any credentials work — cloudemu doesn't validate signatures.

GCP#

client, _ := storage.NewClient(ctx,
    option.WithEndpoint("http://127.0.0.1:4569"),
    option.WithoutAuthentication())

Azure#

Azure is served over HTTPS with a self-signed cert. Point the SDK at it through a cloud.Configuration and either trust the cert or skip verification for local dev:

cloudCfg := cloud.Configuration{
    Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
        cloud.ResourceManager: {
            Endpoint: "https://127.0.0.1:4568",
            Audience: "https://management.azure.com",
        },
    },
}
opts := &arm.ClientOptions{ClientOptions: azcore.ClientOptions{Cloud: cloudCfg}}

NOTE

Bring your own cert with --tls-cert / --tls-key, or add SAN hosts to the generated one with --tls-host myhost.local.

Common flags#

FlagDefaultPurpose
--providersaws,azure,gcpwhich providers to start
--host127.0.0.1bind interface (0.0.0.0 to expose)
--account-id / --region / --project-iddefaultsidentity reported by the emulator
--latency0artificial per-call latency (e.g. 20ms)
--endpoints-filewrite the resolved endpoints as JSON
--admintruemount the /_cloudemu control plane
--shutdown-timeoutdefaultgrace period for in-flight requests on exit
--log-requests / --quietoffrequest logging / suppress the banner

--endpoints-file cloudemu.json writes a machine-readable bundle so an app can be wired at the whole emulated cloud at once:

{
  "aws": "http://127.0.0.1:4566",
  "azure": "https://127.0.0.1:4568",
  "gcp": "http://127.0.0.1:4569"
}

Building your own binary#

The serve command builds a server from a fully-constructed provider using the NewFromProvider helper, so you can embed the same thing in your own main:

srv := awsserver.NewFromProvider(cloudemu.NewAWS())
http.ListenAndServe(":4566", srv)

DriversFrom(provider) returns the wired Drivers if you want to customize before serving.

Admin control plane#

The server mounts a small /_cloudemu control plane (on by default; disable with --admin=false) for test isolation:

  • POST /_cloudemu/reset — wipes all in-memory state so a suite can start each test from a clean slate.
  • a health endpoint for readiness checks.

WARNING

POST /_cloudemu/reset wipes everything. When binding a non-loopback --host (e.g. 0.0.0.0), cloudemu warns that the reset endpoint is reachable off-box — pass --admin=false to disable it in shared environments.

State is in-memory#

The server holds all state in memory and starts empty on each run — there's no built-in seeding or persistence across restarts. Your test or app creates the resources it needs after the server starts.

On this page

On this page