railpack

Configure and troubleshoot Railpack builds, with emphasis on RAILPACK_* environment variables, railpack.json overlays, build-plan inspection, local CLI installation and usage, and local BuildKit containers. Use for Railpack provider configuration, custom install/build/start commands, Mise or Apt packages, build or runtime variables and secrets, generated-plan debugging, BUILDKIT_HOST errors, or running Railpack from a release or source checkout.

Install
npx skills add 'https://github.com/railwayapp/railpack/tree/main/.'
Incomplete bundle · no download
main · 21a254fScanned 2026-09-17

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

buildkit/convert.go

buildkit/convert.goBrowse 1970 files
View on GitHub
← Back to SKILL.md
// converts a railpack build plan to a BuildKit LLB state and image configpackage buildkit import (	"fmt"	"maps"	"slices"	"strconv"	"strings"	"time" 	"github.com/moby/buildkit/client/llb"	"github.com/moby/buildkit/util/system"	specs "github.com/opencontainers/image-spec/specs-go/v1"	"github.com/railwayapp/railpack/buildkit/build_llb"	p "github.com/railwayapp/railpack/core/plan") type ConvertPlanOptions struct {	BuildPlatform specs.Platform 	// Hash of all the secrets values that can be used to invalidate the layer cache when a secret changes	SecretsHash string 	// Unique value prepended to all cache mount keys	CacheKey string 	// BuildKit session ID	SessionID string 	// Token used to make authenticated API requests to GitHub to increase rate limits	GitHubToken string	// Do not use cache when building	NoCache bool} const WorkingDir = "/app" func ConvertPlanToLLB(plan *p.BuildPlan, opts ConvertPlanOptions) (*llb.State, *Image, error) {	platform := opts.BuildPlatform 	// by default, the whole directory is transferred into context, we don't need to explicitly include it	localOpts := []llb.LocalOption{		llb.SharedKeyHint("local"),		llb.SessionID(opts.SessionID),		llb.WithCustomName("loading ."),	} 	// note that exclude patterns can contain inverse (inclusions) patterns. The llb.IncludePatterns should *not* be used for this	if len(plan.Exclude) > 0 {		localOpts = append(localOpts, llb.ExcludePatterns(plan.Exclude))	} 	localState := llb.Local("context", localOpts...) 	cacheStore := build_llb.NewBuildKitCacheStore(opts.CacheKey)	graph, err := build_llb.NewBuildGraph(plan, &localState, cacheStore, opts.SecretsHash, &platform, opts.GitHubToken, opts.NoCache)	if err != nil {		return nil, nil, err	} 	graphOutput, err := graph.GenerateLLB()	if err != nil {		return nil, nil, err	} 	state := getStartState(*graphOutput.State)	imageEnv := getImageEnv(graphOutput, plan) 	startCommand := plan.Deploy.StartCmd	if startCommand == "" {		startCommand = "/bin/bash"	} 	image := Image{		Image: specs.Image{			Platform: specs.Platform{				OS:           platform.OS,				Architecture: platform.Architecture,			},			RootFS: specs.RootFS{				Type: "layers",			},		},		Variant: platform.Variant,		Config: specs.ImageConfig{			Env:        imageEnv,			WorkingDir: WorkingDir,			Entrypoint: []string{"/bin/bash", "-c"},			Cmd:        []string{startCommand},		},	} 	return &state, &image, nil} func getStartState(buildState llb.State) llb.State {	startState := buildState.Dir(WorkingDir)	return startState} func getImageEnv(graphOutput *build_llb.BuildGraphOutput, plan *p.BuildPlan) []string {	paths := []string{}	paths = append(paths, plan.Deploy.Paths...)	paths = append(paths, graphOutput.GraphEnv.PathList...)	paths = append(paths, system.DefaultPathEnvUnix)	slices.Sort(paths)	pathString := strings.Join(paths, ":") 	envMap := make(map[string]string, len(graphOutput.GraphEnv.EnvVars)+len(plan.Deploy.Variables)+2)	maps.Copy(envMap, graphOutput.GraphEnv.EnvVars)	maps.Copy(envMap, plan.Deploy.Variables) 	envMap["PATH"] = pathString	envMap["RAILPACK_BUILT_AT"] = strconv.FormatInt(time.Now().Unix(), 10) 	envVars := make([]string, 0, len(envMap))	for _, k := range slices.Sorted(maps.Keys(envMap)) {		v := envMap[k]		envVars = append(envVars, fmt.Sprintf("%s=%s", k, v))	} 	return envVars}