From 6a8bd35b666728555b42279c67218a2b268aba65 Mon Sep 17 00:00:00 2001 From: George Tsiolis Date: Tue, 21 Apr 2026 18:58:26 +0300 Subject: [PATCH 1/3] Show endpoint and tips when emulator is already running --- internal/container/start.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/container/start.go b/internal/container/start.go index fc79d91c..a2cc27b9 100644 --- a/internal/container/start.go +++ b/internal/container/start.go @@ -159,7 +159,7 @@ func Start(ctx context.Context, rt runtime.Runtime, sink output.Sink, opts Start } } - containers, err = selectContainersToStart(ctx, rt, sink, tel, containers) + containers, err = selectContainersToStart(ctx, rt, sink, tel, containers, opts.LocalStackHost, opts.WebAppURL) if err != nil { return err } @@ -352,7 +352,7 @@ func startContainers(ctx context.Context, rt runtime.Runtime, sink output.Sink, return nil } -func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink output.Sink, tel *telemetry.Client, containers []runtime.ContainerConfig) ([]runtime.ContainerConfig, error) { +func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink output.Sink, tel *telemetry.Client, containers []runtime.ContainerConfig, localStackHost, webAppURL string) ([]runtime.ContainerConfig, error) { var filtered []runtime.ContainerConfig for _, c := range containers { running, err := rt.IsRunning(ctx, c.Name) @@ -360,7 +360,9 @@ func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink outpu return nil, fmt.Errorf("failed to check container status: %w", err) } if running { - output.EmitInfo(sink, "LocalStack is already running") + output.EmitNote(sink, "LocalStack is already running") + resolvedHost, _ := endpoint.ResolveHost(c.Port, localStackHost) + emitPostStartPointers(sink, resolvedHost, webAppURL) continue } if err := ports.CheckAvailable(c.Port); err != nil { From 41add77fd20968085dcdf13c5e4605883b8a0f88 Mon Sep 17 00:00:00 2001 From: George Tsiolis Date: Tue, 21 Apr 2026 19:02:34 +0300 Subject: [PATCH 2/3] Check DNS resolution when emulator is already running --- internal/container/start.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/container/start.go b/internal/container/start.go index a2cc27b9..f437899d 100644 --- a/internal/container/start.go +++ b/internal/container/start.go @@ -361,7 +361,10 @@ func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink outpu } if running { output.EmitNote(sink, "LocalStack is already running") - resolvedHost, _ := endpoint.ResolveHost(c.Port, localStackHost) + resolvedHost, dnsOK := endpoint.ResolveHost(c.Port, localStackHost) + if !dnsOK { + output.EmitNote(sink, `Could not resolve "localhost.localstack.cloud" — your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`) + } emitPostStartPointers(sink, resolvedHost, webAppURL) continue } From e744cdf9d9e8c800a197ea1109ae2b9d02602364 Mon Sep 17 00:00:00 2001 From: George Tsiolis Date: Tue, 21 Apr 2026 19:22:01 +0300 Subject: [PATCH 3/3] Extract DNS rebind note into a shared constant --- internal/container/start.go | 4 ++-- internal/endpoint/endpoint.go | 2 ++ internal/ui/run_awsconfig.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/container/start.go b/internal/container/start.go index f437899d..c26cd87d 100644 --- a/internal/container/start.go +++ b/internal/container/start.go @@ -226,7 +226,7 @@ func runPostStartSetups(ctx context.Context, sink output.Sink, containers []conf if setup, ok := setups[t]; ok { resolvedHost, dnsOK := endpoint.ResolveHost(firstByType[t].Port, localStackHost) if !dnsOK { - output.EmitNote(sink, `Could not resolve "localhost.localstack.cloud" — your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`) + output.EmitNote(sink, endpoint.DNSRebindNote) } if err := setup(ctx, sink, interactive, resolvedHost); err != nil { return err @@ -363,7 +363,7 @@ func selectContainersToStart(ctx context.Context, rt runtime.Runtime, sink outpu output.EmitNote(sink, "LocalStack is already running") resolvedHost, dnsOK := endpoint.ResolveHost(c.Port, localStackHost) if !dnsOK { - output.EmitNote(sink, `Could not resolve "localhost.localstack.cloud" — your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`) + output.EmitNote(sink, endpoint.DNSRebindNote) } emitPostStartPointers(sink, resolvedHost, webAppURL) continue diff --git a/internal/endpoint/endpoint.go b/internal/endpoint/endpoint.go index 04d62de9..017b2eeb 100644 --- a/internal/endpoint/endpoint.go +++ b/internal/endpoint/endpoint.go @@ -4,6 +4,8 @@ import "net" const Hostname = "localhost.localstack.cloud" +const DNSRebindNote = "Could not resolve localhost.localstack.cloud, falling back to 127.0.0.1." + // ResolveHost returns the best host:port for reaching LocalStack on the given port. // If override is non-empty it is returned as-is. Otherwise a DNS check is performed; // if Hostname does not resolve to 127.0.0.1 (e.g. DNS rebind protection is active), diff --git a/internal/ui/run_awsconfig.go b/internal/ui/run_awsconfig.go index b11a1f51..34113f66 100644 --- a/internal/ui/run_awsconfig.go +++ b/internal/ui/run_awsconfig.go @@ -28,7 +28,7 @@ func RunConfigProfile(parentCtx context.Context, containers []config.ContainerCo return runWithTUI(parentCtx, withoutHeader(), func(ctx context.Context, sink output.Sink) error { if !dnsOK { - output.EmitNote(sink, `Could not resolve "localhost.localstack.cloud" - your system may have DNS rebind protection enabled. Using 127.0.0.1 as the endpoint.`) + output.EmitNote(sink, endpoint.DNSRebindNote) } status, err := awsconfig.CheckProfileStatus(resolvedHost) if err != nil {