Experimenting With Dagger.IO (DevOps North East Follow-up)
Introduction:
This week’s blog post actually relates to the DevOps North East Meetup that I was recently able to attend.
As the name suggests, this event looked at the history of DevOps as well as raising awareness to Dagger (An interesting CI Engine which runs pipelines as containers, creating them with code!).
Find out about an overview with the event as well as how I went on to try out this tool; what I got up to as well as some minor challenges that were faced along the way.
As always, be sure to applaud, comment and share with your friends!
Happy Reading!
The Event Itself:
Split into a talk about DevOps (15 years of DevOps) as well as a demo of Dagger.io.
History of DevOps:
Founded in Belgium.
15 Years Old.
Reference made to the DORA Metrics. Whilst currently I’m at the perspective of a developer, there’s definitely value in being aware of these metrics, potentially for future career growth or even just curiosity at the very least.
Thought of as a whole philosophy rather than purely a technical concept (Of course there are now many tools to support this).
The talk also made reference to ‘flashy’ topics like FinOps and MlOps (These may get covered in the future).
Dagger IO:
It’s a programmatic tool for creating pipelines that run in containers.
The idea behind it is you can use the SDK to create pipelines (Using Python/TS/…) rather than Bash/YAML which can get quite messy.
There’s also the ‘Daggerverse’ which is a community of modules for typical pipeline tasks (Using Node, Docker …).
It’s great because the pipeline is local and if it works locally then you’ll be fine to push it up to your Continuous Integration provider.
My Own Experiences With Dagger IO:
Prior Thoughts:
So while the idea of it is great, containers can get messy. In the past I’ve had issues with GCP Billing and Complexity with Cloud Providers. Even with Jenkins, I ran into challenges where it came to creating the pipeline itself therefore I just wanted to see if I could create a pipeline with code.
As with any new library there’s so many new terms and concepts. To avoid getting overwhelmed, I’d decided to stick to the quickstart instructions just to ensure that I could create a pipeline without too many challenges.
The only change I made was using a React JS Starter Project (Those who know me know React is my go-to web app library) rather than a Vue JS Web App.
Challenges:
Path Problem:
During the installation, I kept running into this bug where even though I’d added Dagger to the path, it wasn’t recognised by the Powershell V7 terminal within VS Code.
Eventually I was able to tweak VS Code to use the V7 terminal by default however the path still wasn’t recognised. It would appear when echo-ing the path but dagger commands would not work.
After a lot of trial and error, the solution settled on was to call Dagger in Powershell using a reference to the path, followed by the command itself:
& “C:\PATH_TO_DAGGER\dagger.exe” login
Class Name Problem:
Given the following Dagger Code Snippet (REF: https://docs.dagger.io/quickstart/daggerize):
import { dag, Container, Directory, object, func } from "@dagger.io/dagger"
@object()
class HelloDagger {
/**
* Publish the application container after building and testing it on-the-fly
*/
@func()
async publish(source: Directory): Promise<string> {
await this.test(source)
return await this.build(source).publish(
"ttl.sh/myapp-" + Math.floor(Math.random() * 10000000),
)
}
/**
* Build the application container
*/
@func()
build(source: Directory): Container {
const build = this.buildEnv(source)
.withExec(["npm", "run", "build"])
.directory("./dist")
return dag
.container()
.from("nginx:1.25-alpine")
.withDirectory("/usr/share/nginx/html", build)
.withExposedPort(80)
}
/**
* Return the result of running unit tests
*/
@func()
async test(source: Directory): Promise<string> {
return this.buildEnv(source)
.withExec(["npm", "run", "test:unit", "run"])
.stdout()
}
/**
* Build a ready-to-use development environment
*/
@func()
buildEnv(source: Directory): Container {
const nodeCache = dag.cacheVolume("node")
return dag
.container()
.from("node:21-slim")
.withDirectory("/src", source)
.withMountedCache("/src/node_modules", nodeCache)
.withWorkdir("/src")
.withExec(["npm", "install"])
}
}
‘HelloDagger’ actually refers to the name of the Dagger Project.
Between me using a React app as opposed to the original repository, this cost me time with a strange error message.
Default Example Test Minor Issue:
The examples were usingnpm run test
however this just needs to be npm test
.
Conclusion:
I was able to complete the ‘Quickstart’ section of the Dagger IO docs.
Given that I’ve used TypeScript so much, I can definitely see the benefit in creating the pipeline with code as opposed to Bash/YAML.
As great as this example was, I’d need to apply the Daggerverse into one of my own projects in order to be fully confident.
If we’re comparing this to Jenkins then I was able to complete all of the stages of a Pipeline here (This failed when I tried working with Jenkins).
All in all I see the value in this tool and would be open to using it in the future.
Final Things:
As always, thank you for taking the time to read this article.
All my links are here.