Zum Inhalt springen
Docs Try Aspire
Docs Try

Set up Go apps in the AppHost

Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.

Go logo

This article is the reference for the Aspire Go hosting integration. It enumerates the AppHost APIs — with examples for both AppHost.cs and apphost.mts — that you use to orchestrate Go applications in your AppHost project.

If you’re new to the Go integration, start with the Get started with the Go integration guide.

To start building an Aspire app that uses Go, install the 📦 Aspire.Hosting.Go NuGet package:

Terminal
aspire add go

Learn more about aspire add in the command reference.

Or, choose a manual installation approach:

C# — AppHost.cs
#:package Aspire.Hosting.Go@*
XML — AppHost.csproj
<PackageReference Include="Aspire.Hosting.Go" Version="*" />

Use AddGoApp / addGoApp to add a Go application to your AppHost. By default, Aspire runs go run . from the application directory.

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp("api", "./api")
.WithHttpEndpoint(port: 8080, env: "PORT")
.WithExternalHttpEndpoints();
builder.Build().Run();

The method accepts the following common parameters:

  • name: The name of the resource in the Aspire dashboard.
  • appDirectory: The path to the Go module root. This directory usually contains go.mod and is also the Docker build context for deployment targets that emit container build artifacts.
  • packagePath: The Go package to run or build relative to appDirectory. Defaults to ".".

Go applications commonly read the PORT environment variable set by WithHttpEndpoint / withHttpEndpoint:

main.go
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello from Go!")
})
log.Printf("Listening on :%s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}

Use appDirectory for the Go module root, and use packagePath when the main package is under a subdirectory such as cmd/server.

For a common layout like this:

Go app layout
api/
|-- go.mod
|-- internal/
`-- cmd/
`-- server/
`-- main.go

Configure the AppHost to run go run ./cmd/server from ./api:

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp(
name: "api",
appDirectory: "./api",
packagePath: "./cmd/server")
.WithHttpEndpoint(env: "PORT");
builder.Build().Run();

The same packagePath is used for local run mode, headless Delve debugging, and publish-time go build.

Go build-time options are parameters on AddGoApp / addGoApp. Aspire passes them to go run during local development and to go build when it generates a Dockerfile for publish.

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp(
name: "api",
appDirectory: "./api",
packagePath: "./cmd/server",
buildTags: ["netgo", "integration"],
ldFlags: "-X main.version=1.2.3 -s -w",
gcFlags: "all=-N -l",
raceDetector: true);
builder.Build().Run();

The options map to Go command-line flags:

  • buildTags: Adds -tags=<tag1>,<tag2>.
  • ldFlags: Adds -ldflags=<value>.
  • gcFlags: Adds -gcflags=<value>.
  • raceDetector: Adds -race in local run mode. The generated Dockerfile excludes -race because race detection requires CGO and publish builds create a static Linux binary.

Use WithAppArgs / withAppArgs to pass arguments to the Go program after the package path.

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp("api", "./api")
.WithAppArgs("--config", "dev.yaml")
.WithHttpEndpoint(env: "PORT");
builder.Build().Run();

In normal run mode, this produces a command like go run . --config dev.yaml. In headless Delve mode, Aspire passes the app arguments after Delve’s -- separator.

The Go integration can run common module and static analysis commands before the app starts. These helpers create setup resources in run mode and make the Go app wait for them to complete.

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp("api", "./api")
.WithModTidy()
.WithModVendor()
.WithModDownload()
.WithVetTool()
.WithHttpEndpoint(env: "PORT");
builder.Build().Run();

The helper methods run these commands:

  • WithModTidy / withModTidy: Runs go mod tidy -e.
  • WithModVendor / withModVendor: Runs go mod vendor.
  • WithModDownload / withModDownload: Runs go mod download.
  • WithVetTool / withVetTool: Runs go vet ./....

When multiple module helpers are configured, Aspire orders them so dependency-changing steps complete before later module cache or vendor steps.

Go app resources automatically support VS Code debugging when the Go extension for Visual Studio Code (golang.go) is installed.

The Aspire VS Code extension detects the golang.go extension and, when you start your AppHost in debug mode, launches the Go debugger via dlv-dap. No additional configuration is required beyond AddGoApp / addGoApp. Any buildTags, ldFlags, or gcFlags configured on the resource are automatically forwarded to Delve as build flags, so the debugger compiles your program with the same flags used during normal development.

For GoLand, VS Code attach mode, or another Delve-compatible client, use WithDelveServer / withDelveServer. This replaces the application command with a headless Delve server, such as dlv --headless=true --listen=127.0.0.1:2345 --api-version=2 debug ..

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp("api", "./api")
.WithDelveServer(port: 2345)
.WithHttpEndpoint(port: 8080, env: "PORT");
builder.Build().Run();

Start your attach configuration after the Go resource is running in the Aspire dashboard. For GoLand, create a Go Remote configuration with host localhost and port 2345. For VS Code attach mode, add a launch configuration like this:

.vscode/launch.json
{
"name": "Attach to api",
"type": "go",
"request": "attach",
"mode": "remote",
"host": "localhost",
"port": 2345
}

When a publisher or deployment target emits container build artifacts for a Go app, Aspire uses the appDirectory as the Docker build context:

  • If the app directory already contains a Dockerfile, Aspire uses it.
  • If no Dockerfile exists, Aspire generates a multi-stage Dockerfile.
  • The generated Dockerfile uses a golang:<version>-alpine build image by default. Aspire detects the Go version from go.mod, preferring a toolchain directive over the go directive when both are present.
  • The build stage runs go mod download, caches the module and build caches, and builds a static Linux binary with CGO_ENABLED=0 and GOOS=linux.
  • The runtime stage uses a small runtime image, installs certificate and time zone data for Alpine-based images, creates a non-root app user, and starts the compiled binary.
  • The generated go build command uses the same packagePath, buildTags, ldFlags, and gcFlags configured on the Go app resource. It intentionally excludes raceDetector for publish builds.

For private modules, use WithGoPrivate / withGoPrivate to configure the generated Dockerfile with GOPRIVATE and BuildKit secret-based authentication. This setting only affects generated Dockerfiles; local run mode continues to use the developer’s local Go and Git credentials.

C# — AppHost.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddGoApp("api", "./api")
.WithGoPrivate(["github.com/myorg"], "github.com");
builder.Build().Run();

For more information about publishing Aspire apps, see Deployment overview.

The Aspire.Hosting.Go integration can be used from C# and TypeScript AppHosts. Aspire also includes experimental Go AppHost and Go starter template support in the Aspire CLI. The Go AppHost templates use experimental Go AppHost APIs instead of the Aspire.Hosting.Go package. To enable Go AppHost language support for CLI templates, enable the Go polyglot feature flag:

Aspire CLI
aspire config set features:experimentalPolyglot:go true --global

After enabling the feature, you can create a Go starter app with:

Aspire CLI
aspire new aspire-go-starter

For more information about feature flags, see Aspire CLI configuration. For template command details, see aspire new.