#docker
1 messages Β· Page 1 of 1 (latest)
Will dagger parse cache vols in dockerfiles? or do I have to mount them explicitly with the sdk?
example
RUN --mount=type=cache,target=/var/cache/apt apt-get update
Corresponding dagger is pretty simple.
runtimeContainer := daggerClient.Container().Build(buildDir)
I can't recall how that worked exactly, but should be quite easy to try π
I assume it'd work automatically.. but can't be 100% sure
it works, just verified it quickly
Is there some way to check caching like this? Cache vols etc?
I see the "CACHED" in output, but tbh it's a little opaque where the cache comes from (vols or dagger/buildkit magic)
CACHED will always come from dagger
if you see a CACHED for the build op is because the Dockerfile didn't get re-executed
I guess it's not exactly relevant then if the cache is coming from a mounted volume?
That's moreso just a tweak to help handle the storage of the cache?
and to clarify I see cached on just that run step
if you see CACHED from the run step that means that it wasn't re-executed.
I think I got a bit lost about what your main doubt is
I guess I'm a little lost on what a cache volume actually does that's different from regular caching. I'll read up on it in buildkit docs - doesn't sound like a dagger thing
Cache volumes are directories that Dagger persists for you in between runs, in a best effort way. This allows application-specific caching to work properly in Dagger.
Also discussed here: #1124075148786544671 message
Just today @dim gyro suggested we could call them just "volumes"
which would maybe reduce confusion with the "other" dagger caching?
I have a Podman build/run host going but finding building user-provided Dockerfiles from scratch in it each time takes quite a while - is there any way to utilize Dagger or another tool to automatically cache individual steps wihtin a dockerfile so subsequent runs wiht similr initial steps are faster? I saw the mode=max from the old version of Dagger and seemed along the lines of what I'm looking for
(Or alternatively is there a container dependency spec format like Dockerfile which Dagger could use and do that intermediate caching?)
π is your Dagger host stateful? If that's the case then building with Dagger will preserve the cache as long as you're not running an operation which invalidates.
yes! I can mount persisted volumes (running within fly.io)
ok, in that case you can use Dagger's WithCacheVolume operation to add persistent volumes to your pipelines so it doesn't take that much each time. Let us know if you need some helping setting that up
I remember seeing a package that created dagger service containers from a docker compose file. Is that around somewhere or I was just dreaming?
Also, if it is around, does it support features like health checks? (ie. wait for containers to be healthy before running some actual tests)
if you use serviceBind's it will automatically check for previously exposedPorts to be open, which should indicate "healthy"-ness.
Question: Can Daggers Python SDK parse dockerfile snippets?
Im exploring an idea where Dagger creates a "base image" and our developers can use a partial Dockerfile to extend that base image
https://github.com/vito/dagger-compose. courtesy of @hard sundial π
Awesome, thanks!
Yes you can use directory.dockerBuild
which will produce a container
but parsing without executing - no
I think you could probably use a package like this together with dagger to accomplish what you're describing https://pypi.org/project/dockerfile-parse/
π Hey folks. I'm trying to understand what's going on under the hood with Dagger and I feel like I'm missing something. The docs suggest that Dagger runs docker CLI commands. But as actions are running I don't see any containers running when I run docker ps other than the Dagger image registry. I assumed I would see something. What am I missing?
Welcome π The most important thing to know is that Dagger doesnβt integrate with docker in any special way. At most, the dagger engine is run in a container with docker run, as a default convenience. But any other tool that can run a container will do. From there, dagger does its own thing to run its own containers
@neon void at the system level (linux cgroups, namespaces etc) you will see dagger-managed and docker-managed containers side by side
but actually Iβm wondering if we could improve compat with docker specifically, by taking advantage of the fact that we share the underlying dependency on containerd.
That makes sense. As you can probably guess I'm still fiddling with testcontainers. No lucky Daggerizing my project just yet though.
do you have a repo or code snippet you can share?
do you have a repo or code snippet you
This is the repo: https://github.com/mattupstate/acme (it's a hobby project I teach myself things through) but there isn't any Dagger code in there yet. My first attempt looked like this
import { connect } from "@dagger.io/dagger"
connect(async (client) => {
const mavenCache = client.cacheVolume("maven-cache")
const gradleCache = client.cacheVolume("gradle-cache")
const test = client.container().from("gradle:8.3.0-jdk17")
.withUnixSocket("/var/run/docker.sock", client.host().unix_socket("/var/run/docker.sock"))
.withMountedCache("/home/gradle/.m2", mavenCache)
.withMountedCache("/home/gradle/.gradle", gradleCache)
.withDirectory("/home/gradle", client.host().directory("."), { exclude: [".gradle/", "ci/", "node_modules/", "acme-app/acme-app-web/node_modules/"] })
.withExec(["gradle", "test"]).stderr()
console.log(test)
}, { LogOutput: process.stdout })
But that obviosly doesn't work since the containers aren't addressable from the gradle container. I tried running the docker engine as a service container but didn't really get anywhere with that either.
You need to run the docker engine in a privileged container: https://docs.dagger.io/current/sdk/nodejs/reference/modules/api_client_gen#containerwithexecopts
By passing insecureRootCapabilities as an option to WithExec
RIght, I gathered that much. I had something that looked like this:
import { connect } from "@dagger.io/dagger"
connect(async (client) => {
const dockerEngine = client.container().from("docker:dind")
.withExposedPort(2375)
.withExec(["dockerd", "--host=tcp://0.0.0.0:2375"], { insecureRootCapabilities: true})
const mavenCache = client.cacheVolume("maven-cache")
const gradleCache = client.cacheVolume("gradle-cache")
const test = client.container().from("gradle:8.3.0-jdk17")
.withServiceBinding("docker", dockerEngine)
.withMountedCache("/home/gradle/.m2", mavenCache)
.withMountedCache(process.cwd() + "/.gradle", gradleCache)
.withDirectory(process.cwd(), client.host().directory("."), { exclude: [".gradle/", "ci/", "node_modules/", "acme-app/acme-app-web/node_modules/"] })
.withWorkdir(process.cwd())
.withEnvVariable("DOCKER_HOST", "tcp://docker:2375")
.withExec(["gradle", "test"]).stderr()
console.log(test)
}, { LogOutput: process.stdout })
But I hit this error with testcontainers and kinda gave up after getting this error in the attachment
Hey, I'm also hitting my head when trying to give access to my CDK container to run Docker build. Any tips? Using Golang. Iterated with what there's above and ended up with this, but it's still complaining that Unable to execute 'docker'
package main
import (
"context"
"fmt"
"os"
"path"
"path/filepath"
"dagger.io/dagger"
)
const WORKDIR = "/app"
func main() {
ctx := context.Background()
// create Dagger client
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr))
if err != nil {
panic(err)
}
defer client.Close()
codePath, err := filepath.Abs("..")
if err != nil {
panic(err)
}
cdkDir := client.Host().Directory(codePath)
dockerEngine := client.Container().From("docker:dind").
WithExposedPort(2375).
WithExec([]string{"dockerd", "--host=tcp://0.0.0.0:2375"}, dagger.ContainerWithExecOpts{InsecureRootCapabilities: true})
ctr := client.Container().
From("robertd/alpine-aws-cdk:2.99.0").
WithServiceBinding("docker", dockerEngine).
WithDirectory(WORKDIR, cdkDir).
WithWorkdir(path.Join(WORKDIR, "infra")).
WithUnixSocket("/var/run/docker.sock", client.Host().UnixSocket("/var/run/docker.sock")).
WithEnvVariable("DOCKER_HOST", "tcp://docker:2375").
WithEnvVariable("AWS_DEFAULT_REGION", "eu-north-1").
WithEnvVariable("AWS_ACCESS_KEY_ID", os.Getenv("AWS_ACCESS_KEY_ID")).
WithEnvVariable("AWS_SECRET_ACCESS_KEY", os.Getenv("AWS_SECRET_ACCESS_KEY")).
WithExec([]string{"cdk", "deploy", "--all"})
stdout, err := ctr.Stdout(ctx)
fmt.Println(stdout)
if err != nil {
panic(err)
}
}
Hey is there a way to pass --cgroupns host to the container at the moment? I need to access /sys/fs/cgroup from container
nope, not currently unfortunately. Could you open an issue describing the use-case please? π
it is related with zenith modules. Should I open issue at dagger/dagger repo or create post in #1151970583723126844 ?
a dagger issue would be better since this requires a more in-depth work to be supported
Hello I'd like to asks, I try to run dagger engine on docker container, and uses _EXPERIMENTAL_DAGGER_RUNNER_HOST env var. I'm following this comment to run the engine.
When I run it, the logs always return Unknown desc = server not found once, before succeeding. Is anyone know how to resolve it?
π take into account that you can't run stand-alone buildkit anymore you need to use the dagger engine
you can run the engine in docker as simple as: docker run -d --privileged --name dagger-engine registry.dagger.io/engine:v0.8.8
you can then set _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-container://dagger-engine and it should work
Ah yeah I think I didnβt explain me well
I run the engine manually with that command, but expose it via TCP instead. And that so what Iβve got
I see .. are you still getting this error?
this worked for me:
docker run -d --privileged --name dagger-engine-779fedd2902d2511 -p 1111:1111 registry.dagger.io/engine:v0.8.8 --addr tcp://0.0.0.0:1111
_EXPERIMENTAL_DAGGER_RUNNER_HOST=tcp://0.0.0.0:1111 dagger run go run main.go
sorry for late reply.
Yes it still happening
β _EXPERIMENTAL_DAGGER_RUNNER_HOST=tcp://private-ip:1234 go test -v
=== RUN TestStructure
Creating new Engine session... OK!
Establishing connection to Engine... 1: connect
1: > in init
1: starting engine
1: starting engine [0.10s]
1: starting session
1: [0.14s] Failed to connect; retrying... name:"error" value:"make request: Post \"http://dagger/query\": rpc error: code = Unknown desc = server \"abneknncwm0x16252f0lm9f5i\" not found"
1: [0.28s] OK!
1: starting session [0.18s]
1: connect DONE
OK!
The execution is done, no error at the end, but the logs always come like this.
oh, I see.. we just opened an issue for that incorrect error message here: https://discord.com/channels/707636530424053791/1164242960167206922
but the pipeline works
Thanks for link it up back π
π i am looking for host network equivalent in dagger. docker run/build --network host using Go SDK. anyone know how? 
You can bind your containers to host services, see https://dagger.io/blog/dagger-0-9
I did go through that doc. The trouble is I am using tailscale and the image pull always fails unless I set --network host. Maybe my problem is elsewhere in tailscale lalaland.
sorry for the slow response, I am at Kubecon at the moment. If I understand correctly, your host machine is on the tailscale network, and your docker build requires access to that network so it can pull an image.
Dagger doesnβt support the equivalent of docker build βnetwork host. But there are a few options:
-
You could run tailscale in a container, managed by dagger, and maybe we can find a way to hook that up to the
dockerBuildcall. Perhaps we could add a service binding call? @heavy garden @hard sundial @dusk ridge -
if itβs an option, consider replacing that Dockerfile with a pure Go implementation, then you can definitely hook up tailscale for your image pull
Option 1 sounds super cool. Seems a little tricky, since of how we wire up dockerBuild today, but not impossible - I've opened an issue in https://github.com/dagger/dagger/issues/6089.
We should definitely do it IMO, since the same thing that stops services from working like this also stops secret scrubbing working in RUN steps (which feels sad).
I was chatting with Solomon about this and I have the theory that the problem here is not networking per-se but DNS (of course, it always is). Since tailscale ruining on the host only sets up a tun device and modifies routing tables accordingly. It also modifies the host resolv.conf file by adding their special 100.100.100.100 DNS entry for their magic DNS thingy. I have a hunch that what's happening here is that dagger containers are not getting set the correct DNS server and therefore they can't resolve the proper IP so they're routed through the tailnet. I'll give it a try next week to validate this.
Do you see a clean solution to this?
Yes, having a true stateless engine locally should solve this. Since today, in local the engine is long living and if the host network config change, it won't pick up those changes
But do we want the host dns to leak into the containers?
Stateless as the dagger-engine process stops once the pipeline finishes
Well.. it's very convenient and it's what buildkit does when spinning new containers by default
Thing is because we run it containerized (and long living) locally, these weird networking drifts are exposed.
Hey π, I have an existing set of integration tests that are using testcontainers-go and I'm migrating our automation tooling to use dagger. Test containers is spinning up lots of containers on dynamic ports that the test are then connecting to. Because I don't know the ports that the containers will be running on ahead of time I cannot mount the host's docker socket and map the ports. I've ended up using docker in docker (docker:dind) to get this to work with various hacks. Just wondering if there's a better way to approach this that doesn't require migrating the tests to dagger services as well?? Thanks!
Best practice would be wrapping your services to dagger services. However, as low hanging fruit here, you can try to start docker-in-dagger as service and set it as DOCKER_HOST in your setup. https://github.com/aweris/daggerverse/tree/main/docker I write a dagger module for my internal use-case but you can try to use this
Yeah this is how we've been able to get testcontainers running in dagger without modifying anything in the past. Let me know if you run into anything @rough peak
great, thanks I'll give this module a go instead of my home grown container and let you know! Thanks @latent pebble
This is how i use it https://github.com/aweris/gale/blob/f2d1acacc4f17341ce8e7b469c4a5fb7f60947bb/daggerverse/gale/runner.go#L70-L71 just as additional info
Hey @latent pebble , just an update. So using your dind module worked to allow the tests (and testcontainers-go) to talk to the Docker daemon. However, once the containers (e.g. Redis) were spun up the tests could not reach their exposed ports as Dagger doesn't know those ports in advance and thus can't map them. Given test containers randomly allocates these ports at runtime I'm not sure how I could wrap them in a service either without dropping test containers and using Dagger instead so I've had to stick with running everything (tests + docker) inside the same container which is proving pretty slow and flakey.
probably you need to look up container ip from docker config
https://github.com/aweris/daggerverse/blob/main/kind/kind.go please look this getClusterIPAddress method
This could give an idea to how to continue
Thanks, so I'm using Dagger to ultimately invoke a go test command that has some setup using testcontainers-go. I've updated those test so when we build the config for our services off the containers we use the container IP and no port mapping. The test containers are running on the bridge network. I'm getting the error dial tcp 172.17.0.15:3306: connect: no route to host from the tests. Is there anything Dagger specific I should be doing to allow the tests that are executing in a container created by Dagger to connect to those containers created by test containers on the bridge network? Appreciate your help! π
@hard sundial we may need your help on thisβ¦
This is probably worth a guide/cookbook/something in the docs, seems like a lot of people are trying to do it. cc @uncut mason (Also doesn't Airbyte do this? I know they use dind and TestContainers but can't find where the two fingers on the Sistine Chapel meet... https://github.com/airbytehq/airbyte/blob/ea5e4bf07de4ec2d366c4013d2f487f2ece91606/airbyte-ci/connectors/pipelines/pipelines/dagger/actions/system/docker.py#L30)
@rough peak Dagger's container-to-container networking doesn't need to map ports upfront; it's all just over DNS/IP. If there's some way to configure TestContainers to expose service ports to the dind container, they'll be reachable via the service's address (or alias) as long as those ports are listening on 0.0.0.0. You should just need to take the IP:port returned by TestContainers and swap the host portion out for either your WithServiceBinding("<alias>", dind) alias or dind.Hostname(). I'm not super familiar with using TestContainers but that seems like the best bet.
Thanks everyone π. I got it working, the key was updating the tests to use the service alias for the hostname which I hadn't appreciated would resolve from the tests.
cooked up a quick module after some trial + error, will show it during tomorrow's community call: https://daggerverse.dev/mod/github.com/vito/daggerverse/testcontainers@bc816f2d1784c2af7f4e1bd93edd4645ac21ccff
demo: dagger call -m github.com/vito/daggerverse/test testcontainers
What did you use previously? Iβd love to document it somehow on testcontainers side as well perhaps?
My initial idea is that genericContainer.getHost() should return the correct thing, did it not work?
I was using container.Host(ctx) but now when running with dagger I override with the service alias explicitly
one thing I have noticed with using Dagger + TestContainer is when running test suites in parellel (each that are using test containers) I get flakey behavior and some testcontainers fail to be created. Explicitly running with -p=1 works consistently though
My coworker and I are working through an interesting issue. We want to be able to select the tag we use for our build container using a docker build arg.
We wrote the following typescript and Dockerfile.
import { connect } from "https://esm.sh/@dagger.io/dagger@0.9.3";
import path from "node:path";
import { fileURLToPath } from "node:url";
import process from "node:process";
const projectDir = path.resolve(fileURLToPath(import.meta.url), `../..`);
const buildTag = Deno.env.get("BUILD_TAG") || "latest";
connect(
async (client) => {
const source = client.host().directory(projectDir);
console.log(`Building with alpine:${buildTag}`);
await source
.dockerBuild({
buildArgs: [
{
name: "BUILD_TAG",
value: "3.14.2",
},
],
})
.stdout();
},
{
LogOutput: process.stdout,
},
);
ARG BUILD_TAG
FROM alpine:${BUILD_TAG} as build
RUN echo "Build TAG: ${BUILD_TAG}"
This docker file works in docker but not when using dagger.
The build arg is just not populated.
Seems like we should just maybe refactor to remove the dockerfile.
@lethal rampart I think you could def refactor to remove the Dockerfile, but could you tell me, how are your running this with deno?
I'm super interested in what your final command line invocation looks like π
Just βdagger run deno run -A file.tsβ the npm dagger module doesnβt work right now. But the source I added has the polyfills to make it work right.
ah, does -A allow all the things?
I was entertained as deno asked me for each permission for file-read, file-write, env-read, etc
@lethal rampart I saw this StackOverflow and tried this
https://stackoverflow.com/questions/47459614/docker-argument-to-a-run-echo-command
First: Make sure, your ARG comes after your FROM. See: https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
My adjusted Dockerfile:
ARG BUILD_TAG
FROM alpine:${BUILD_TAG} as build
ARG BUILD_TAG
RUN echo "Build TAG: ${BUILD_TAG}"
works!
My adjusted file.ts
import { connect } from "https://esm.sh/@dagger.io/dagger@0.9.3";
import path from "node:path";
import { fileURLToPath } from "node:url";
import process from "node:process";
const buildTag = Deno.env.get("BUILD_TAG") || "latest";
connect(
async (client) => {
const source = client.host().directory(".");
console.log(`Building with alpine:${buildTag}`);
await source
.dockerBuild({
buildArgs: [
{
name: "BUILD_TAG",
value: "3.14.2",
},
],
})
.stdout();
},
{
LogOutput: process.stdout,
},
);
My simple project:
Dockerfile
file.ts
For the goal of having an identical build pipeline between CI & local, one area where Dagger has been falling short for me container artifacts. With pretty much all of my pipelines, the end result is a container. Testing locally, I obviously don't want to publish that to our company registry. I've been using the container export, but it's pretty inconvenient - spitting out a tar that needs to be imported and tagged on the host. One possibility I'm considering is writing a "helper" function that eliminates some of that inconvenience, but I want to pursue another option first.
Publishing to a local registry is obviously going to be a lot simpler and more consistent between local & CI runs. My only hesitation in just going for it is I don't want these images stored on my disk twice over - once in the registry, once in Docker/Podman itself. This got me thinking, there's got to be a way to use the "Docker/Podman itself" storage as a registry. So, at the moment, I'm searching through GitHub and Google, trying to find such a thing, and somewhat surprised that I'm at a loss so far.
Has anybody ever come across anything like that? Is it possible to have Dagger push the final image into the host's OCI image storage as if it were a registry? Or is there some other solution and I'm going about this the wrong way?
Each container runtime will have a different way to import images - so if we implemented something like DockerImport in dagger, then it would just work for dagger/similar commands.
Also worth keeping in mind that the image store that docker uses out-of-the-box is quite bad for storing images (yes, that's weird) - it mutates image digests, it removes OCI annotations, it can't handle multi-platform, etc. Thankfully, that's changing with https://github.com/docker/roadmap/issues/371 (just a side note, maybe it affects you wanting to import to docker).
Push to local registry
@viscid basin I think the upcoming Zenith release will help with this. It introduces a concept of Dagger Function, which lets you break down your pipeline logic into discrete units with clear inputs and outputs. So instead of trying to make the entire pipeline the same across CI and dev, you would simply call the same functions, with slightly different inputs or outputs connected
Is there a way to get around DinD? using kaniko or whatever else?
Hi π If you're running in Kubernetes, you don't need Docker/DinD: https://docs.dagger.io/194031/kubernetes/
Dagger-in-Docker should be possible with normal (not Kubernetes) Docker/Podman, and without a docker cli binary, right? From everything I've read it seems like it should work but I must be missing some detail. I have the socket piped into the container via a host service. .withExec['curl'...] can communicate with my Podman socket successfully, but .withExec['sh', '-c', 'echo ... | dagger query'] hangs forever on Dagger trying to connect to the engine. I have _EXPERIMENTAL_DAGGER_RUNNER_HOST = "docker-container://dagger-engine.dev", and this is confirmed to echo out properly in the withExec as well.
hi, maybe it is a dumb question... but here it is
what I like about docker is that is kind become a standard, but I have the impression that with dagger we should do without a Dockerfile nor docker compose / docker buildx bake π€ did I get it wrong? is it possible or advised to keep them / use them in dagger?
Dagger is designed to adapt to you π
So if you have Dockerfiles and want to use them, it's perfectly fine to do so, and we have native Dockerfile compatibility in the Dagger API to make that easy.
In other cases, Dockerfiles are just not powerful enough to express your build logic, and it's better to orchestrate your build as code.
Both are equally find, and supported.
I hope this helps!
Thank you π so if you would start a new projet, you would go full dagger? (no docker compose to start the project, no Dockerfile?)
There is built-in Dockerfile support, but indeed, you'll probably benefit by moving those to Dagger over time.
Docker Compose yaml isn't callable from Dagger yet, so you'd use Dagger Service Containers for those situations.
Let us know if we can help you get started π
Sorry for missing this!
Personally yes, with Functions support now shipped, I would start my new project with pure Dagger from the beginning. Granted I am already comfortable with it π
So my baseline would be pure Dagger, and I would then accommodate other constraints in a pragmatic fashion: my teammate's preference for certain tools, pre-existing stack, etc
Out of curiosity I searched for "Dagger Service Containers" and ended up here with a warning that the documentation is updated: https://archive.docs.dagger.io/0.9/757394/use-services/
Is there an equivalent page in the current docs?
Dagger v0.9.0 includes a breaking change for binding service containers. The Container.withServiceBinding API now takes a Service instead of a Container, so you must call Container.asService on its argument. See the section on binding service containers for examples.
Sorry about this. The guide is still valid (it's the same core API whether you're calling from a custom client, or from a Dagger Function). We need to move these guides over into the new docs asap.
You can follow the guide as-is, you'll just need to replace the main() function from your own Dagger Function in the examples, and it works the same.
Awesome, thanks for the speedy reply π
Is there something like docker compose for dagger, so we can easily "as-service up" multiple services?
Is there something like docker compose
Hi there, I'm trying to replace our docker-compose file with a dagger script(not using functions for this). We use postgres:16-alpine with an extra init-database.sh script. The problem I have is that the healtcheck succeeds as soon as postgress is running so my tests starts but the init-database.sh script isn't finished.
I saw there isn't support for custom healthchecks yet, but is there any other way to delay the service being used?
is the init script run by dagger? if so you can just wait for it to complete before running the tests
yeah, that is the tactic I switched to. Seems to work better
I have another question.. We spin up an openstack cluster in a single vm using a templated image that contains kolla-ansible. We don't have a DNS server with api available so we pull some dns tricks in /etc/hosts and --add-hosts to make it work. Since every pipeline spins up its own openstack instance the ip changes(but the dns record stays the same). Currently I'm solving this by starting up a dagger engine per pipeline: docker run -d --add-host=openstack-lab.company.net:${ip_address} --privileged --name dagger-${ip_address} registry.dagger.io/engine:v0.11.4. But that is not a great solution due to not being able to reuse the cache etc. Is there a way to add dns entries to dag.Containers()?
Yes you can pass a host service as argument to your function, and attach it to a container with Container.WithServiceBinding
Dagger's Service type can be backed either by a container, or by a tunnel to a service in the client's context
you need a static set of ports to forward though. do you have that with openstack?
Hmm, but that would only work if that port was on the host it self right? in my case this is a vm in a remote network
no it can be remote, as long as it's reachable on the client's network
aah
dagger call myfunc --openstack-server=tcp://1.2.3.4:4242
the CLI will translate that url to a Service object backed by a tunnel
I don't know if the single port is a limitation of the engine's tunnel API, or of the CLI
(I'm not using functions, since we're on gitea and thus can't pull modules directly. So still just running from a single file. But think I get the idea)
Is it possible to forward to the same host on multiple ports?
(it's a CLI limitation: https://docs.dagger.io/api/reference/#Host-service)
yes. call dag.Host().Service(). See the ports argument
That is what the dagger call CLI does under the hood
You can also find the API reference for your SDK of choice
awesome thanks! Think this should do the trick. If this works I should probably record something for #1075928318802657340 . We(safespring.com) are doing something pretty cool here. we've build an api around openstack and okd as a kind of self-service project. We can connect multiple openstack sites and okd clusters to it and have customers manage all their stuff(projects, quota's, users) from a single api. I'm working on getting the code tested against a full openstack cluster on every change while keeping the ci/cd times minimal.
That sounds very cool. Yes you should absolutely show it at a community call!
yes. call dag.Host().Service(). See
Is there any documentation around how dagger's caching is better than docker's standard caching? I'm just assuming it is...maybe its not? π I see things like
Caching by default: Dagger caches everything. Expect 2x to 10x speed-ups.
but I'm looking for info around how its better/what makes it better.
Ah when I searched again I got more hits and I think this answers my question
The layers cache: This caches build instructions and the results of withExec() API calls. It is implemented by Buildkit.
Yeah I think "Expect 2x to 10x speed-ups." is referring to daggerizing a CI pipeline in general, but not specifically just a docker build for example
@leaden scarab sounds awesome! I'll DM you
Hey, I have a question.
I am in the process of converting some GitHub Workflow actions+scripts to some Dagger modules.
Specifically for creating OCI containers I am a bit confused.
It seems that Dagger Containers are very similar to traditional Docker containers.
However, for a Container that is not meant to be constructed and used in a Dagger function, but rather built and published so that it can run somewhere, I am missing or perhaps just misunderstanding a few things.
Am I supposed to still use docker build or such for this, or should I be able to use Dagger Containers?
If I should be able to use Dagger Containers, how do I add health checks and metadata? Also, it seems Entrypoint works slightly different than a Dockerfile ENTRYPOINT.
Yes you can use dagger containers both to run yourself, or to build and publish. Same as in a dockerfile (the underlying tech is the same). You don't need a docker enginr, or a dockerfile, to build and publish containers (although there are compatibility bridges to both if really needed).
Entrypoint works the same. I don't think we have an API call for setting the "healthcheck" OCI field, or custom metadata. Should trivial to add.
the only difference with entrypoint is that Dagger doesn't need it when running a container, because being programmable, you can just implement the same thing directly in code. Same idea for healthcheck, onbuild.. Those are stopgaps to compensate for Docker not being properly programmable.
That said we should have full support for those OCI fields so that Dagger can build any image.
Thanks for you answers.
What I meant with Entrypoint behaving slightly different, is based on how I understand Dockerfile vs Dagger Container.
For Dockerfile, ENTRYPOINT is combined with CMD, or docker run args, to form the runtime command.
Dockerfile also has RUN which does not utilize ENTRYPOINT.
On the other hand, Dagger Container combines Entrypoint and WithExec, into what I would say roughly corresponds to RUN in Dockerfile.
However, when a Dagger Container is turned into a Dagger Service, the last WithExec becomes the runtime command (sort of like CMD).
I just wanted to highlight my confusion around these concepts.
When i was also working with understanding WithExec, WithoutEntrypoint etc etc. I came into a similiar situation as you @ember smelt
I wonder if a sort of "matrix/grid" like table that helps describe behavioural differences which may help people understand and migrate from docker to dagger easier?
hey folks, how do i use a local docker image in a Container.From invocation?
it keeps prepending docker hub
oof... just read that it's not supported by design
@muted sundial it's not supported in the core but you can do it yourself in code (written by you, or by another module). It's a very common use case.
probably easiest for me right now is to just mirror gcr in the engine config
General idea: you run the docker CLI in a container, with your local engine's unix socket passed as an argument. Then you translate container content back and forth with the likes of docker load and docker save
there are several dagger modules that implement this
- One by me: https://daggerverse.dev/mod/github.com/shykes/daggerverse/docker
- One by @hard sundial : https://daggerverse.dev/mod/github.com/vito/daggerverse/docker
- One by @dim gyro : https://daggerverse.dev/mod/github.com/kpenfound/dagger-modules/dockerd
We've been meaning to merge them, but didn't get around to it.
Note that until very recently, you couldn't pass a unix socket as argument to the CLI. So these modules focused on running an ephemeral docker engine in Dagger (yes you can do that too). That is very useful in many docker integration scenarios, but not what you're looking for in this case. Most of the logic orchestrating the docker CLI in a container is the same
@hard sundial @heavy garden can a Service be backed by a unix socket? If not, in this case I would probably still run a tcp-to-unix proxy in the container. Then the containerized Docker CLI is always configured to talk TCP.
this can be used to spin up dev containers through dagger now? right?
I think you could always do that. You need docker CLI and devcontainers CLI. But afaik, devcontainer CLI still doesn't allow port forwarding.
and that can be forwarded by docker cli, and we are good to go right?
Just for vanilla usage of devcontainer that may be enough. But if you wanted to "live-reload" something that devcontainers is hosting it may not be enough. The devcontainers CLI will have to support it. VSCode extension of devcontainers supports that. Maybe you can host the code-server and proxy that port. I've used devcontainers but by no means an expert on it.
Why will live-reload not be enough? And have you tried the code-server way?
I have not.
what if we are dropping dev container cli and directly using docker cli and then opening vs code in local with vs code url handler and connecting that dev conatiner with ssh remote or something for dev all throug dagger, possible?
This is what I'm referring to. https://github.com/devcontainers/cli/issues/22. But there seems to be ways around it - https://github.com/nohzafk/devcontainer-cli-port-forwarder. Theoretically you can run all of this in Dagger. I have not tested any of it yet.
alright thanks for guidance.
Is there an equivalent of ADD --link foo.tar to provide whole layer tarballs to dagger to build an image?
I'm not super familiar with it, but it looks like a hack to work around the lack of real programmability.
Since Dagger is programmable, you can just use variables and arguments to pass different directory or container states around
(but it's possible that I'm missing something)
Maybe --link is a distraction, but we already generate layer tarballs (with bazel) so I'm wondering how that would fit in with dagger
I'm totally new to dagger, just trying to get a feel for what it would replace of our existing stack
the link is all automatic fyi - it uses MergeOp internally in buildkit, which is the same underlying operation as dagger's WithDirectory
Ah cool
Like the goal is to make a docker image that contains a bunch of python, some c++ python extensions and some java
@dusk ridge @crisp blade the part I'm not sure I understand, is the reference to foo.tar, and to layer tarballs. I don't think COPY --link handles layer tarballs in any special way. And although Dagger has the ability to export an OCI tarball, I'm not it supports importing one
Hah seems like you do: https://dagger-io.readthedocs.io/en/sdk-python-v0.11.9/client.html#dagger.Container.import_
Indeed we do!
My concern is about changes to one layer causing a change to the hash of every subsequent layer, resulting in large uploads for a relatively small change when pushing the image
Dagger gives you all the tools to optimize this. And usually the default behavior is what you expect it to be.
Generally you only need to worry about this kind of "mass cache invalidation" when chaining lots of exec operations (withExec in the Dagger API) in a naive way.
Cool Iβll give it a shot
Hey all! Checking out dagger for a work project, trying to daggerize an existing docker-compose file. One of the containers brought up is a mongodb container, and we use the docker compose health check thing to wait for it to be up before starting other apps
Does something like this exist in dagger? Waiting for one container to finish initializing? I havent found anything like it in the docs, I may be searching for the wrong thing
Yes! Services are what you're looking for. Healthchecks are builtin to service bindings
Awesome! Thank you!
Hi π
I'm looking through the cookbook and I'm trying to simply build a docker image (using a Dockerfile) without publishing it, is it possible?
I have no problem building the image but I feel like I'm missing something to "write" it without publishing it (basically, doing a docker build -t name:tag.
EDIT: I'm realizing I might be trying to use dagger to do something it's not intended for π€
hey @granite mason you totally can do that! see https://docs.dagger.io/cookbook/#export-a-container-image-to-the-host
essentially, you just need to export the container to a file, and then you can docker load that in
Indeed ! Thanks a lot, I don't know how I missed that!
I'm sure this is a FAQ, but I swear I could not find an answer. Dagger integrated in Azure pipeline: I cannot use curl to download it. I was thinking to running dagger as a docker container. Is this possible? I could not find the right image to use.
There are 2 ways to run Dagger:
- Directly as a Docker container with the engine + CLI installed together
- As a CLI only, which will auto-download the container and connect to it
Either way, the engine will run in a container - and either way, that container needs to be privileged, so that it can run more containers
@bright plinth Little suggestion: I would include 1 in the How to install documentation: finding that the image to use is registry.dagger.io/engine is not immediate
Would you mind helping me translate dagger call container-echo --string-arg="hello, world!" to docker run .... ? Or, would you address me to the documentation page about it?
Last one I tried is docker run --privileged --entrypoint=dagger registry.dagger.io/engine call container-echo --string-arg="hello" but it does not seem to work.
what error do you get?
@pure tusk if you are trying to load a local module, the container will not be able to access it. For local use I recommend using the CLI directly. The docker image is for server-side use, eg. deploying dagger in your self-hosted CI cluster. Any reason you don't want to use the CLI directly?
Is there a way to inspect an actually running container in dagger? The usual container resource as a just-in-time resource does allow inspecting files, ENVs, ARGs etc., but I didnt find a way to check what processes would actually run in it.
While obviously container shouldn't be used as a VM I have to interact with some VM-like containers, where I need to check that all expected processes ( π ) are actually running.
service container do run, but as far as I understood the documentation you cannot execute arbitatrary commands like ps aux inside of them
Not sure if it's the best channel to ask but is there a way to append to RUN stanzas that match a certain signature or even the ability to specify exact matches on the lines as part of a DockerBuild(). Use case is consuming Dockerfiles I don't own but want to publish. Mostly I want to clean up after apt install, make install, pyc artifacts, etc so the layers are lighter and not carrying a bunch of intermediate work files.
Example in original:
RUN python3 -m venv /app/venv && \
. /app/venv/bin/activate && \
pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/nvidia-cudnn-cu12
Rewritten to something that is effectively does clean up in the layer:
RUN python3 -m venv /app/venv && \
. /app/venv/bin/activate && \
pip install --no-cache-dir -r requirements.txt --extra-index-url https://download.pytorch.org/whl/nvidia-cudnn-cu12 && \
rm -rf /root/.cache/pip && \
find / -type d -name '__pycache__' -exec rm -rf {} + && \
find / -type f -name '*.pyc' -delete
I don't think there's a way to do that other than download the dockerfile and modify it. Maybe you could translate those dockerfiles into dagger calls?
return (
dag.container().from_("original")
.with_exec(["rm", "-rf", "/root/.cache/pip"])
.with_exec ...
)
Yea it would be neat if you could specify DockerFile instead of DockerBuild and rewrite it and then call Build
Sure, but in this case if you're just running more things at the end, is there a difference?
@dim gyro wouldn't that still leave the earlier layer "fat"?
Python virtual envs are probably not the ideal example as you can copy forward the venv to another container. apt list/cache cleanup and object files from a make install might be a better example if it's spreading artifacts at various points in the container.
Does dagger support buildkit syntax 1.6+? Tried to run it against a dockerfile with a heredoc and it didn't work. Saw in the go source code it's a generic major version but that's the only reference
https://github.com/dagger/dagger/blob/main/core/integration/container_test.go#L287
https://www.docker.com/blog/introduction-to-heredocs-in-dockerfiles/
Introduction to heredocs in Dockerfiles ...
Any thoughts on supporting squashfs for ImageMediaTypes ? It's used heavily in ML training with enroot.
That seems highly desirable! Would you mind creating a github issue for it? π
Done let me know if you want anymore details.
https://github.com/diskfs/go-diskfs
would something like this be a useful starting point or do you have anything else youβd use as a starting point?
stupid question, i am almost done converting a pretty complex docker setup to dagger and it's very cool! how do I migrate the dockerfile VOLUME instruction to dagger though? https://docs.docker.com/reference/dockerfile/#volume
I opened an issue https://github.com/dagger/dagger/issues/9998
Dagger has WithMountedDirectory and WithMountedFile. Would those work for you? Keep in mind dagger doesn't yet have host filesystem livesync yet so you can't use it to reflect your host changes on the volumes you mount without re-running the dagger command.
no the VOLUME instruction is quite different to that. basically the volume instruction makes it so that when a container is run, it populates the volume with the contents of the docker container. it basically has nothing to do with the build itself. it also seems to be very rarely used although it is pretty handy
it populates the volume with the contents of the docker container.
Sounds like aCacheVolume? Dagger supports that too.
Nope cacheVolumes are also only relevant during build
Yeah if I remember correctly:
VOLUMEsimply adds metadata to the final OCI image?- Cache volumes are more like mount options in Dockerfile
RUN
yeah I assume VOLUME should be very easy support as there shouldn't be much logic needed in dagger.
Yup!
The only issue will be what to call it, to avoid confusing people
Maybe we'll tuck it under withOCIConfig or something
withVolume looks like you're actually attaching a volume to the live container
i am not opposed to that. VOLUME is for sure confusing
Not being familiar with VOLUME thoroughly threw me off
I love these conversations because I still remember the IRC conversations we had 10+ years ago when designing these keywords π
i have a problem. I am pretty much done with transitioning our stuff to dagger. I am using a remote engine with _EXPERIMENTAL_DAGGER_RUNNER_HOST, but running .export(/tmp/test.tar) on the finished container, the tar is nowhere to be found. it's a bit unclear where I should expect it in the first place: on the dev machine or the remote machine, but it's in neither place.
oh wait I just tried simply returning the container and then piping to the export function in dagger shell and that works
but the question remains why it doesn't work in the typescript sdk
(yes I am awaiting the promise)
Hey @clever verge , what you are seeing is the expected behavior. You can't export anything from code to your host machine unless you do the --export or -o from the dagger CLI. There is no implicit export. When you do .export from the code, it exports to a folder inside the module runtime (container) and will not be available on your host. It's a tradeoff made to maintain the sandbox.
@uncut mason , I've seen this question come up multiple times recently. I think the documentation here can be a bit clearer on where artifacts are exported to https://docs.dagger.io/api/chaining/#export-directories-files-and-containers
OK, I'll make that clearer, opening a ticket for it
this is actually documented already but in a different section: https://docs.dagger.io/cookbook/#export-a-directory-or-file-to-the-host
mhm makes sense. I was hoping there would be some way to get the tarball directly on the remote runner. my usecase is that I am planning on setting up dev VMs on our infra and have our devs deploy our software directly via _EXPERIMENTAL_DAGGER_RUNNER_HOST . the workaround I guess is to instead use SSH. Sadly I can't use asService since our software is very opinionated in how it is run.
mhm we also have a CI step where we run some smoketest on our built containers. it would be nice to do this directly with dagger, but there doesn't seem to be a good way to run containers and to then interact with that container. i know that dagger is for building containers and not for running them, still it would be nice
What kind of smoke tests are you running in those containers? Exposing a server or do you mean inspecting files in a given container. Depending upon on your use case I might be able to point you in the right direction
You could add/make a new function (e.g. smoketest/qa) that takes that built image address, dagger.Container, or dagger.Service and interact with a given set of instructions (e.g. ping this endpoint, this file should exist at this path). Or depending on your needs, might be worth adding a QA style agent with the new LLM integration to let it run checks based on a prompt? https://docs.dagger.io/features/llm
Yeah all kinds of stuff. Those endpoints should return this at this stage and those files should be there with this content. Dagger service seems to be the only way, but I guess you could only check the endpoints that way.
You could break that into two functions that are chained? On takes a service and one takes a container as an argument?
Ah wait I am stupid, you can just query files from the container without running it right?
Absolutely, once you have a container object you can get files and directories from it. Then you can make a new service using the container and pass it to another QA style container to check the endpoints
Yeah makes a lot of sense
Thanks for the pointers!
I am still too much in the docker mindset
Hard to get out of that mindset, I literally had an aha moment yesterday because I was above to do something in Dagger that was always a pain in Docker π
ah one more question, in the artifacts of our smoketest we saved the docker logs of the container. is there any way to access the logs of the service container?
Unfortunately thats not possible at the moment, these GitHub issues have more details if you would like to track: https://github.com/dagger/dagger/issues/7377 https://github.com/dagger/dagger/issues/6553
alright! glad it's already being considered!
is it possible to not start a service (withServiceBinding) when the layer that needs the service is cached? wastes quite a few seconds on every run (as it waits for the service to be healthy)
added this https://github.com/dagger/dagger/pull/10026
Hi all,
I'm working on a Dagger module that scans a local container image using sysdig-cli-scanner. How can I pass a local Docker image without Dagger trying to pull it from a registry?
My current workaround is for the function to take a .tar file instead that it can then scan.
This looks good! Thank you!
Similar question was asked here - #general message. Can the sysdig-cli-scanner use a tarball?
@charred tide Just saw the message after posting mine here. The sysdig-cli-scanner can also use a tarball. However, when I tried updating the method to take a *dagger.Container and then always mount the tarball using Container.AsTarBall, and then running my scan on that, it seemed that Dagger would still always pull the image from a registry instead of using my local image.
If everything we did used Dagger, I think this would work. But since we are still new to using Dagger, it needs to be used with our existing workflows that build a Docker image locally and then run the scan on that.
Currently, I was planning on using docker save before calling the Dagger module so that I can just pass the .tar file instead of a container. But I was hoping it was possible to pass a local Docker image as a *dagger.Container.
Oh, so you want to scan an image you have on your host currently, using dagger. I think what you proposed with docker save is the only way to do it. Otherwise Dagger would have to pull the image. I think you could pass the docker socket to dagger, mount it inside another container with docker CLI installed and use that, but I personally haven't gone down that path.
Alright, thank you for the help. I think I will continue just using the Docker save solution then, and long term look at migrating my other workflows to also use Dagger as a way to avoid this issue.
Is there an easy way to create a dagger container from a locally built docker image? I've done some research but have what seems like conflicting information and various approaches I've tried have not worked. Can anyone point me in the right direction? Basically I would love to do container | from my-pre-built-image but if I need to do something extra that is fine, but ideally the simplest approach to do some adhoc testing with dagger on that image. NOTE: I'd prefer not to use a registry or build the docker file with dagger since I have a pre-existing docker bake setup I'd like to re-use for now.
I don't know if there's a better way currently, and that might sound a bit like a hack, but at least you can do it that way:
- export the image as an OCI artifact:
$ docker save -o my-image.tar my-image
- import it to a dagger container
$ dagger -c 'container | import $(host | file my-image.tar)'
An import-image like the export-image recently added would be really nice for sure
Thanks, I'll try this out. If it works it seems simple enough for my purposes atm. Are there any requirements for the host access part? For reference, I'm running colima on a mac which doesn't use the default docker context by default, but I do believe it supports host.docker.internal.
What you need is an OCI archive of your image. So using docker or colima or any other will be fine as soon as you can produce the archive.
On dagger side it doesn't matter, container | import just wants a file, so docker or any other will be fine.
this will be a lot more possible once we've merged https://github.com/dagger/dagger/pull/10810!
I have a question posted here https://discord.com/channels/707636530424053791/1407378108373536819 about accessing OIDC credentials (eg Github Action + GCP Workflow Identity Federation) inside dagger, is that easy?
Hey good people of Dagger! After today's talk by @bright plinth I figured I need to see if anybody in the Dagger community has been playing with integrating inference servers into the Dagger pipelines. Lo and behold https://dagger.io/blog/docker-model-runner this was a good starting point. However, Docker model runner is but a tiny-tiny local inference server (which I'm sure will grow over time) but the real game in town are things like Triton Inference Server, Seldon Core and to a certain extent BentoML (which maybe the closest conceptually the vibes of Dagger). Has anyone integrated any of those into the non-trivial pipelines?
Better yet -- am I even in the right channel askin this question here π
@mossy monolith note that the blog post is not about running docker model runner inside Dagger, but connecting to it as a client, to power agentic functions in Dagger
@mossy monolith for running the inference server, my guess is that GPU access is the only real issue. Otherwise it's "just" a matter of running the server in a container.
For GPU access, here's a good reference -> https://dagger.io/blog/gpu-challenges
Oh I get that -- but what I saying that even that level of intergation would be interesting for me to hear about (e.g. googling bentoml or Triton and dagger returns no results whatsoever)
Would it be fair to say that Dagger replaces Docker Compose use case for dev environments?
I could just start services and keep them running.
almost π We're missing a few building blocks for true feature parity, but yes that's definitely the direction we're going in. We want Dagger to be a great choice for both CI and local dev environments
The biggest gap is live sync of volumes while the service is running
but @dusk ridge is working on it π
Ahh thatβs of course would be a deal breaker π
But for now, it works great for running local instances of your service dependencies
Ya makes sense. Like a database and redis.
The gateway drug usually is standing up ephemeral services for e2e test environments
yes or even the other microservices in your stack - like the backend service if you're developing on the frontend, etc
My dream was always a single setup for local dev and CI. Complete unification.
Otherwise you have compose on local, weird Action services in Ci, deploying to ECS. Itβs a cacophony of solutions.
e2e test environments usually build up a lot of cruft and hacky scripts. Daggerizing them works great because they're repeatable of course, but also you can parametrize all the stuff that tends to change between dev and CI, making your scripts not portable across them.
For example you can parametrize a DB dependency, simply by passing an argument called db to your function, of type Service. Then depending on the context, you can pass an ephemeral container, or a tunnel to a dev DB running on your local machine, or even to staging or prod.
One dag as you guys say is my vision too for a looong long time.
Ha ha you see it too π Welcome to dag nerd central
You can also parametrize secrets... etc
You can stack up those building blocks as high as you want, and the whole system holds. For example we build and test dagger end-to-end in dagger.
I wish I could hard code secret refs actually. Was surprised I had to supply 1P refs via CLI params. Seems like a difficult thing to do if you have 20 of them. Wouldnβt it be better to put refs in code?
You can get a full end-to-end build of dagger (CLI + engine) and try it out interactively right now from your computer, for any branch or tag, with one command.
Say, a PR I'm working on to add .env support:
dagger call -m github.com/dagger/dagger@pull/11034/head dev terminal
Funnily enough, that's exactly what the PR I just gave you as example solves π
You just write the arguments you want to pass to dagger call, encoded to a var in .env, and dagger will automatically merge it into the schema as a default value.
Nooo
This is where I diverge from dag vision π€£
I HATE dot envs with a passion of 1000 suns.
eg.
$ cat .env
github_token=op://foo/bar/baz
aws_secret_key=vault://hello/there
base_container=myregistry/goldbase:v42
It's just a convenience to meet people where they are
Note that you don't have to actually write secret values in the .env π This is where our use difders from the current state of the art
You just use it to persist default arguments. You can keep your secrets in 1password, hashicorp vault etc
@main moth what do you use as an alternative to .env? Some fancy environment variable sync service? We could add direct integration to that
I just want to supply well know secret refs to the functions. These donβt change. Every dev has access to them via 1P. So putting them into dot env seems weird. As you technically not even supposed to commit that.
btw this is where we're discussing the particular topic of persisting user defaults (via .env or otherwise): #1413254056188579901
Ah I see. You'd like to commit them into the function's code.
Well this is where there is tension between portability and sandboxing on the one hand; and convenience on the other.
Convenience is always tempting, but it's what got the current devops stack in the mess it's in.
Even if you only used it sparingly and preserved the portability and safety of your functions. Not everyone will, and an ecosystem is only as good as its weakest link.
But isnβt it just code? I could branch based on some param and use a different set of secrets.
So by forcing dagger functions to remain sandboxed, we improve the quality of the ecosystem for everybody.
In other words: if we allow anyone to hardcode eg. 1password references in their code, what will actually happen is that lazy devs everywhere will hardcode everything all over the place, and the promise of Dagger functions being truly portable and parametrizable will vanish.
Still not seeing how dotenv solves portability. Itβs just code too. Just a weird format of code that pretends to be environment variable.
Ah I think you're thinking of .envrc or direnv?
Our implementation is just a dumb key=value, with variable interpolation and quotes
Iβm thinking of a typical dot end .env
definitely not code
Itβs code in a sense that itβs a file in your repo. Itβs not text either. Itβs not a document.
It has variables in it. Itβs code.
Itβs convenient to pretend itβs not code though. But it is.
I see. The useful part for us, is that there's already a convention that its lifecycle is not the same as your code's lifecycle. You typically don't check it into git. And if you do, you're advised to do it carefully and remember the difference. So we just piggyback on that.
Itβs also a poor syntax with gotchas and quickly adds variable expansion. And itβs definitely code then.
So once I check in .env itβs effectively the same as checking in hard coded ref into TypeScript code. So might as well allow for that. Otherwise Iβm forced to use this weird obscure abstraction that also enables action at a distance and has poor syntax.
I agree it's not the cleanest separation of code and configuration. There are other solutions, usually they involve an external service. For example 1password has an "environments" feature now. Doppler is a service that offers this also.
If you have a favorite alternative, I can make a note to prototype support for it π
It's not the same for Dagger, because when you load a remote module, dagger ignores the .env for safety
I want to hard code refs into actual code that is TypeScript not .env
Got it. Well Dagger doesn't do that, sorry
It should
There is an escape hatch, that we want to improve - seems like what you'll want β¬
Secret loading is a massive pain
You can always run the 1password client yourself in a container, orchestrated by a dagger function
Iβm liking the hatch concept just not .env weird baggage
The problem is that it's tricky to safely get the plaintext value from that command execution, without leaking it into the dagger cache or logs
But it will get solved eventually
I sense that you plan to add secret loading as EE in the future. π fair of course.
Then you'll still need to get the 1password service account token into the function π
Ah no, the development experience should be the same for everyone. This will be a matter of API, so no price tag
Have you seen DMNO?
It kinda reminds me of dagger for secret loading.
I think something like that could be part of dagger itself.
I didn't know about it but it looks interesting.
I think our approach will be to integrate with whatever your favorite environment configuration system is, outside the dagger sandbox. I guess that could be DMNO, too
Thatβd be quite meta. I was just envisioning a concept of a βsecret providerβ that can load secrets from somewhere
Right, you can do that today, Dagger gives you the API to fill a secret dynamically yourself (the "escape hatch"). There's just that issue of leaking the plaintext into the cache
1P or vault. But this is from code with refs. Not from dotenv. Like a proper codified secret scheme with defaults and fallback values.
Ya that leaking part is very much undesirable π
Maybe that's a weird question, but does dockerBuild cache intermediate instructions results the same way as if they would have been executed via the Dagger API? This was my assumption.
I am facing this issue (have been facing from the very beginning with Dagger): I am keeping most of my base build steps in Dockerfile and hand it to Dagger to perform some fine-grained dynamic steps after the main bulk has been finished.
And apparently it hasn't been cached for this entire time (like 8 moths lol).
I am experiencing full rebuilds of the dockerBuild step quite frequently (even when doing innocent changes to other projects in my monorepo). I think it is cached across dagger call invocations within the same GitHub Actions run, but not across runs (commits).
@bright plinth could you helm me out here, please? I wasn't able to find any docs on this.
related issue? https://github.com/dagger/dagger/issues/6170
I want to test with Selenium using Dagger. Is there a way to specify memory size like Docker's --shm-size, or pass an option to the backend Docker?
I noticed that my question is being discussed in the thread below. Please disregard this question.
No
?
Hi, does dagger use docker in docker?
No. Dagger needs a container runtime. It can be docker, it can be something else (like apple containers) or natively on linux. And then all the containers Dagger is creating are not docker containers. No docker in docker.
I confused now i get answer from @bright plinth "No, Dagger does not have a runtime dependency on docker. It bundles its own container runtime and calls the underlying linux kernel directly to orchestrate containers."
Question is now is Dagger needs container runtime or not π how it's working actually can I found it somewhere on docs please. Or i appriacite explanation here if you have time
Well, yes, that's me, I wasn't clear enough. If you're not on linux, it will use a container runtime to spin up its engine. It can be docker or anything else. For instance on my machine I'm running docker so I have a dagger engine container running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9191d944cd24 registry.dagger.io/engine:v0.19.11 "dagger-entrypoint.sβ¦" 24 hours ago Up 24 hours dagger-engine-v0.19.11
But once it's started, all the rest is going through dagger's container runtime and creating containers directly by talking to the linux kernel. There's no docker in docker (or similar).
The only thing is you need this linux kernel, and on mac for instance it doesn't exist. So we are using the one provided, as a vm, by the container solution, for instance the vm provided by Docker Desktop in which docker will create containers.
Here is a quick schema that should be close enough to how it works
Perfect thanks for explanation now it's much clearer, so in VM in Github Actions runner its actually don't needs to have docker it will just work if runner is default ubuntu-latest Github runner?
I tried it in GHA just not sure as we have docker installed in our runner and dagger was working out of the box.
In CI runners, the three most common ways the dagger engine is started:
-
By default, auto-started using docker, podman, or other equivalent tools. If the CI runner itself is running inside docker, then this would qualify as "docker-in-docker". As we discussed earlier, once started the engine doesn't rely on docker at all - it's just that in some cases it might be running inside a (privileged) docker container.
-
Optionally, you can deploy a the dagger engine yourself, for example to a dedicated machine or kubernetes cluster, and configure the CI runners to connect to it. This is often done in production deployments of Dagger, for better control and performance, and also sometimes to avoid docker-in-docker.
-
Optionally, you can use Dagger Cloud to deploy dagger engines for you on demand, auto-scaled and with persistent cache. DM me if that's an interesting option π
--> I know the answer to "docker-in-docker" can seem confusing. What complicates the answer, is that the engine doesn't call docker, but it can sometimes run inside docker.
Before I start a lengthy help thread, finding ONBUILD is ignored by Dagger's Directory.DockerBuild? Build an image with Docker it works, build it with Dagger it doesn't. Compare the two, the Docker-built image has the correct COPY/ENTRYPOINT/CMD instructions (all from ONBUILD) and the Dagger image doesn't. It's a very easy test - the Dagger-built image doesn't have the ONBUILD COPY content, the Docker-built image does.
Found https://github.com/dagger/dagger/issues/7530 which describes exactly our usecase. Building a base image that has ONBUILD instructions, used by other images. Is this not supported?