Quickstart
Build the application
If your application passes all its tests, the typical next step is to build it.
So, let's update the previous pipeline and add a build step to it, by running npm run build
.
The npm run build
command is appropriate for a React application, but other applications are likely to use different commands. Modify your Dagger pipeline accordingly.
package main
import (
"context"
"fmt"
"os"
"dagger.io/dagger"
)
func main() {
ctx := context.Background()
// initialize Dagger client
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr))
if err != nil {
panic(err)
}
defer client.Close()
// use a node:16-slim container
// mount the source code directory on the host
// at /src in the container
source := client.Container().
From("node:16-slim").
WithDirectory("/src", client.Host().Directory("."), dagger.ContainerWithDirectoryOpts{
Exclude: []string{"node_modules/", "ci/"},
})
// set the working directory in the container
// install application dependencies
runner := source.WithWorkdir("/src").
WithExec([]string{"npm", "install"})
// run application tests
test := runner.WithExec([]string{"npm", "test", "--", "--watchAll=false"})
// build application
// write the build output to the host
buildDir := test.WithExec([]string{"npm", "run", "build"}).
Directory("./build")
_, err = buildDir.Export(ctx, "./build")
if err != nil {
panic(err)
}
e, err := buildDir.Entries(ctx)
if err != nil {
panic(err)
}
fmt.Printf("build dir contents:\n %s\n", e)
}
- It invokes the
Container.WithExec()
method again, this time to define the commandnpm run build
in the container. - It obtains a reference to the
build/
directory in the container with theContainer.Directory()
method. This method returns aDirectory
object. - It writes the
build/
directory from the container to the host using theDirectory.Export()
method.
Run the pipeline by executing the command below from the application directory:
dagger run go run ci/main.go
import { connect } from "@dagger.io/dagger"
connect(
async (client) => {
// use a node:16-slim container
// mount the source code directory on the host
// at /src in the container
const source = client
.container()
.from("node:16-slim")
.withDirectory(
"/src",
client.host().directory(".", { exclude: ["node_modules/", "ci/", "build/"] })
)
// set the working directory in the container
// install application dependencies
const runner = source.withWorkdir("/src").withExec(["npm", "install"])
// run application tests
const test = runner.withExec(["npm", "test", "--", "--watchAll=false"])
// build application
// write the build output to the host
const buildDir = test.withExec(["npm", "run", "build"]).directory("./build")
await buildDir.export("./build")
const e = await buildDir.entries()
console.log("build dir contents:\n", e)
},
{ LogOutput: process.stderr }
)
This revised pipeline does everything described in the previous step, and then performs the following additional operations:
- It invokes the
Container.withExec()
method again, this time to define the commandnpm run build
in the container. - It obtains a reference to the
build/
directory in the container with theContainer.directory()
method. This method returns aDirectory
object. - It writes the
build/
directory from the container to the host using theDirectory.export()
method.
Run the pipeline by executing the command below from the application directory:
dagger run node ci/index.mjs
import sys
import anyio
import dagger
async def main():
config = dagger.Config(log_output=sys.stdout)
async with dagger.Connection(config) as client:
# use a node:16-slim container
# mount the source code directory on the host
# at /src in the container
source = (
client.container()
.from_("node:16-slim")
.with_directory(
"/src",
client.host().directory(
".", exclude=["node_modules/", "ci/", "build/"]),
)
)
# set the working directory in the container
# install application dependencies
runner = source.with_workdir("/src").with_exec(["npm", "install"])
# run application tests
test = runner.with_exec(["npm", "test", "--", "--watchAll=false"])
# build application
# write the build output to the host
build_dir = (
test.with_exec(["npm", "run", "build"])
.directory("./build")
)
await build_dir.export("./build")
e = await build_dir.entries()
print(f"build dir contents:\n{e}")
anyio.run(main)
This revised pipeline does everything described in the previous step, and then performs the following additional operations:
- It invokes the
Container.with_exec()
method again, this time to define the commandnpm run build
in the container. - It obtains a reference to the
build/
directory in the container with theContainer.directory()
method. This method returns aDirectory
object. - It writes the
build/
directory from the container to the host using theDirectory.export()
method.
Run the pipeline by executing the command below from the application directory:
dagger run python ci/main.py
After Dagger resolves the pipeline, the built application is available in a new build/
sub-directory of the application directory. Confirm this by executing the tree
command in the application directory, as shown below:
tree build
build/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── robots.txt
└── static
├── css
│ ├── main.073c9b0a.css
│ └── main.073c9b0a.css.map
└── js
├── 787.305db8b6.chunk.js
├── 787.305db8b6.chunk.js.map
├── main.5e49019b.js
├── main.5e49019b.js.LICENSE.txt
└── main.5e49019b.js.map
3 directories, 14 files