#Builds requiring os dependencies

1 messages · Page 1 of 1 (latest)

craggy valley
#

Hey everyone!

I was playing around with the Go sdk last night and couldn't get my head around how to RUN the os dependencies (apt update -y && apt install foo bar) as a base stage like I normally do in my Dockerfiles that is then cached as a layer and used for subsequent stages.

Should I be thinking about this differently or should I just run .WithExec(string[]{"/bin/sh", "-c", "apt update -y && apt install foo bar"}) and use the output somehow before creating a new Container() instance?

fathom root
# craggy valley Hey everyone! I was playing around with the Go sdk last night and couldn't get ...

Hi 👋
You are right. Here is a repro:

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "dagger.io/dagger"
)

func main() {
    client, err := dagger.Connect(context.Background(), dagger.WithLogOutput(os.Stderr))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // create a container, lazily executed (later)
    ctr := client.Container().From("alpine")

    // add package, lazily executed too (later)
    ctrWithCurl := ctr.WithExec([]string{"apk", "add", "curl"})

    // curl google
    // Here, the ctr + ctrWithCurl gets computed + cached.
    // Any subsequent command relying on ctrWithCurl will rely on that cached layer.
    output, err := ctrWithCurl.WithExec([]string{"curl", "google.com"}).Stdout(context.TODO())
    if err != nil {
        log.Fatal("did not manage to curl google", err)
    }
    fmt.Println("google", output)

    // curl yahoo
    // relies on ctrWithCurl, which has been cached
    output, err = ctrWithCurl.WithExec([]string{"curl", "yahoo.com"}).Stdout(context.TODO())
    if err != nil {
        log.Fatal("did not manage to curl google", err)
    }
    fmt.Println("yahoo", output)
}
#

You do not need to execute. The way Dagger works, your code gets resolved as N graphQL queries.

For example, ctr := client.Container().From("alpine") creates a graphQL query, but output, err := ctrWithCurl.WithExec([]string{"curl", "google.com"}).Stdout(context.TODO()) actually runs it (including the referenced ones along the way ctr and ctrWithCurl in above example).

As we have a strong cache, you indeed just need to add your apk add command with a WithExec to add it to your container. You then just need to rely on the return container to exec any command, these will not be computed again. Or, to be precise, they will be computed again, but be skipped because the state of the layers represented by your container variable would have been cached 😇