Last active
April 20, 2023 17:51
-
-
Save sheldonhull/84f45fc521274f144c01f3a02d494298 to your computer and use it in GitHub Desktop.
optimze dagger go sdk build speed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"os" | |
"os/exec" | |
"path/filepath" | |
"github.com/pterm/pterm" | |
) | |
// Build contains the mage task for ... building stuff ... duh. | |
type Build mg.Namespace | |
const ( | |
// ArtifactDirectory is a directory containing artifacts for the project and shouldn't be committed to source. | |
ArtifactDirectory = ".artifacts" | |
// PermissionUserReadWriteExecute is the permissions for the artifact directory. | |
PermissionUserReadWriteExecute = 0o0700 | |
// CacheDirectory is where the cache for the project is placed, ie artifacts that don't need to be rebuilt often. | |
CacheDirectory = ".cache" | |
) | |
var( | |
// TargetBuildDirectory is the directory where the build artifacts are placed and should be ignored by git. | |
TargetBuildDirectory = filepath.Join(ArtifactDirectory, "builds") | |
) | |
// MyApp builds the myapp service using Dagger. | |
// | |
// Development notes: This is a fully containerized build. | |
// Running go build locally was approx 3 seconds faster without further tuning, so I'm leaving the build method to use Dagger/BuildKit here to easily support containerized builds. | |
func (Build) MyApp() error { | |
ctx := context.Background() | |
pterm.DefaultHeader.Println("Building with Dagger") | |
if err := os.MkdirAll(filepath.Join(constants.TargetBuildDirectory, "myapp"), constants.PermissionUserReadWriteExecute); err != nil { | |
return err | |
} | |
// initialize Dagger client | |
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout)) | |
if err != nil { | |
return err | |
} | |
defer client.Close() | |
// get reference to the local project | |
src := client.Host().Directory(".") | |
cachedBuild := client.CacheVolume("go-build-cache") | |
cachedMod := client.CacheVolume("go-mod-cache") | |
modcache := "/nonroot/.cache/go-mod-cache" | |
buildcache := "/nonroot/.cache/go-build-cache" | |
// get `golang` image | |
golang := client.Container().From("cgr.dev/chainguard/go:latest"). | |
WithEnvVariable("CGO_ENABLED", "0"). | |
WithEnvVariable("GOOS", runtime.GOOS). | |
WithEnvVariable("GOARCH", runtime.GOARCH). | |
WithEnvVariable("GOMODCACHE", modcache). | |
WithEnvVariable("GOCACHE", buildcache) | |
// mount cloned repository into `golang` image | |
golang = golang.WithMountedDirectory("/src", src). | |
WithWorkdir("/src"). | |
WithMountedCache(modcache, cachedMod). | |
WithMountedCache(buildcache, cachedBuild) | |
// define the application build command | |
outputDirectory := filepath.Join(constants.TargetBuildDirectory, "myapp") | |
outputFile := filepath.Join(outputDirectory, "myapp-service") | |
golang = golang.WithExec([]string{"build", "-o", outputFile, "-ldflags", "-s -w", "-trimpath", "./myapp/main.go"}) | |
// get reference to build output directory in container | |
output := golang.Directory(outputDirectory).File("myapp-service") | |
// write contents of container build/ directory to the host | |
_, err = output.Export(ctx, outputFile) | |
if err != nil { | |
return err | |
} | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment