About this video
What You'll Learn
- Use the Python SDK to define Dagger pipelines for an open source project.
- Pass files and artifacts between containers to compose multi-step build workflows.
- Run Docker daemon as a Dagger service to support nested container tooling.
Kat Cosgrove joins to Daggerize the Cargo project. We start with the Python SDK, explore container composition and caching, debug async issues, and end with a working Docker-in-Dagger setup running the Docker daemon as a service.
Jump to a chapter
- 2:09 Introduction to Daggerizing and Cargo
- 2:33 Introducing the Guest: Kat
- 4:04 Kat's Background in DevOps and Platform Engineering
- 5:41 The Trend of "As Code"
- 6:48 Overview of the Cargo Project
- 8:11 Initial Challenges and Hopes for Dagger
- 8:48 Understanding Cargo's Existing Tasks & Workflows
- 9:26 Discussion on Authentication and Cloud Services
- 11:06 Planning the Daggerization Strategy
- 11:22 Setting Up the Local Development Environment
- 15:24 Reviewing the Existing Makefile
- 16:03 Benefits of Dagger over Traditional Task Runners
- 17:51 Identifying Key Tasks for Dagger (Auth, Pulumi, Kind)
- 21:06 Initializing Dagger with Python SDK
- 25:21 Running the First Dagger Function (Container Echo)
- 27:55 Dagger Fundamentals: Containers, Execution, I/O
- 34:30 Improving the Python Editor Experience
- 40:28 Using the Conductor Container (Project Environment)
- 43:56 Exploring Dagger Composition and Artifact Passing
- 45:28 Demonstrating Composition: Passing Files Between Containers
- 51:00 Introspecting and Using Container Artifacts
- 1:00:40 Debugging with Dagger Terminal Feature
- 1:03:30 Attempting to Create a Kind Cluster with Dagger
- 1:04:05 Reviewing Kind Setup and Challenges
- 1:06:34 Attempting Docker-in-Dagger (Running Docker CLI inside a Dagger Container)
- 1:09:59 Running Docker Daemon as a Dagger Service
- 1:11:35 Implementing the Docker Service and Client
- 1:14:49 Debugging Python Async/Await Issues
- 1:20:48 Correcting Service Connection in Dagger Client
- 1:25:05 Fixing Docker Daemon Service Arguments
- 1:26:15 Debugging the Docker Client Container with Terminal
- 1:28:09 Successful Docker-in-Dagger Demonstration
- 1:28:55 Recap and Future Plans for Cargo Dagger Integration
- 1:30:33 Conclusion and Farewell
Full transcript
Generated from the English captions. Timestamps jump the player to that moment.
Read the full transcript
2:09 Introduction to Daggerizing and Cargo
2:09 Hello, and welcome back to the Rawkode Academy. I'm your host, David Flanagan, also known across the Internet as Rawkode. Today, we are gonna take a look at Daggerizing. And by Daggerizing, obviously, it's an old word. We're gonna use Dagger to build or augment or enrich pipelines and existing open source projects to see if we can make their lives a little bit easier. And today, we're taking a look at a project called Cargo, and I have the pleasure to be joined by a friend and a maintainer, Kat. Hey. How are you? You're on mute. See, you had that music playing, and I
2:33 Introducing the Guest: Kat
2:48 was, like, jamming you. And I was like, I gotta mute mute this, and now I look like a fool. No. I'm super excited to be on with you. I know we've kind of been running in parallel craft paths across the interwebs, and we finally actually get to do something. So that's cool. Yeah. We we both seem to like a lot of the same technological stuff. So now we get to sit down and actually experiment and have some fun together, which is awesome. And don't think we we streamed once before, right, when I was at Equinix, I think.
3:25 I it maybe. I have to go look. I My feelings aren't hurt. That's okay. It's not a tear. I was so sorry. I swear I will remember this one. Like, you you had music for, like, custom lyrics with card how'd you do that? That's so cool. I have been experimenting with AI music, and I'm gonna do some videos on it because it's so freaking cool right now. And it's so inexpensive to do and so quick. I can't believe it. But, yeah, that was a nice that was the first time we've ever used AI and AI opening music, and it was customized
3:57 for Dagger, Cargo, and Jew, which was awesome. I thought so. Thank you. Okay. Alright. Look. For anyone who is not familiar with you, can you give us a little bit of a TLDR on who you are and what you've been up to? Good god. Okay. So TLDR version. I am a nerd on the interwebs and nerding out with everyone on platform engineering and DevOps, GitOps, all those fun ops y things. Kind of climbed through the ranks a little bit at a time professionally, just going from being a Linux nerd to actually getting to apply that knowledge in support
4:04 Kat's Background in DevOps and Platform Engineering
4:35 roles. And then kind of growing up from there into OpenStack and Kubernetes from, you know, along the career path from canonical, well, Dell Canonical, and Red Hat there. And then since leaving those larger companies, kind of carrying those skill sets around to a couple of few different startups, including some professional work, in the space, which we're going to be playing in a little bit today. So and then, like, now we're full on in, like, the the coding world with Dagger and, you know, other code powered IAC tools and things like that. So kind of getting further into,
5:18 like, software dev like ops work, which I feel like is a really cool progression, and we're probably gonna see that more and more as AI lowers the barrier to entry there. And so, hopefully, today helps, you know, other supercharge other people along their their trajectory as well. Awesome. Yeah. You're right. We are totally in the of as code. You know? I write my infrastructure in Terraform CDK, deploy it with Open Tofu, which I'm not sure if I'm even legally allowed to do, but, you know, screw it. And we've no good Dagger for pipelines. Like, these days, you never have to leave your
5:41 The Trend of "As Code"
5:59 code editor or your your language servers. Like, everything is just right there. I have gotten so attached to Versus Code, and it still feels wild to me that, like, Versus Code and GitHub are Microsoft things, and I'm in love with it somehow. Yeah. It's a different world now than when I entered the tech scene for sure. Yeah. If you had to ask 20 year old me if I'd be using Microsoft developer tools, I'd be like, fuck no. And here we are. I'm using Copilot. It's got everything. Unbelievable. But I that's a testament to Microsoft. Right?
6:33 They're they've changed their whole mentality. They're doing good things, and they're helping developers. Like, I have good nothing but good things to say about Microsoft in twenty twenty plus. So Exactly. Alright. Anyway, we're not here to talk about Microsoft or AI or cool music. We're here to do some Dagger stuff, and we're gonna be doing some Dagger pipelines for cargo. So can you tell us a little bit about what cargo is? Sure. Okay. So cargo, not to be confused with the Argo CD land stuff, was named several years ago before those products came out. And,
6:48 Overview of the Cargo Project
7:09 it's, named after the concept of an aircraft carrier, if you will. I think in in French, cargo actually is a word, that they use for that sometimes. And the concept is we're building a platform that is from from the ground up, a pass that's built on Kubernetes, can run containers, virtual machines, the works. We're looking at Wasm in the future as well because that's definitely a really hot item that is proving to be really valuable. I'm I'm I'm looking for that whole road map. And right now, the whole deployment of the project is either, you know, manual CLI
7:54 or really rudimentary GitHub actions with a lot of, like, bash run and stuff like that in there. So kind of excited to see what the Dagger spin on all of this looks like. Yeah. I am a little bit worried about this one just because there's so much container stuff going on, but we're gonna give it our best shot and see what we can do with this. Just because yeah. It's an interesting project to play with, but there's been some really good improvements with Dagger recently. And Markoff, one of the Dagger team members, has been showing off how to run the KTS and
8:11 Initial Challenges and Hopes for Dagger
8:35 save up a Dagger pipeline and stuff like that. So, like, if we need to hook into any of that stuff, we're certainly gonna go and grab those examples and steal them. But before we go to the code and share my screen and all that, you mentioned that you've got some GitHub actions. Right? I just wanna understand when we talk about Daggerizing a project, what we're saying is taking things that would typically live in a Docker Compose dot YAML, a Just file, make file, CI pipelines, whatever they're using, any task associated with that project or CI or CD or even local
8:48 Understanding Cargo's Existing Tasks & Workflows
9:09 development environments, we wanna be able to do that as code. That's kind of what we wanted to do today is cover a few of those use cases, hopefully. So beyond the GitHub actions and don't spend too much time going into it because we will look at the code in a minute. But what else do we have? What kind of tasks are you running with your day to day working on Cargo? Sure. I don't have CI tasks tests yet on on this code base. I have some in some related code bases that I intended to pull in.
9:26 Discussion on Authentication and Cloud Services
9:38 But, I mean, you're looking for being able to authenticate against your cluster. In my case, that's actually a pretty weird topology because I'm using tallow stuff with Omni, and it's all OIDC powered. So I don't even use my local network when I'm in my IDE. I'm all working in code spaces in the cloud, you know, a VM somewhere in Azure. We need all of that to work out really well here. I'm not entirely sure how we're going to set up the authentication within Dagger. I know that it's a few fairly simple commands on the CLI, so worst case
10:19 scenario, we can shell out. But I definitely have a number of questions there myself that we're just kinda kinda gonna unwrap and uncover. Wow. Talk about striking fear to me. I mean, normally on Rawkode Live, I just sit here like this and go, yeah, show me a cool check. And now today, I need to type stuff. And you're mentioning OIDC and Talos and Omni and I'm like, oh, fuck. You know what? I for the record, I did not twist your arm into this. So I this was voluntary, and I I I'm not being crazy or sadistic or anything here. Right? No.
10:58 I I I think we're gonna have some fun, and we're gonna install some cool challenges and have a look at Dagger and see how we can use it. You know, we've what we have is a a Python project, and we can start to lay it in our code or Dagger pipelines as Python, as Go, as TypeScript, wherever we want, and we can just see how far we can push this thing. So Yep. I think it's about time we start taking a look at some code, don't you? Yes. Let's dive in. Ta ta da. Alright. So I have already
11:22 Setting Up the Local Development Environment
11:26 cloned the project. I have made a couple of changes just because of my very weird setup. I do run XOS, so I've had to modify your ENVRC and add a dev env environment just to get Python to exist in this thing. Yep. So I'm only going to run a dev env share. I use dev containers for all of this, which supplies a a lot of the same tooling. So if we're if we're hunting around for environment and integration, there's a big difference between how you're approaching it and my go to. But that should actually be a neat way to really actually understand
12:05 what's in the black box instead of just blindly running from a prepackaged starting line. Yeah. I'm I'm trying not to go straight into containers because Dagger itself uses BuildKit. So I'm not sure. Yeah. So for for the container, the dev container that I run, like I routinely run Docker commands with it. I use kind Kubernetes for a lot of the in development testing, things like that. So it's it's it's fully compatible and supports that Docker CLI from within the container itself. I ran a couple Dagger commands and just kinda like the hello world stuff, which
12:47 is obviously not highly complex. And things went well so far. Conductor is that dev container. It also is what I use to maintain Conductor. So it's literally maintaining Conductor in Conductor. So I think we should be have the freedom to do all of that if we need to go there. But I'm also really curious how you set up all the the I used her end and you added some extra stuff. So I'm gonna enjoy how that's all tied together. Yeah. I only added one line, which is just this path ad Oh, okay. Which you see me tweet about
13:23 earlier because I it was infuriating that this is a different mackerel. So are both are both of those actual functions or is it just camel case syntax? Yeah. Path add lowercase is when you want to specify a variable name. So maybe you've got like an old path and then you can add stuff to it. Wow. That's That is not intuitive at all. No. I lost an hour on that. I don't know if I would have figured it out that fast. Bravo. Yeah. So that's all I did. And that's just because I have Dagger locally again, and
14:03 Dagger's not available in the next package repository, and this is next to us. So it's very hard for me to escape next, but the dev container is there. So if we need to open it, we will. But let's just try and get things started and take it from there. So You're warming up. I'm gonna read through we got a bunch of hellos here. So we've got Ravi from San Diego. We've got Marcos from Uruguay, Pat, Felipe, Jeremy, Sam, Russell. Hello, all of you. Yeah. Oh, there's Marcos who I was talking about as well. So, hey, thank you for
14:38 joining. That means we've got help when we need it. We can proceed with confidence. And some Dagger team as well. Awesome. Hello, everybody. My voice level is low. Yeah. I'll turn that up a bit. Hopefully, that helps. Yeah. Russell says your bamboo print screens are awesome. Yeah. They are awesome. I was enjoying that. Was a lot of fun. It was a desperate attempt to hide a bunch of stuff when I was rearranging things in the house one day, and then I was like, I'm just keeping this. This is great. Alright. There is all the hellos. Thank you
15:16 all for joining us, and definitely glad to see some Dagger folks in case the help is needed. So let's see. Now, you do have a make file. I I do. It is It's gnarly. It is not well maintained right now because the project during the refactor has changed a lot. So I was gonna wait for the refactor to kinda tidy up and then double check to make file, and I'm kinda tempted to go into task files anyway. But tell me, like, with the Dagger stuff, like, does Dagger end up replacing a lot of the logic that I have to
15:24 Reviewing the Existing Makefile
15:57 painfully write in this makefile syntax? Or what is the op what are our options there? Yeah. I mean, I found with my own repositories and adopting Dagger, I I don't even need just files, make files. I'm not writing Bash scripts anymore. I'm pretty much just writing a Dagger task for everything because the nice thing about it is is cached exceptionally well at BuildKit via inputs and outputs, you know, like, caching in any system. Then they're composable. So, like, you know, dependencies across tasks are very easy to tie together because it's just a function call at the
16:03 Benefits of Dagger over Traditional Task Runners
16:31 end of the day. So applying that methodology to my pipelines is really hard to go backwards. And I started with repository to have a just file, but that's just because I've not got the time to sit down and write more Dagger right now. But I the more I write, the the happier I get for sure. Well, I mean, you mentioned Makefiles and the Bash scripts. And one of the reasons that those two go together so strongly is Makefiles have very limited ability to maintain just inputs and outputs from different tasks in a make file. So that becomes like really really
17:04 difficult if you have to pass an output into something so that you're dynamically assembling the whole project. So, yeah, I'm I I have I have high hopes here that this will merge into the product project and and and be a a long lived bit of code. Yeah. Plus, you also get to say goodbye to phony. Like Oh my gosh. I've had twenty odd years of phony. I'm done with phony, so I don't want phony anymore. I I've had half that, and I'm still ready to be done with it. Alright. So you could that's wonderful help target.
17:40 And I think this would be the the kind of starting point as we try to work out what to start with first, what to replace. Yeah. I think as far as the steps here, the first thing we need to do is figure out our authentication. What we're doing in Cargo is using a number of different cloud services. At this point, it's starting to really add up because I am using Pulumi IAC for the project at at the moment. I have secrets all stored up in Pulumi. I'm using my Omni account over on the Sidero side
17:51 Identifying Key Tasks for Dagger (Auth, Pulumi, Kind)
18:17 of the house, and that's necessary for actually authenticating to the Kubernetes API the way that I use Talos. And then now, if we're using Dagger, that is another cloud account that we have to authenticate against. So I've added the token for Dagger to my GitHub Actions environment and my Codespaces environment. So that authentication should be an environment variable, but I don't even know how we go about just getting started to be able to run those basic authentication pieces if we wanna start there. Yeah. Well, the Dagger token is 100% optional. It's a value add with Dagger cloud. So
19:04 everything that we do, we're gonna start off locally. Okay. And then we'll start to work out how we can bring in, you know, like, spinning up a kind cluster for instance. Maybe we can get that done. For sure. Do you have any other tasks that aren't using for me in Telus? Yeah. So as far as the KIND testing goes, we do have support in the IAC for switching between KIND and Talos. Both are a little bit different in some of the components that they actually roll out, how those variables map. So we can set our
19:40 IAC config to include that we are deploying the kind, and then we just need to get the kind cluster started. I do have in the hack directory. I have a kind config. So if we want, we can get that started. The kind task in make file also creates a couple of volumes that the config mounts into the kind cluster just for making it easier to build and destroy kind clusters without redownloading tons of images every single cycle. Mhmm. So if we want to start there, that is all local. Okay. Right. So I'm I'm just trying to understand
20:32 the the flow here. Yeah. So you've got two different avenues when you run your tests. One is against cloud infrastructure, which Pulumi provisions, and the other is against kind infrastructure, which Pulumi provisions. Is that correct? Kind infrastructure that the make file provisions. Well, we provision kind, but does Pulumi still deploy resources to that? Yes. Pulumi still deploys to that based on the koop config. Okay. Cool. Both paths work off of the kube config locally. So Yeah. So something we're gonna want to do then is to obviously get our Dagger instantiated. Right? We need the boilerplate so we
21:06 Initializing Dagger with Python SDK
21:14 can start putting things together. We can then look at writing some Pulumi tasks that can execute Pulumi commands. We'll start with something really simple, which is just Pulumi test dash version. Then we'll try and bring in the cane component and see if we can get Pulumi to actually run against that. Now you mentioned secrets, which does have which has me also a little bit worried. Do we need secrets when working with the cane setup? You know what? I don't we do need to open the stack. Well, I mean, need to select the stack that we're using. And Azure's in Pulumi
21:53 Cloud, is it? My state is currently stored in Pulumi Cloud. So Pulumi login and then Pulumi stack select and kind create cluster. Those are the three commands that we need to do before we actually start deploying. So can I let me just where's the Pulumi code? Is that under no. Not stores. Pulumi directory. I don't have a Pulumi directory. What branch are we on? You are on the reef the the ah, actually, I don't have the right branch open in my Versus cup. Hang on. Git checkout. Rawkode Dagger. IO CICD. Sweet. And the IAC is in the Pulumi
22:54 directory. Yeah. With the main dot py in there. So if you look I need to zoom in on the screen a little bit, but I can see. I've only got the main branch. Yeah. Yeah. Yeah. Okay. So, there's a branch specifically for you in here. I don't know if you want to how you wanna carry over the environment stuff that you've done so far. It it'll be okay. Okay. Let's be If you do git branch dash a, you can copy paste the name of your branch over. This one. Okay. Yep. There it is. Okay. So stash
23:46 switch. Nice stash too. Yeah. Main on this project is currently hugely behind the refactor. That was just instantiating all the pieces in the most rudimentary way so that I could see what I needed to turn in for common patterns and simplify. And now I'm I I've been refactoring the whole code base to actually apply some consistent design and stuff like that. More reusable code, modular, all that. Alright. So I think the problem is where did we get that? Yeah. And nothing is staged. Why is this a new fail? Doesn't matter. Okay. Let's go back to the switch
24:42 command. Stash. Good. Switch. Find my path add and pop back over. Pulumi directory right there. Uh-huh. Cool. Yay. Okay. Alright. So this is Pulumi config stack. Mhmm. Alright. Yeah. And a lot of the logic in this IAC is targeted to be replaced with a Golang operator. So way more way more code to come in the future. Alright. So let's actually try and run a Dagger command. What are we? Twenty five minutes in and we haven't run a Dagger command. We can do a hello world if you want. Or Well, when we set up Dagger, we have
25:21 Running the First Dagger Function (Container Echo)
25:34 to provide which SDK we want and where we want it to live. So we can keep it in a Dagger directory. Now SDK wise, you wanting Golang, TypeScript, Python? Yeah. Let's go with let's go with Python. That is the language you're using for this generation of the project. Yeah. Let's keep it consistent. You've never seen me write Python. That's the challenge. We'll give that a moment. So let's just create an all the the boilerplate that we need. So a little dagger in it here. We have the SDK. We have I'm guessing we're getting a new directory out
26:16 of this. Yeah. It's gonna create a dagger directory with our first kind of Dagger function, Dagger task, which, you know, we can start to make modifications to it. We can drop in some Pulumi containers. We can run Pulumi commands, and then we'll just tackle the problems one at a time as we go. Sure. But we now have an initialized module. So what does that mean? Well, the first thing we get is just a Dagger dot JSON, which just tells us where the Dagger code lives, which is in the Dagger directory and the SDK that we're using.
26:50 We pop this open. We have our init dot py where we have a container echo function and a grep dir function. So that is the first two functions that we can run with the the Dagger CLI. Okay. So that with exec there on line 31 is, for example, just basically shelling out running a bash command. Right? Yeah. And a and a container. That's true. That is in a container. So everything that Dagger does starts with a from statement, just like a Docker file. Yeah. We can run from Alpine. We can run from Ubuntu. We can run from Nexus. We
27:36 can run from Python, whatever you want. We then add mounted directories. We add caches. We add working directories. We can execute one or more commands. And all we're doing is just building up all the steps that we've been typically put in a bash or a makefile. We're doing them in a containerized environment where we have very strong inputs and outputs. Right? We know what goes into the container. And Yeah. It's in content addressable and we know what comes out and we can reference things from containers, move them around, and do the juggly dance and all that without ever doing anything on
27:55 Dagger Fundamentals: Containers, Execution, I/O
28:08 the phone. That juggly dance. K. What is Marcus saying? If you're using Python, you'd want to do Python v n. I already have a VMs. I set it up with dev env. So Yeah. We've have a local Python virtual environment with UV, which is also installed also requirements.text that are part of the project. So I don't think we'll need to specifically get its own VM for for Dagger. Although, you are saying to run that in my Dagger directory. So I am curious. I'm guessing we're gonna be able to set environment variables in these containers. And I wonder
28:54 since we can do mounted directories and all of that, it should be reasonable to assemble everything so that credentials, coop configs, all of that manages to cross the boundary into the Dagger containers. But it might be just a tad tedious. I'm trying to think through how that's all gonna go. So there are ways to get secrets in to our Dagger containers in a secure fashion. Let let's just start making some progress. Right? Let's let's see if we can run our first Dagger function. Alright. So we got a Dagger CLI. From here, we can call functions. We can
29:38 list functions, you know, everything that we need. If we do functions, it does container stuff, and then it should give us a list of functions. Marco says my editor seems happy. It's a little bit happy. It's obviously it's not picking up the DAG, so you're we may need to do a virtual environment just for this, but let's wait and see for now. So this this is what's kinda cool about Dagger is that everything in our function here, like, Dagger can run functions in any language. So you can have functions in Python, we could have some in Go, we could have
30:13 some in TypeScript, It puts all into the container, builds it, and then gives us access to it. So now we could do Dagger call. We could say container echo. And it wants a string argument, so we'll just say Rawkode. Well, I think I need to do dash dash string. Alright. Yeah. Add string back. And you can see here that it's doing our container echo and, I don't see my echo, but it it ran. I'm happy with it. Cargo container echo string Rawkode. Yeah. Levison. Okay. So pip install dash e SDK. Alright. We'll get to that. I mean, the
31:12 Dagger pipelines are running right now. Our editor experience might not be ideal, but we'll tell you up as we go. Now let's just make sure that you're you're happy with what's actually happening here. So I wanna just make sure that we can tweak this, you can understand what's happening. I'll take any questions along the way. If anyone watching has questions, fire away. So the other thing we can do here is we're just pulling our container echo is just pulling from Alpine latest. Right? But we could do Ubuntu twenty two zero four because nobody ever updates
31:47 beyond that. Right? So I'm curious if we want to do that or if we want to do use the conductor container that's specifically built for the project that does have all of the dependencies that might kind of speed us along. Oh, I was just gonna make a change to show you it. But you're right. Yeah. We should be using Conductor too. Okay. But I just wanna you know, we've got Ubuntu, and I'm changing the command to apt. So if we run this again, apt raw code isn't gonna do anything, but apt update should be able to run some. Oh,
32:18 that's Dagger call lets you actually append additional command arguments at that point? Because this one is configured. This function has a string argument called string arg. Okay. So it it knows that it's looking for that argument. Yeah. So there's our Cool. At update. Right? Now if we change this to be at trying to remember the Python underscores. I usually do some TypeScript, so it's camel case all the way, but we'll get there. So we can change this to app command now, and let's get standard out. We actually want to see the output of this container. Oh, look at
33:02 that. Okay. So now string arg will fail. It'll throw it into container and give us an error message, but then we can add the app command, and then we're starting to piece together a function that does what we wanted to do with the arguments that we want and that makes sense from a consumer point of view. So, at command update. Fingers crossed. Looks good. Should have picked a faster command, but still I feel like Marcos is over here. He's like the voice of Versus Code. He's like, I'm not happy. This is your this is your code editor
33:46 speaking. Alright. Yes. Editor's not happy. Thank you, Marcus. We're let's fix that now then. Now that I've covered a little bit about how to get started with Dagger and then Jean Luc and C and website's looking good. Thanks, man. Appreciate it. Yeah. That website's pretty cool. It's it's like Yeah. It's making people feel really insecure about my websites that are legitimately terrible. Well, I mean, it's all a few months ago. A website to me was, you know, a white background with black text, but I'm I'm learning. So Lev earlier mentioned so let's go into our
34:20 Dagger directory. So this is his own Python project. It was gonna show requirements dot lock as py project. I'm not a Python person. I'm really no idea what I'm doing. I don't have pep. So, Lev, based on your comment, you said pep install dash e SDK. Is that because the SDK has its own requirements, or am I installing that into my existing VM? Do I need a new v n? Maybe we should have used TypeScript. Well, if I knew Python. Right? What what would you do with a py project dot toml? Okay. So I I I I I I
34:30 Improving the Python Editor Experience
34:57 know Python in terms of IAC and have not used pyproject toml configs before. Alright. So the blind are currently leading the blind. Okay. The SDK has the binding. So we does that mean I can just go to my requirements dot text here? Can I just add a local Dagger? Is that a thing? I know that Not that I'm aware of, but it would be cool if it was. I'm waiting for a lever. Obviously, the Python people are not appreciating the genius that we bring. Yeah. I mean, I would love to do this in Python for you, but I don't wanna
35:44 slow us down. I'm thinking maybe we should go to a language that I'm comfortable with. That's fine too. If you wanna jump, if you wanna switch. And then, I mean, when it comes to transposing from one language to another, I just need to see like the structure, what the possibilities are, and then I can transpose it myself later today. Hey, it worked. Holy cow. I'm a genius. You are. Clearly. Twenty years paid off right in this moment. You're done. Retire. Alright. Can I restart a pang a Python language server? Of course, I can. Is it
36:24 gonna be happy? Let's just pop it open again. Happy. Are you happy? Yeah. I I I've legitimately impressed right now. I'm gonna have to like go back and watch the recording and I was here for the whole thing. Alright. So, I mean, that's my filled with my standard out. So let's see. Let's see if we can get that error message again. So we run Dagger call container echo. That's interesting. Oh, I haven't Okay. Chat is blowing up over what you just did right now. Yeah. I often say that the best developer experience is one where you can be successful with
37:20 intuition rather than informed decisions. And that is a key example of something that is a good developer experience. That I think that was the highlight of the this livestream for me. Oh, we better start to stop now. Right? Fuck it. Like, we're done. Quit on a high note. Okay. So now we need her at, and we'll do our updates. I just want to see that So that flag, explain the flag to me because I wasn't actually expecting the flag to be apt command. That is that determined based on what you call the argument in the code?
37:58 Yeah. So there's a lot of code generation happening behind the scenes here, a lot of magic stuff. The way that Dagger works is there's essentially build kit with a GraphQL API in front of it. The GraphQL API tells us, like, you know, container with mount, blah blah blah, and they're nested all the way down, gets pretty gnarly. But then they generate the SDKs on the back of the GraphQL definition. And and when we have a parameter to a function, the name of that parameter becomes a flag on the command line, and we can also apply the types and stuff like
38:33 that. So you get all this. There's the the they're magical voodoo warriors. I don't know what they do, but it works. I I was impressed looking at the brochure and and now I'm like, somebody needs to rewrite the brochure because this is way better than the brochure says it is. Yeah. There's the and the pace they're moving at is ridiculous as well. It's so much cool stuff. Especially for the size, like, Dagger team is. Like, the Right. Impact per seat, they're killing it. Yeah. We we need to stop catering to their egos, We don't wanna, you know, let
39:07 them get too big. So it's crap. I hate it. Why does it all work? Fix it. I'm not getting paid. So when I say things right now about Dagger, it's legitimately just enthusiasm. All of my enthusiasm is 100% legitimate. That's for sure. Right. Standard out. What's the error? Invalid selection for command container echo response and query call function. Run did not complete successfully. That So this is this the return type on this is it expects a container back where it actually our standard out is returning a string. A string. Yeah. So if we modify this because who knew Python
39:47 could be typed in 2024? Whatever. So. That yeah. That just was released as a fairly new feature in Python. And I know that a lot of early or bleeding edge type projects are still working on adopting that. I wonder if Dagger's already there. Yeah. I mean, the type and stuff is great. They're also, you know, using all of these attribute annotation stuffs as well. It's all very, very slick. As you can see, we now get the output. So so that is your first introduction to a Dagger function, how we make changes. Now we actually need to try and do
40:26 something useful. So next step. I'm gonna get ready. Two minutes in. Let's do something useful. Don't tell people. Alright. So you were talking about conductor. There's a conductor container. Can you tell me a bit more about that and how do we bring that into this process? There is. I'm wondering, do I actually get to write in chat or or or am am I censored here? There's a private chat between you and I. If you wanna chat on YouTube, you have to do that your your yourself. But you can use Okay. Alright. So, conductor container is the developer
40:28 Using the Conductor Container (Project Environment)
41:06 environment for the project and the op operations environment. It has all the dependencies for like Talos and Pulumi and Dagger and all the Python bits and stuff like that preconfigured with durenf and nixes in there if you use that yourself. So I'm thinking that might be the easiest container to run with. It's not small, but no mature Python container is. So it's g h c r dot I o slash container craft slash conductor. If we just wanna write that in. With a k? Uh-huh. Yes, it Of course, because everything in Kubernetes land has to start with a k. Right?
41:57 Like my name. I started the trend Kubernetes just, you know, got got there a little slow. Docs. Alright. So we should be able to do a dag where we grab a container, and it's ghcr.i0containercraft Mhmm. Call it's got it. Yeah. Beautiful. Copilot. Holy cow. Copilot. I love you. You're recognizing my work. No. Because I don't use the Python language ever, I've noticed that it's from the keyword, so our function here is actually from underscore. Now you said this has got everything in it. Right? So that's the web exec Pulumi version, and let's grab that standard out again just
43:01 so we can see that and update our type. Now what's cool here, we've added a new Python function and annotated it as a function. The docs are our docs help string, which we're gonna see in the CLI in a moment. And that's that's all we need to do to register a new, you know, like a make target or a bash script of which you would typically do, only we're doing it as a Dagger. Sure. So the point now where if we run Dagger functions, it should come back, rebuild the SDK and all that and and build
43:30 kit, and then tell us that we have this new function, and then we'll see my horrendous documentation as a description for what that task actually does. Got it. The conductor container, again, is not small. So do you have a solid download pipe? How big is that? Are we talking many gig? A few. Yeah. We may go a different route. Because based based on what you're telling me conductor does, I actually think the need for conductor slowly disappears with the Dagger approach. You know, you don't need some monolithic be interesting. So alright. Let's run our conductor function. So we're
43:56 Exploring Dagger Composition and Artifact Passing
44:14 gonna do a call conductor. Okay. We didn't add any parameters. This is just gonna run. We should see the output of Pulumi dash dash version as my connection is able to handle the size of this image. Yeah. So one thing that I'm curious about here, we're running all of these different things in containers. And I know one of the plans is to create a kind cluster. How does that all work? Because I know that kind results in, like, a kube config, for example. So does that mean we have to, like, volume mount the kube config
44:52 directory in so that it can write that kube config and then we can carry it on into other things? Or are we exporting it as a string and carrying that around? Or what's the plan? So this is where composition within Dagger becomes really cool. So Okay. What we're gonna do, we're gonna add some more function. I'll I'll leave that pulling just now. Right? But we'll do some other stuff so we're not sat here in silence. Plus, you asked a phenomenal question. So let's have I did ask a phenomenal question. Thank you for recognizing it. Yeah. Of course.
45:25 I like to appreciate genius when I see it. So so I'm adding a new function. Right? And we're gonna do this step by step as if I was doing this in my own project. And I'm not gonna pull this massive image. Instead, let's go back to that. I'll paint later. Cat, find a better way. And I'm gonna do a temp a b c. Right? So the function is called touch a b c, and we're creating a file called a b c. Right. And we'll return this as a a Dagger container so that we can use it later on
45:28 Demonstrating Composition: Passing Files Between Containers
45:57 as part of other pipelines, other functions, other Interesting. Whatever. Okay. Now here's where this is gonna is is it gonna let me do two of these at the same time? Dagger functions. I like that spelling dagger. Let's see. Yeah. It looks like it's working, so that's good. My editor is happy, Marcos. Well, yeah, we have touch a b c. So call touch a b c. Like so. And now this should be nice and quick. There's no outputs. We're just returning a container. So blah blah blah. It's finished. There we go. Perfect. So we have this container which
46:44 we can now use. Yeah. My address? Now we come along and go, know what? We wanna do something here. So what I'm actually gonna do is say, We we need a new function. We're gonna say read a b c. And I know this is horribly horribly contrived. No. I I this is the kind of like iterative testing that I do when I'm trying to understand something for the first time. So you are perfectly in my lane for how I learned. I appreciate this a lot. Awesome. And I'm gonna read it from a different image. I'm not gonna use alpha
47:22 So we can do a web itching to use that even to container. Well, I've told it now. So, yeah, we we're going through it. Now this isn't gonna work just yet. Right? Because we have a new base layer. We haven't pulled down anything from anywhere else. So let's run it and see that fail. Yeah. Read a b c. And we'll check on it's pulling. Yep. It is. My connection Codespaces pulls the image pretty quick. My connection is not gonna be fantastic when I'm streaming, but we'll make it Right. So now we get an error that fail
48:06 doesn't exist. So what we could do here is you can say, well, actually, let's assign horrible. I need a better name. I can't do that. I can't do that to myself. We'll just call this a t a b c file equals, and we're gonna do self touch a b c. So we're gonna run that task. Now these will be cached a lot because Uh-huh. It's and puts and outputs with both in in container. The same way a Dockerfile works, so caching is very similar. But we want to get a file from this. Okay. And then
48:44 well, I mean, I could just write that as is to the I I could just take that and then print it, to be honest. But we could mount it into this other container. So we could say with file, which needs a path and a source. So I'm gonna put it in the same location, and it is our a b c file, like so. I think I'm gonna now that we're doing this part, I think I'm gonna have to sleep on it for it to actually fully sink in and then start thinking natively in this paradigm.
49:19 Because that is a little bit, like I mean, we're layering a lot of concepts here. We're writing Python. The Python runs a ton of stuff in containers. It's not normal Python because a ton of things are happening in the background. Like, there is a lot of new neurons that you have to build in your brain for this. Yes. Just a shame we don't have fourteen hours otherwise. We we just need to Yeah. Yeah. I'm I'm gonna be playing with this after this because it very intriguing, and I'm so glad to have this introduction to it. I don't I think it would
50:00 have taken me a couple months to catch up to this No. We're gonna do something useful with this repository. But I'm I'm glad that we're we're we're we're making progress. Right? Yeah. So let's let's touch on the thing that your question there. Our touch a b c returns a container. Yes. This then becomes a variable that we can just use. Right? You know, if you think about building a container image. Right? Mhmm. If you want to get something out of it, it's actually very difficult to do because you have to, like, exec into it with a local
50:29 volume out and copy it across. I think it's been a little bit easier now, but it's been a pain point for many, many years. With this a question that I had that, like, Dagger container isn't a concept. It's literally an OCI container. And when you do Dagger, it just becomes a variable that we can introspect. I can request files, I can request directories, I can run more commands inside that container, I can do whatever I want. And then it inherits the name of the function itself is what I'm seeing. Oh, I do understand that statement.
50:59 Dag container from with file and then you have the temp a b c and wait. I'm sorry. No. The self touch a b c dot file. That is named based off of the line 39 def touch a b c. Right? Or am I Yeah. So we're calling this function, which gives us back a container. We're gonna inside the container to get a file, and we're just attaching it to this variable here. And from there, I could write it to my local host if I want. But instead, what's more like that you know, if you think about a workflow,
51:00 Introspecting and Using Container Artifacts
51:35 say with Pulumi. Right? You run a Pulumi plan, and you wanna see if that plan to fail so that you can guarantee that's what runs on your next apply. If you do that in Dagger, you could pull that file out and store it somewhere, and then your next function, which runs a Bloomie apply with Mount Nab plan and and run against it. And that's what we're doing here. We're saying grab this a b c. Now we haven't written anything to it. We could change us to be an echo with a redirect or whatever. Sure. But we just want it to exist
52:02 to a point where we can see the empty output here. So we're reaching into a container. We're saying, give me that file. I want to use it in this other container, and then it runs. Another thing we could do here, actually, maybe this is gonna be a bit. Let's run this first, and then we'll modify it in a slightly different way. Yeah. I'm I'm sitting on, like, a dozen questions that I'm not asking so that I don't continue to derail us. All questions are good questions. It's less code I have to write in Python. Right. It works. The whole time. It's a
52:36 feature. This is great. We have all these text. No. It doesn't really do anything useful. So let's change this. Right? Now what we're gonna do is I'll paint, and I need to be careful here actually because we've got a muscle and glibc thing if I try to do a command from Alpine. Instead, let's grab is there an Arch Linux image? Surely. Yeah. There there must be. Right? Sure. Surely. You're you're gonna do another intuitive thing here and it's gonna work flawlessly. What I'm gonna do is I'm gonna grab gold one. What's the latest version of gold?
53:11 One one twenty seven? No. Seven or eight? Go one. So to the point where I'm gonna run Go I'm on 1.21. One two one. Right. Okay. I thought Yeah. 2112 should work for Marcus. Okay. And we're gonna run Go version here, and we're gonna get back a container. But what I'm actually gonna do what I'm actually going to do, we'll get the path for it so I know where it lives. So I assume it's gonna be used to bring Go. Yeah. So let's keep it more visual. Right? We wanna see the version number. So let's grab the Go
53:51 binary, which I believe is going to be here. It may be wrong. And we're gonna mount this in to user bin Go On the bin to a container, which has no go. And we're gonna run go version again. Thing that I'm curious about here is you could actually do which go and then use that output as a string to inform the path that you hard coded in on forty four and forty five? I totally could. Yes. Okay. Practicing concepts here out loud. Alright. Let's get standardized first. One dot two doesn't exist, so I think we need to drop
54:42 one dot two one. It looks like Marcos is backing us up here. Well, he says up for failure faster than fixed it, so that's okay. So let's run touch a b c. Touch. Hey. We've got conductor as well, so we can make some progress on the the real work. But let's see the output of Go version, and then we're gonna pull that binary out, stick it into the Ubuntu container, and run Go version again, which I just think is very cool. Oh, Go one doesn't exist. Yeah. You might go latest. I think go line. That's what it's gonna
55:25 be, isn't it? Possibly. Yeah. There we go. There it is. You didn't catch that, Marcos. Come on. Supposed to be a team. He's not even here to defend himself, and you're like I know. He's trying to stick me on one bookworm there. But, yeah, we're we're all good. He's also talking about really oh, I just showed the wrong comment there. He's talking about a really cool feature we could do with Dagger. And, hopefully, we have time to get into it. But we actually have the ability to, like, go inside of our build pipeline and debug things live.
55:58 I need to see that. That is necessary for success. Yeah. Debugging is a very important skill. And that's one of the challenges You've got Podman here. Are you Mhmm. Is Dagger happy with Docker and Podman interchangeably? Like, is there anything unique there? You need the alias. So under the hood, at least when you run a Dagger in it, when it creates that build kit engine, the Dagger engine. I believe it does shell out to to Docker to get that set up. So I just have to alias that, Podman to Docker for that to work. But
56:41 everything else is okay, and I do run Podman in compatibility mode with Docker. So I I feel like our audience knows as much, if not more than us right now because apparently, they're telling us all they're speeding ahead and and, like, answering the stuff that we're gonna reveal here. Right. Well, we got oh, yeah. Because I didn't update my type. I wonder if I can just leave that off. No. Let's be good citizens. Yeah. Think yeah. And let's not fall back to the lazy typing. Exactly. Yes. No. This should be pretty quick. It's just regenerating the SDK because we changed the type.
57:25 And then we should see Go version one twenty two. Perfect. Cool. Let's take off that standard out. Go back to a Dagger container, which means that our second thing here will work. If we returned a string, we would no longer be able to query that container itself, which is when you really get into composition. Right? This is where I would just say, well, let's have another function where we say def touch a b c output or something like that, and that would just be returning that. So now we have a new function if we need to, but we always wanna
58:00 keep that container available for other things. The good code hygiene becomes very important, especially for composition. But let's not get too too meta with the code right now. So now we can do a read a b c, which is going to execute Go on an Ubuntu container, which has never seen Go in its life. Right. Read a b c. Does that make sense? I know we're not really getting into anything particularly useful, but We are. Absolutely. I mean, I know that we kind of suggested we would be doing actual cargo work here, but I feel like we both have to be
58:45 on the same page to actually make progress there, and you are doing a phenomenal job teaching. Thank you. So her container file failed. So that is not the path of Go. So let's say, read Go or file. Let's call it Witch Go, where we're going to execute another command. I love Copilot. It's so good. And we'll run which go. And that will give me the path for go, which will then fix that main statement, and we'll see us passing artifacts from job to job and a code first fashion. So it's user local go bingo. I want the container to tell me. I
59:38 know. You're doing a brilliant job coding your way to the and I'm just like, docker run exec. The Dagger team are yelling at me going, just show terminal. And I'm like, yeah. But, you know, composition is important too. We wanna show people editors. But, yeah, we should show terminal. So let's just make sure we've put out the right binary. Let's go for read ABC, and then we will use terminal. So one of the nice things that I'm seeing here about, for example, using the code itself to find the path is later on down the road, if you switch
1:00:15 out a container that has a different path, that's just gonna, like, dynamically adjust itself, and you don't have to go in and fix a bunch of hard coded stuff. So that's pretty cool all by itself. Yeah. I mean, that should have worked. I'm not gonna fix that. I said, no. Just complete it and the go route doesn't exist and stuff. We did get go into that container, and it did attempt to run. To me, that is good enough. Okay. So let's do terminal. So when we have let's this one returns a container. We have touch
1:00:40 Debugging with Dagger Terminal Feature
1:00:52 a b c. So if we do Dagger call, I will look at the help here. You'll see all of our functions, and we've got all the parameters. Is terminal not documented? Okay. We'll go to touch a b c and do terminal. Tribal knowledge. So what's actually happened here is that Dagger call touch a b c returns a container. So when we add terminal, that gives us the ability to get a shell inside of that returned container. If we return to anything else, it wouldn't happen. So I wanna compare this to what I have been using. I've been using
1:01:40 GitHub actions for a lot of my CICD, and I use Act CLI. That's a little CLI that runs GitHub Actions locally in a container. When things go wrong and it's a very long workflow, you have to wait sometimes fifteen, twenty minutes in between iterations to see if you actually succeeded at fixing or enhancing whatever you're doing correctly. And it is not accessible for debugging. So this actually lets you jump into your pipeline at the point that it's breaking and sort out the problems, like, hands on. And that is my style. Like, if I can't get hands on with my own infrastructure
1:02:28 and build and things like that, I feel like my hands are tied. I love this and I'm going to overuse it and that's so cool. Yeah. I think, you know, the Dagger team are using Dagger themselves, of course, and that dog fitting comes a lot of strong developer experience benefits with every release. Right? They're always making things that little bit nicer, a little bit easier. Yep. But Marco says the problem with my help was I needed the function first, and that should have told me the terminal extra. Cool. You can actually run any of Dagger's
1:03:06 functions. So Got it. There is a lot of help there to read and I love that that generates all dynamically based on your functions. Yeah. It kind of insane. Yeah. You can even retrieve the file. We could do that just on the command line if we wanted to. So Okay. Okay. I mean, I think that covers all of the the basics. Now there's a whole bunch of other stuff that we're I mean, we've got what? Twenty five minutes left of the time that we can set aside for this. If we can build the kind cluster,
1:03:30 Attempting to Create a Kind Cluster with Dagger
1:03:40 then that'll give me enough boilerplate to proceed from there. And I'm I kind of have a goal of seeing if I can get the whole, like, build and deploy to run by, like, 01:00 my time. So that would give me something like two and a half hours. So if we can get a kind cluster built, I can run with it from there solo. Okay. So we're gonna have to work out the container within the container part. So I'm gonna ask Marcos, so I know he's been doing the KCS stuff. I think it was Marcos. Sorry, Marcos. I'm speaking
1:04:05 Reviewing Kind Setup and Challenges
1:04:17 and assigning you something that you haven't done. But let's get the the boilerplate for the kind stuff working with your config. And then, hopefully, Marcos can drop in some context for how we make sure that that's actually going to work. Sure. So So for this, you might wanna open the makefile because the makefile, I do use make kind a lot. And there's a few commands in there. Yep. There it is. Okay. So you're looking at lines one sixty three to one sixty six is the important stuff. Do we need the volumes? If we comment out those volumes
1:05:07 from our kind config, then we don't. But as long as that's the kind config, we do. With Dagger, we wouldn't use Docker volumes. We would use Dagger volumes and put them into the containers as required. Although then, they have to get in propagated into. Yeah. Let's yeah. Let's work this out. So let's take a look at your kind config first. Mhmm. In the hack directory because, I mean, aptly named. Yeah. That seems to be it's a ghost thing. Right? The hack directory. It's it's never something I've I've done a lot of, but I know. I I I have them littered
1:05:47 around everywhere. It's it's not it's probably not great hygiene. Okay. So what do you use these mounts for? This is just an image cache. Right? Yeah. I I I was just using it to cache images because it is a Kubernetes project with a ton of different operators and helm charts and things like that. And building and destroying and building is a lot of work if you're downloading images every single time. So I was volume mounting basically local file image caches so that it can survive multiple cluster build and destroys. Okay. I'm gonna try something. Let's come back to
1:06:34 Attempting Docker-in-Dagger (Running Docker CLI inside a Dagger Container)
1:06:36 Kangen just a moment. Right? So I don't know. Python, can I drop this down? Is that valid Python? No. You you should be able to do that within the parentheses itself. So if you go yeah. What? I have to do it that way? Mhmm. Yeah. That would work. But there must be a way for me to do it. Wait. Not that I know of. Alright. We'll just deal with the really long lanes. What I wanna do is grab says kind will be a bit painful to make work. So I'm really curious how that really works out and
1:07:24 it requires Docker CLI. So I have Docker CLI in the conductor container, but actually running the conductor container requires a lot of extra flags and things that I do have documented if we want to figure that out. But Well, was gonna try this first. Super pretty. I was wondering if because if we can get Dockerdams to work, we could just stick say kind go binary inside of that from the kindest image and it should it may work. So I'm gonna try if I can see if I can run Docker hello world with Dines inside of our Dagger pipeline.
1:08:01 Okay. And see what happens. So there's a lot of and see what happens today. Apparently. We are we are mastering the see what happens today. Yeah. So let's see. I feel like we've been like succeeding rather you've been succeeding so well for an hour and ten minutes now and we're gonna run out of luck at some point. We're really really either that or you should go to a casino after this if if that's a thing you do. Yeah. I'm not alone in casinos anymore. Okay. A self imposed ban. They sell whiskey and they've got poker. It's not it's not good.
1:08:48 They know that magic combination works. Marco says, I may need privileged, and he's got a point. Mhmm. Yeah. There's definitely some things. Although that did say that it couldn't get a socket. And then that's just probably because I'm not actually using Docker. Right? Oh, yeah. Good god. We are, like, stacking the unicorn, yeah. Is there a pod man Oh my god. Don't Well, just put my container around pod man Podman. Let's yeah. There is. Oh gosh. The the insanity inception going on at the moment. I feel like this is proof that the internet should not work and somehow does.
1:09:59 Running Docker Daemon as a Dagger Service
1:10:20 So Marco's saying we have to start that first. So we have to start Docker daemon. Hey, I've got an idea. Right. Right. This is gonna be awesome. So I hope. David said, hey, I've got an idea. So we need to start Docker d. Right? And I spelled privilege wrong. Let's just ignore that. As a service, This might be just absolutely crazy, but I'm gonna go for it anyway. Insane. Create so Dagger has this other really cool thing where you can run things as services, and then you can launch other containers that can then consume them and speak to them,
1:11:04 allowing you to replace Docker Compose. Marcus is getting excited. Okay. Yeah. There's a similar thing in GitHub Actions, of course, where you can start, like, what if you need, like, a database or something like that for your pipeline to run, it it it has the concept of starting service containers as well. So now we could see we could just run down again. Only this time, what we actually want to do is a docker run. Ugh. I hate using that shorthand since that. It bugs me. Container run dash dash r m a little world. Right? So that should give
1:11:35 Implementing the Docker Service and Client
1:11:44 us, and we don't need the thing. Right? But we have to tell it where that Docker host is. So if we do web environment variable, Docker host, and then we need to grab the service endpoint by doing self stock create endpoint. Okay. And apparently, we're gonna need elevated Dagger privileges on line 53. Yeah. I'm gonna So I'm actually curious what that means. If that means, like, Dagger has pseudo or something within our current environment. What's the Docker port? Two. Oh, come on. 2376? That sounds right. Thank you. I was hoping to drop in. Alright. That
1:12:56 should give us an endpoint. 75. 2 C 7 5. Alright. Okay. So this is gonna create a service running the Docker daemon. We're then going to add an environment variable, set in our Docker host to that endpoint and run Docker. And I'm totally making up this up as I go along. So I am gonna check the chat to see. Oh, okay. WebExec. So the Docker d needs some sort of parameter. So let's just and secure root capabilities. Thank you. And the one that we're setting here, so we're not using positionals. It's just args. So args,
1:13:38 and then we can also do in true. Is that right, Marcos? Well, I mean, let's try it. He can he can fix my terrible code layer. So now we should be able to run create king cluster. Dagger called create king cluster. So now we're actually gonna see multiple containers happening with our Dagger output here. So it's gonna compile that, generate the new SDK because, obviously, lots of things have changed. And we should see it spin up that service for us running Docker d. Oh, no. Class. So we didn't get a string. We got something else. What's the endpoint then?
1:14:35 What have I what is a a coroutine? Any any string. Where do they go here? Is there, like, a two string or something? Quotes. Wait. Are we missing wrap Oh, wait. Does this need to be a string? Supposed to be a string? Ah, okay. No. It's a nim. No. It's a nim. It's async. Oh, I don't know how to do async await in Python. Can I just do await? And then set an async function. How do you do async functions? Deaf async? Nope. Alright. Save us, chat. Or you might pull the away off of I don't know. Deaf, async.
1:14:49 Debugging Python Async/Await Issues
1:15:29 Oh, it's async deaf, not deaf async. Yeah. Copilot's getting me there. Alright. Thank you, chat and Copilot. Sweet. And then No errors. Thank you, Jeremy and Lev. I'll jump it in there. Oh. Alright. So Create kind cluster. But I think I've got, Yeah. That looks okay. Redeemed endpoint. From address. Where's the standard out coming from? I don't think we're oh, here. Oh. Oh, because we've got an async function there. So we're gonna have to await this one too. Right? And he also said we may have to make this one async. So let's just make everything async. Right?
1:16:51 Should've used TypeScript. Actually, I'm quite enjoying the pie. I mean, I'm not enjoying these really long lines, and I wish I knew how to format these. I don't have a a Python form. Yeah. I'm gonna I'm gonna get really obsessive with formatting and apply that on my own time. But Alright. So no end point. So that returns the service. Oh, I'm gonna have to await await. Right? Because we just made the other one async. And then await await. I think async causes more problems than it's solving. Service can't be used in an area. Alright. Okay. Which one are we? I'm gonna ask
1:17:46 you to retype now. Endpoint. So create things returns a core routine. So we do have to await this, and that's because we made this one async. Right? An endpoint returns one. Let's see. Jeremy dropped an example. Return that container Alpine directory with exact bash. Jeremy, let's have a look. I'm not sure what that that doesn't solve our async thing. Right? Yeah. It's not grokking with what's in my head yet. Oh, you're showing me the formatting thing. Right? Right. Right. Okay. Okay. Create was never awaited. I do awaited. Oh, wait. Wait. Oh, wait. Alright. What we have here is a parenthesis problem.
1:19:09 Service can't be used. Right. I'm I Marco says this doesn't need to be oh, let's I think we're making this difficult for ourselves now. Create things is fine, and we just want to await the endpoint. Cool. I mean, that shouldn't be needed. Right? But I'm sure we tried this first. That just that didn't work. There's gotta be some prior art floating around somewhere on creating a kind cluster with Dagger. Oh. Look, things things and stuff. So he I tried to speak to Docker or Dain. That's amazing. But it says, no such host. So it got our endpoint. It resolved it
1:20:06 to an IP address and then failed. Now this shouldn't just be So there in something in the Daggerverse specific for creating cluster. Is this where we get to show off some of the ecosystem? Yes. And that looks like there's quite a few parameters that we can run with. Oh, yeah. I I'm being silly. We've created a service, but we haven't given desk container access to it. Okay. There we go. Oh, yeah. And we can alias it. We can just call it down, and then we provide the service, not the endpoint. Okay. Like so. They're trying to fix all my all my
1:20:48 Correcting Service Connection in Dagger Client
1:21:24 bugs for me. So here, we could do two, three was it seven five? Yeah. Alright. Let's give that a bash. And you're right. There is the Daggerverse. We should definitely take a look at that, but I really wanna get this cluster working. Really, really wanna get it working. I actually like this because it looks like I I'm interested in deprecating the project support for kind in favor of the equivalent with Talos where you're running Talos either in containers or virtual machines locally. And I'm seeing how even though there's not like a built in feature that plays completely nice with starting a
1:22:16 kind cluster locally without like kube proxy and things like that so that I can CI all of my Cilium integration. But I feel like Dagger I thought we had it. I don't know. Lets me cover those bases and accommodate some of the conditions. Sorry. I didn't mean to yell over you there. No. You're fine. I excitement excitement is always welcome. Alright. Let's go back to service endpoint four two three seven five. And this needs a week. So you wanted to have to get kind and do it another way. That's what you're saying before. I really interrupted
1:22:57 you. Sorry. It's yeah. It's gonna be the the same the same thing. Like, it's Kubernetes and Docker, but it's Talos specifically. And that will simplify my code base a lot because right now, I'm accommodating different, like, helm values and things like that depending on which Kubernetes I'm targeting. Nice. Alright. Well, Marco says I was almost there, but I need a web exposed port because Dagger uses that for the health check. Alright. So that's how it knows whether it's to restart that service or not. We'll get there. I'm I really want to make this work just
1:23:48 so that we have a very cool Kubernetes cluster thing where you can start to then experiment and play with. And I know you said you were gonna maybe get rid of King. Well, it all of this will probably transpose pretty closely to the Talos version because again, it is Kubernetes in Docker. It's just slightly different than Kine. Alright. We only got four minutes to save the world. I mean, create a kind cluster. I'm missing a parameter for Docker d, aren't I? Let me pop open a Docker d. Cut the red wire. Apparently, you need a config fail.
1:25:05 Fixing Docker Daemon Service Arguments
1:25:05 It looks like Marcos is pointing out that we need to set the address to, like, zero zero zero zero would work. Oh, thank you, Marcos. Dash dash code. Host. So Is this the one? I have hope. Marco says it's the one. We will all be wrong together. So the service worked. Yep. Alias as d I n d exited. We have response from query input. Blah. Is that just my command did it wrong? Let's get standard error. I think we're actually getting a real error message from the docker trying to execute that container. This is when we could hit the terminal
1:26:15 Debugging the Docker Client Container with Terminal
1:26:29 command. Yeah. Totally, actually. Alright. Let's get in there. So let's just return a Dagger container. Now this should give us a container with the Docker CLI and an environment variable pointing it to our Docker service. I've never never used a terminal command with back end services. So I'm assuming this is just gonna work well. Spoke too soon. Why did we have to pick a difficult starting line? Yeah. I don't know why that one's failing. You can blame me. And violation for command terminal response. Oh, actually, I I didn't even catch this and I probably should have Marcos said we have
1:27:29 hosts. Plural? There we go. Yeah. But I I I mean, I should still got this. Given us a terminal. Unless I mean, Docker wouldn't like a flag that's not real. It was the service was happy. It was passing itself to said so. One minute. And I'm running terminal. We were closer with hosts, aren't we? Oh, it doesn't like the insecure access right now. Oh, it's working. Holy moly. And I'm pulling the standard error. Although, we'll now see that this should be nice and quick because most of this is gonna be cached. Right on 06:30. Right when we said we'd finish.
1:28:09 Successful Docker-in-Dagger Demonstration
1:28:52 But we didn't really that will work. Yeah. We didn't we didn't do the things that we, you know, we said we were going to do. But I do think that we have hopefully taken you on a bit of a Dagger journey and showed you the power, flexibility of having Will be the power. All of this as code. So I'm pretty chuffed with that. There we go. Look at that. Holy cow. We just spun up a cane cluster inside of a dagger function. Okay. This is this is like a Internet high five here. Yes. I'm gonna leave you with that to play with
1:28:55 Recap and Future Plans for Cargo Dagger Integration
1:29:33 it. If you were to have to that. Pick this back up in a few weeks and then Yeah. Make make that next step and to run-in the Pulumi as part and provisioning to that kind cluster. Well, might be that, like, I push this code a little bit further because I'm very motivated to drop that make file stuff and I have to rewrite the make file or replace it before I merge back in the main. Yeah. So it might be that I push this a bit further and then we just spend a while roasting my Dagger code and you're like, Pat, how
1:30:07 much did you use ChatGPT because you're looking like a trench coat right now. Alright. I am gonna get that pushed. We will reconvene once you've pushed it a little bit further forward, and maybe what we'll do, depending on how far you get, is we'll be looking at refactoring. How do we clean it up? How do we make it shareable? How do we publish it to the Dagger first? Because you know what? People are gonna want a kind cluster in their Dagger pipeline. We can share that. Absolutely. Awesome. Thank you so much for your time today.
1:30:33 Conclusion and Farewell
1:30:35 Thank you to everyone who watched. Any final words before I say goodbye? Bravo. I I feel like that was a great way to show off your skill and do more than talking on a livestream. So really, you you went in into it with a lot of blind faith, and I feel like you're coming out of it victorious. So round of applause from everybody. Thank you so much. Alright. Thank you for having chat soon. Yeah. Awesome. Speak to you soon. Everyone else, have a wonderful day. We'll see you all next time. Bye. Rawkode. Rawkode. Miss you for a little while. Never fear
1:34:12 the return. Rocket with a smile. Join the crew again. Don't you take the fall. Stand tall. Raise your voice. Let's conquer it out.
Technologies featured
Meet the Cast
Stay ahead in cloud native
Tutorials, deep dives, and curated events. No fluff.
Comments