{
  "$type": "site.standard.document",
  "content": {
    "$type": "site.standard.content.markdown",
    "text": "Have you ever had to implement a CI/CD pipeline and then proceed to push to a repository 10/20 times just to see if the pipeline works correctly? Well, this ends today!\n\n## Dagger (not the stabby kind)\n\nDagger's tagline is\n\n> CI/CD as Code that Runs Anywhere\n\nIt is a way for developers to create pipelines that run everywhere, be it locally, as Github Actions or anywhere where you can spawn containers; it is what I use to do a test build on [magiedit](https://magiedit.magitools.app) and what I'll use when I eventually write unit tests (it'll come one day, I promise.)\n\n### How do you use it?\n\nDagger provides different sdks (for Javascript, Python, Go etc) and they also have an HTTP and GraphQL api, so you can use with whatever coding language you prefer. Then you just run it wherever your pipelines run.\n\n## Creating a Pipeline\n\nIn this article I'll be using the Javascript sdk, because that is the one I know better (and because it is my article, after all). We'll be looking at how to create a simple pipeline script with some extra configuration like setting some env variables.\n\n### Prerequisites\n\n#### Container engine\n\nDagger requires a container engine for it run wherever it needs to run (at this stage, at least, locally); the recommended one is Docker (I have an article on the basics of Docker [here](at://did:plc:dgtaz4vldacvqhvvmdvoc4ad/site.standard.publication/3mfbydibiwc7f/articles/taming-the-whale)), but other runtimes are compatible (podman, containerd etc): here's [an article](https://docs.dagger.io/541047/alternative-runtimes) detailing how to use them, though I would still recommend Docker.\n\n#### Install Dagger CLI\n\nYou can find the installation instructions [here](https://docs.dagger.io/quickstart/729236/cli), but the gist is (for Linux / WSL) to execute this line:\n\n```sh\ncd /usr/local\ncurl -L https://dl.dagger.io/dagger/install.sh | sh\n```\n\n#### Install Dagger SDK\n\nFor this example I'll be using the NodeJS sdk which you can install like this:\n\n```sh\nnpm install @dagger.io/dagger --save-dev\n```\n\n### Writing the actual pipeline\n\nThe main thing to do is import the `connect` function from the Dagger sdk, because everything will happen in there:\n\n```javascript\nimport { connect } from '@dagger.io/dagger'\n```\n\nOnce we call this function, we can pass it a callback that gets as its argument the client instance; this is what we will use to define our pipeline:\n\n```javascript\nconnect(async (client) => {}, { LogOutput: process.stdout })\n```\n\nAs you can see from the snippet above, you can also specify where the output logs will be sent; in this case, the standard output is good enough, but you could also sent them to a file that could, for example, be uploaded as an artifact for the pipeline run.\n\nThen you can declare a runner with a base image and run all the commands you need with it;\n\n```javascript\nconst node = await client\n  .container()\n  .from('node:18')\n  .withDirectory('/app', client.host().directory('.'), {\n    exclude: ['node_modules', 'ci'],\n  })\nconst runner = node.withWorkdir('/app').withExec(['npm', 'install'])\n```\n\nIn the above snippet, we declare a container based on node 18 and we copy the contents of the current directory (excluding the folders called node_modules and ci), then set the working directory to /app (the directory we copied our project to) and execute npm install inside it.\n\n![The Walking Dead Easy Peasy GIF](https://media0.giphy.com/media/NaboQwhxK3gMU/giphy.gif?cid=bcfb6944db5rkmw2adjnr7wtx95a7veo71t5t5zl7aj2gs9h&ep=v1_gifs_search&rid=giphy.gif&ct=g)\n\nNow, how about running a build script and getting the error output (if any)? Simple, we just continue adding calls to our connect callback:\n\n```javascript\nawait runner.withExec(['npm', 'run', 'build']).stderr()\n```\n\n### Running the pipeline\n\nTo run pipeline, you simply execute it like any other NodeJS script; assuming you have saved your script as `build.mjs` in a `ci` folder, you can just run:\n\n```sh\nnode ci/build.mjs\n```\n\n![Weird Al GIF by The Roku Channel](https://media1.giphy.com/media/iFCmbYrTnj96luPXhE/giphy.gif?cid=bcfb69441tcje7xshjfsao2o95j0e18ft09mbqt9mfjs0g6f&ep=v1_gifs_search&rid=giphy.gif&ct=g)\n\nAnd that's how you can create and run a basic pipeline; note that you can create multi-stage builds, publish images, using existing Dockerfiles and much more!\n\n### Bonus Round: Github Actions\n\nRunning a Dagger pipeline in Github Actions is pretty straightforward; you need to setup your environment to be able to run Dagger, which means basically installing nodejs js and installing dependencies:\n\n```yaml\nname: build\non:\n  push:\n    branches:\n      - master\n      - feature/*\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: pnpm/action-setup@v2\n        with:\n          version: 8\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 18\n      - name: Install dependencies\n        run: pnpm install\n      - name: Build\n        run: node ci/build.mjs\n```\n\nIn this example, I'm using pnpm to install my dependencies, and then simply execute the pipeline.\n\nIf you want to learn more about Dagger, check out [their website](https://dagger.io/); they have some very nice real case articles on how to use Dagger to build more complex pipelines.",
    "version": "1.0"
  },
  "path": "/articles/test-with-dagger",
  "publishedAt": "2023-10-15T00:00:00.000Z",
  "site": "at://did:plc:dgtaz4vldacvqhvvmdvoc4ad/site.standard.publication/3mfbydibiwc7f",
  "tags": [
    "docker",
    "devops",
    "dagger.io",
    "javascript"
  ],
  "textContent": "Have you ever had to implement a CI/CD pipeline and then proceed to push to a repository 10/20 times just to see if the pipeline works correctly? Well, this ends today!\n\nDagger (not the stabby kind)\n\nDagger's tagline is\n\nCI/CD as Code that Runs Anywhere\n\nIt is a way for developers to create pipelines that run everywhere, be it locally, as Github Actions or anywhere where you can spawn containers; it is what I use to do a test build on magiedit and what I'll use when I eventually write unit tests (it'll come one day, I promise.)\n\nHow do you use it?\n\nDagger provides different sdks (for Javascript, Python, Go etc) and they also have an HTTP and GraphQL api, so you can use with whatever coding language you prefer. Then you just run it wherever your pipelines run.\n\nCreating a Pipeline\n\nIn this article I'll be using the Javascript sdk, because that is the one I know better (and because it is my article, after all). We'll be looking at how to create a simple pipeline script with some extra configuration like setting some env variables.\n\nPrerequisites\n\nContainer engine\n\nDagger requires a container engine for it run wherever it needs to run (at this stage, at least, locally); the recommended one is Docker (I have an article on the basics of Docker here), but other runtimes are compatible (podman, containerd etc): here's an article detailing how to use them, though I would still recommend Docker.\n\nInstall Dagger CLI\n\nYou can find the installation instructions here, but the gist is (for Linux / WSL) to execute this line:\n\nInstall Dagger SDK\n\nFor this example I'll be using the NodeJS sdk which you can install like this:\n\nWriting the actual pipeline\n\nThe main thing to do is import the  function from the Dagger sdk, because everything will happen in there:\n\nOnce we call this function, we can pass it a callback that gets as its argument the client instance; this is what we will use to define our pipeline:\n\nAs you can see from the snippet above, you can also specify where the output logs will be sent; in this case, the standard output is good enough, but you could also sent them to a file that could, for example, be uploaded as an artifact for the pipeline run.\n\nThen you can declare a runner with a base image and run all the commands you need with it;\n\nIn the above snippet, we declare a container based on node 18 and we copy the contents of the current directory (excluding the folders called node_modules and ci), then set the working directory to /app (the directory we copied our project to) and execute npm install inside it.\n\nNow, how about running a build script and getting the error output (if any)? Simple, we just continue adding calls to our connect callback:\n\nRunning the pipeline\n\nTo run pipeline, you simply execute it like any other NodeJS script; assuming you have saved your script as  in a  folder, you can just run:\n\nAnd that's how you can create and run a basic pipeline; note that you can create multi-stage builds, publish images, using existing Dockerfiles and much more!\n\nBonus Round: Github Actions\n\nRunning a Dagger pipeline in Github Actions is pretty straightforward; you need to setup your environment to be able to run Dagger, which means basically installing nodejs js and installing dependencies:\n\nIn this example, I'm using pnpm to install my dependencies, and then simply execute the pipeline.\n\nIf you want to learn more about Dagger, check out their website; they have some very nice real case articles on how to use Dagger to build more complex pipelines.",
  "title": "test everywhere with dagger.io",
  "updatedAt": "2026-05-17T13:09:10.188Z"
}