docs/versioned_docs/version-0.17.2/cookbook/cookbook.mdx
import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem";
The following Dagger Function accepts a Directory argument, which could reference either a directory from the local filesystem or from a remote Git repository. It copies the specified directory to the /src path in a container and returns the modified container.
:::note When working with private Git repositories, ensure that SSH authentication is properly configured on your Dagger host. :::
<Tabs groupId="language"> <TabItem value="Go">Copy the /myapp host directory to /src in the container and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container and return the modified container:
Copy the private user/foo GitHub repository to /src in the container and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container and list the contents of the directory:
The following Dagger Function accepts a Directory argument, which could reference either a directory from the local filesystem or from a remote Git repository. It copies the specified directory to the /src path in a container, adds a file to it, and returns the modified container.
:::note Modifications made to a directory's contents after it is written to a container filesystem do not appear on the source. Data flows only one way between Dagger operations, because they are connected in a DAG. To transfer modifications back to the local host, you must explicitly export the directory back to the host filesystem. :::
:::note When working with private Git repositories, ensure that SSH authentication is properly configured on your Dagger host. :::
<Tabs groupId="language"> <TabItem value="Go">Copy the /myapp host directory to /src in the container, add a file to it, and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container, add a file to it, and return the modified container:
Copy the private user/foo GitHub repository to /src in the container, add a file to it, and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container, add a file to it, and list the contents of the directory:
The following Dagger Function accepts a Git repository URL and a branch name, tag name or commit id. It copies the repository at the specified branch, tag or commit to the /src path in a container and returns the modified container.
:::note When working with private Git repositories, ensure that SSH authentication is properly configured on your Dagger host. :::
<Tabs groupId="language"> <TabItem value="Go">Clone the main branch of the public dagger/dagger GitHub repository to /src in the container:
Clone the public dagger/dagger GitHub repository at tag v0.12.1 to /src in the container and list the contents of the CHANGELOG.md file in the repository root directory:
Clone the public dagger/dagger GitHub repository at commit id 196f232a4d6b2d1d3db5f5e040cf20b6a76a76c5 to /src in the container and open an interactive terminal to inspect the container filesystem:
The following Dagger Function accepts a File argument, which could reference either a file from the local filesystem or from a remote Git repository. It writes the specified file to a container in the /src/ directory and returns the modified container.
Copy the /home/admin/archives.zip file on the host to the /src directory in the container and return the modified container:
Copy the /home/admin/archives.zip file on the host to the /src directory in the container and list the contents of the directory:
Copy the README.md file from the public dagger/dagger GitHub repository to the /src directory in the container:
Copy the README.md file from the public dagger/dagger GitHub repository to the /src directory in the container and display its contents:
The following Dagger Function accepts a Directory argument, which could reference either a directory from the local filesystem or a remote Git repository. It copies the specified directory to the /src path in a container, using a filter pattern specified at call-time to exclude specified sub-directories and files, and returns the modified container.
:::note When working with private Git repositories, ensure that SSH authentication is properly configured on your Dagger host. :::
:::note This is an example of post-call filtering with directory filters. :::
<Tabs groupId="language"> <TabItem value="Go">Copy the current host directory to /src in the container, excluding all sub-directories and files starting with dagger, and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container, excluding all Markdown files, and list the contents of the directory:
Copy the private user/foo GitHub repository to /src in the container, excluding all Markdown files, and list the contents of the directory:
Request the README.md file from the public dagger/dagger GitHub repository over HTTPS, save it as /src/myfile in the container, and return the container:
Request the README.md file from the public dagger/dagger GitHub repository over HTTPS, save it as /src/myfile in the container, and display its contents:
The following Dagger Function accepts a File argument and copies the specified file to the Dagger module runtime container. This makes it possible to add one or more files to the runtime container and manipulate them using custom logic.
Copy the data.json host file to the runtime container and process it:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'copy-file ../data.json'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
copy-file ../data.json
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call copy-file --source=../data.json
```
</TabItem>
</Tabs>
The following Dagger Function accepts a Directory argument, which could reference either a directory from the local filesystem or a remote Git repository. It copies the specified directory to the /src path in a container, using pre-defined filter patterns to exclude specified sub-directories and files, and returns the modified container.
:::note When working with private Git repositories, ensure that SSH authentication is properly configured on your Dagger host. :::
:::note This is an example of pre-call filtering with directory filters. :::
<Tabs groupId="language"> <TabItem value="Go">Copy the specified host directory to /src in the container, excluding everything except Markdown files, and return the modified container:
Copy the public dagger/dagger GitHub repository to /src in the container, excluding everything except Markdown files, and list the contents of the /src directory in the container:
The following Dagger module uses a constructor to set a module-wide Directory argument and point it to a default path on the host. This eliminates the need to pass a common Directory argument individually to each Dagger Function in the module. If required, the default path can be overridden by specifying a different Directory value at call time.
Call the Dagger Function without arguments. The default path (the current directory .) is used:
Call the Dagger Function with a constructor argument. The specified directory (/src/myapp) is used:
The following Dagger Function performs a multi-stage build.
<Tabs groupId="language"> <TabItem value="Go">Perform a multi-stage build of the source code in the golang/example/hello repository and publish the resulting image:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/golang/example#master:hello'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/golang/example#master:hello
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --src="https://github.com/golang/example#master:hello"
```
</TabItem>
</Tabs>
The following Dagger Function performs a matrix build.
<Tabs groupId="language"> <TabItem value="Go">Perform a matrix build of the source code in the golang/example/hello repository and export build directory with go binaries for different operating systems and architectures.
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/golang/example#master:hello | export /tmp/matrix-builds'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/golang/example#master:hello | export /tmp/matrix-builds
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call \
build --src="https://github.com/golang/example#master:hello" \
export --path=/tmp/matrix-builds
```
</TabItem>
</Tabs>
Inspect the contents of the exported directory with tree /tmp/matrix-builds. The output should look like this:
/tmp/matrix-builds
└── build
├── darwin
│ ├── amd64
│ │ └── hello
│ └── arm64
│ └── hello
└── linux
├── amd64
│ └── hello
└── arm64
└── hello
8 directories, 4 files
The following Dagger Function builds a single image for different CPU architectures using native emulation.
<Tabs groupId="language"> <TabItem value="Go">Build and publish a multi-platform image:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/golang/example#master:hello'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/golang/example#master:hello
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --src="https://github.com/golang/example#master:hello"
```
</TabItem>
</Tabs>
The following Dagger Function builds a single image for different CPU architectures using cross-compilation.
:::info
This Dagger Function uses the containerd utility module. To run it locally
install the module first with dagger install github.com/levlaz/daggerverse/[email protected]
:::
Build and publish a multi-platform image with cross compliation:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/golang/example#master:hello'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/golang/example#master:hello
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --src="https://github.com/golang/example#master:hello"
```
</TabItem>
</Tabs>
The following Dagger Function builds an image from a Dockerfile.
<Tabs groupId="language"> <TabItem value="Go">Build and publish an image from an existing Dockerfile
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/dockersamples/python-flask-redis'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/dockersamples/python-flask-redis
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --src="https://github.com/dockersamples/python-flask-redis"
```
</TabItem>
</Tabs>
The following function builds an image from a Dockerfile with a build context that is different than the current working directory.
<Tabs groupId="language"> <TabItem value="Go">Build an image from the source code in https://github.com/dockersamples/python-flask-redis using the Dockerfile from a different build context, at https://github.com/vimagick/dockerfiles#master:registry-cli/Dockerfile:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build https://github.com/dockersamples/python-flask-redis https://github.com/vimagick/dockerfiles#master:registry-cli/Dockerfile'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build https://github.com/dockersamples/python-flask-redis https://github.com/vimagick/dockerfiles#master:registry-cli/Dockerfile
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call \
build --src="https://github.com/dockersamples/python-flask-redis" \
--dockerfile=https://github.com/vimagick/dockerfiles#master:registry-cli/Dockerfile
```
</TabItem>
</Tabs>
The following Dagger Function adds OpenContainer Initiative (OCI) annotations to an image.
<Tabs groupId="language"> <TabItem value="Go">Build and publish an image with OCI annotations:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c build
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build
```
</TabItem>
</Tabs>
The following Dagger Function adds OpenContainer Initiative (OCI) labels to an image.
<Tabs groupId="language"> <TabItem value="Go">Build and publish an image with OCI labels:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c build
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build
```
</TabItem>
</Tabs>
The following function demonstrates how to invalidate the Dagger layer cache and force execution of subsequent pipeline steps, by introducing a volatile time variable at a specific point in the Dagger pipeline.
:::note
Print the date and time, invalidating the cache on each run. However, if the CACHEBUSTER environment variable is removed, the same value (the date and time on the first run) is printed on every run.
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c build
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build
```
</TabItem>
</Tabs>
The following Dagger Function accepts a GitHub personal access token as a Secret, and uses the Secret to authorize a request to the GitHub API. The secret may be sourced from the host (via an environment variable, host file, or host command) or from an external secrets manager (1Password or Vault):
Use a secret sourced from an environment variable:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'github-api env://GITHUB_API_TOKEN' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github-api env://GITHUB_API_TOKEN ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call github-api --token=env://GITHUB_API_TOKEN ``` </TabItem> </Tabs>Use a secret sourced from a file:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'github-api file://./github.txt' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github-api file://./github.txt ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call github-api --token=file://./github.txt ``` </TabItem> </Tabs>Use a secret sourced from a command:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'github-api cmd://"gh auth token"' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github-api cmd://"gh auth token" ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call github-api --token=cmd://"gh auth token" ``` </TabItem> </Tabs>Use a secret from 1Password:
:::note
If using a 1Password service account, ensure that the OP_SERVICE_ACCOUNT_TOKEN environment variable is set.
export OP_SERVICE_ACCOUNT_TOKEN="mytoken"
:::
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'github-api op://infra/github/credential' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github-api op://infra/github/credential ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call github-api --token=op://infra/github/credential ``` </TabItem> </Tabs>Use a secret from Vault:
:::note
Ensure that the VAULT_ADDR and either the VAULT_TOKEN or VAULT_APPROLE_ROLE_ID (for Vault AppRole authentication) environment variables are set.
export VAULT_ADDR="https://127.0.0.1:8200"
export VAULT_TOKEN="gue55me7"
export VAULT_APPROLE_ROLE_ID="roleid-xxx-yyy-zzz"
:::
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'github-api vault://credentials.github' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github-api vault://credentials.github ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call github-api --token=vault://credentials.github ``` </TabItem> </Tabs>The following Dagger Function accepts a GitHub hosts configuration file as a Secret, and mounts the file as a Secret to a container to authorize a request to GitHub.
Use a mounted secret file:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'github-auth file://$HOME/.config/gh/hosts.yml'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
github-auth file://$HOME/.config/gh/hosts.yml
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call github-auth --gh-creds=file://$HOME/.config/gh/hosts.yml
```
</TabItem>
</Tabs>
The following code listing demonstrates how to inject a secret into a Dockerfile build. The secret is automatically mounted in the build container at /run/secrets/SECRET-ID.
The sample Dockerfile below demonstrates the process of mounting the secret using a secret filesystem mount type and using it in the Dockerfile build process:
FROM alpine:3.17
RUN apk add curl
RUN --mount=type=secret,id=gh-secret \
curl "https://api.github.com/repos/dagger/dagger/issues" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer $(cat /run/secrets/gh-secret)"
Build from a Dockerfile with a mounted secret from the host environment:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build . env://GITHUB_API_TOKEN'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build . env://GITHUB_API_TOKEN
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --source=. --secret=env://GITHUB_API_TOKEN
```
</TabItem>
</Tabs>
The first Dagger Function below creates and returns an HTTP service. This service is bound and used from a different Dagger Function, via a service binding using an alias like www.
Send a request from one Dagger Function to a bound HTTP service instantiated by a different Dagger Function:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c get
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
get
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call get
```
</TabItem>
</Tabs>
The Dagger Function below creates and returns an HTTP service. This service can be used from the host.
<Tabs groupId="language"> <TabItem value="Go">Expose the HTTP service instantiated by a Dagger Function to the host on the default port:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'http-service | up' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." http-service | up ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call http-service up ``` </TabItem> </Tabs>Access the service from the host:
curl localhost:8080
Expose the HTTP service instantiated by a Dagger Function to the host on a different host port:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'http-service | up --ports 9000:8080' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." http-service | up --ports 9000:8080 ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call http-service up --ports 9000:8080 ``` </TabItem> </Tabs>Access the service from the host:
curl localhost:9000
The following Dagger Function accepts a Service running on the host, binds it using an alias, and creates a client to access it via the service binding. This example uses a MariaDB database service running on host port 3306, aliased as db in the Dagger Function.
:::note This implies that a service is already listening on a port on the host, out-of-band of Dagger. :::
<Tabs groupId="language"> <TabItem value="Go">Send a query to the database service listening on host port 3306 and return the result as a string:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'user-list tcp://localhost:3306'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
user-list tcp://localhost:3306
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call user-list --svc=tcp://localhost:3306
```
</TabItem>
</Tabs>
The following Dagger Function creates a service and binds it to an application container for unit testing. In this example, the application being tested is Drupal. Drupal includes a large number of unit tests, including tests which depend on an active database service. This database service is created on-the-fly by the Dagger Function.
<Tabs groupId="language"> <TabItem value="Go">Run Drupal's unit tests, instantiating a database service during the process:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c test
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
test
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call test
```
</TabItem>
</Tabs>
The following Dagger Function demonstrates how to control a service's lifecycle by explicitly starting and stopping a service. This example uses a Redis service.
<Tabs groupId="language"> <TabItem value="Go">Start and stop a Redis service:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c redis-service
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
redis-service
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call redis-service
```
</TabItem>
</Tabs>
The following Dagger Function runs two services, service A and service B, that depend on each other. The services are set up with custom hostnames, svca and svcb, allowing each service to communicate with the other by hostname.
Start two inter-dependent services:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'services | up --ports 8080:80'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
services | up --ports 8080:80
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call services up --ports 8080:80
```
</TabItem>
</Tabs>
The following Dagger Function publishes a just-in-time container image to a private registry.
<Tabs groupId="language"> <TabItem value="Go">Publish a just-in-time container image to Docker Hub, using the account username user and the password set in the PASSWORD environment variable:
Publish a just-in-time container image to GitHub Container Registry, using the account username user and the GitHub personal access token set in the PASSWORD environment variable:
The following Dagger Function tags a just-in-time container image multiple times and publishes it to a private registry.
<Tabs groupId="language"> <TabItem value="Go">Tag and publish a just-in-time container image to Docker Hub, using the account username user and the password set in the PASSWORD environment variable:
Tag and publish a just-in-time container image to GitHub Container Registry, using the account username user and the GitHub personal access token set in the PASSWORD environment variable:
The following Dagger Functions return a just-in-time directory and file. These outputs can be exported to the host with dagger call ... export ....
Export the directory returned by the Dagger Function to the /home/admin/export path on the host:
Export the file returned by the Dagger Function to the /home/admin/myfile path on the host:
The following Dagger Function returns a just-in-time container. This can be exported to the host as an OCI tarball.
<Tabs groupId="language"> <TabItem value="Go">Export the container image returned by the Dagger Function as an OCI tarball to the /home/admin/mycontainer.tgz path on the host. This OCI tarball can then be loaded into Docker with docker load ....
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'base | export /home/admin/mycontainer.tgz'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
base | export /home/admin/mycontainer.tgz
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call base export --path=/home/admin/mycontainer.tgz
```
</TabItem>
</Tabs>
The following Dagger Function uses a cache volume for application dependencies. This enables Dagger to reuse the contents of the cache across Dagger Function runs and reduce execution time.
<Tabs groupId="language"> <TabItem value="Go">:::note
The default location for the cache directory depends on the package manager (~/.cache/pip for pip or ~/.cache/pypoetry for poetry).
:::
Build an application using cached dependencies:
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'build .'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
build .
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call build --source=.
```
</TabItem>
</Tabs>
The following Dagger Function demonstrates how to set a single environment variable in a container.
<Tabs groupId="language"> <TabItem value="Go">The following Dagger Function demonstrates how to set multiple environment variables in a container.
<Tabs groupId="language"> <TabItem value="Go">Set a single environment variable in a container:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c set-env-var ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." set-env-var ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call set-env-var ``` </TabItem> </Tabs>Set multiple environment variables in a container:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c set-env-vars ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." set-env-vars ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call set-env-vars ``` </TabItem> </Tabs>The following Dagger Function uses a cache volume to persist a Redis service's data across Dagger Function runs.
<Tabs groupId="language"> <TabItem value="Go">Save data to a Redis service which uses a cache volume to persist a key named foo with value `123:
Retrieve the value of the key foo after recreating the service state from the cache volume:
The following Dagger Function demonstrates how to use native-language concurrency features (errgroups in Go, task groups in Python), and promises in TypeScript to execute other Dagger Functions concurrently. If any of the concurrently-running functions fails, the remaining ones will be immediately cancelled.
<Tabs groupId="language"> <TabItem value="Go">Execute a Dagger Function which performs different types of tests by executing other Dagger Functions concurrently.
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c 'my-module $(host | directory .) | run-all-tests'
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
my-module $(host | directory .) | run-all-tests
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call --source=. run-all-tests
```
</TabItem>
</Tabs>
The following Dagger Function demonstrates how to handle errors in a pipeline.
<Tabs groupId="language"> <TabItem value="Go">Execute a Dagger Function which creates a container and runs a command in it. If the command fails, the error is captured and the Dagger Function is gracefully terminated with a custom error message.
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c test
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
test
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call test
```
</TabItem>
</Tabs>
The following Dagger Function demonstrates how to continue using a container after a command executed within it fails. A common use case for this is to export a report that a test suite tool generates.
:::note The caveat with this approach is that forcing a zero exit code on a failure caches the failure. This may not be desired depending on the use case. :::
<Tabs groupId="language"> <TabItem value="Go">Continue executing a Dagger Function even after a command within it fails. The Dagger Function returns a custom TestResult object containing a test report and the exit code of the failed command.
Obtain the exit code:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'test | exit-code' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." test | exit-code ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call test exit-code ``` </TabItem> </Tabs>Obtain the report:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c 'test | report | contents' ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." test | report | contents ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call test report contents ``` </TabItem> </Tabs>Dagger provides two features that can help greatly when trying to debug a pipeline - opening an interactive terminal session at the failure point, or at explicit breakpoints throughout your pipeline code. All context is available at the point of failure. Multiple terminals are supported in the same Dagger Function; they will open in sequence.
The following Dagger Function opens an interactive terminal session at different stages in a Dagger pipeline to debug a container build.
<Tabs groupId="language"> <TabItem value="Go">Execute a Dagger Function to build a container, and open an interactive terminal at two different points in the build process. The interactive terminal enables you to inspect the container filesystem and environment "live", during the build process.
<Tabs groupId="shell">
<TabItem value="System shell">
```shell
dagger -c container
```
</TabItem>
<TabItem value="Dagger Shell">
```shell title="First type 'dagger' for interactive mode."
container
```
</TabItem>
<TabItem value="Dagger CLI">
```shell
dagger call container
```
</TabItem>
</Tabs>
The following Dagger Function clones Dagger's GitHub repository and opens an interactive terminal session to inspect it. Under the hood, this creates a new container (defaults to alpine) and starts a shell, mounting the repository directory inside.
The container created to mount the directory can be customized using additional options. The following Dagger Function revised the previous example to demonstrate this, using an ubuntu container image and bash shell instead of the defaults.
Execute a Dagger Function to clone Dagger's GitHub repository and open a terminal session in the repository directory:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger -c simple-directory ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." simple-directory ``` </TabItem> <TabItem value="Dagger CLI"> ```shell dagger call simple-directory ``` </TabItem> </Tabs>Execute another Dagger Function that does the same as the previous one, except using an ubuntu container image as base and initializing the terminal with the bash shell: