2021-06-09 16:27:24 +02:00
---
2021-07-16 18:37:29 +02:00
slug: /1003/get-started/
2021-06-09 16:27:24 +02:00
---
2021-09-24 23:43:22 +02:00
# Get Started with Dagger
2021-06-09 16:27:24 +02:00
2021-10-01 23:25:45 +02:00
In this tutorial, you will learn the basics of Dagger by building a Dagger project from scratch. This simple project deploys a [React ](https://reactjs.org/ ) application to your local machine via Docker. In later tutorials, you will learn how to configure Dagger to deploy to your infrastructure. And, for advanced users, how to share access to your infrastructure in the same way that we share access to ours now.
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
This tutorial does involve writing CUE, so if you haven’ t already, be sure to read [What is CUE? ](../introduction/1005-what_is_cue.md )
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
In this tutorial we will learn:
2021-06-16 18:50:38 +02:00
2021-09-24 23:43:22 +02:00
- How to initialize and structure a Dagger project
- About Dagger concepts such as
- the plan
- environments
- inputs and outputs
- How to write CUE for Dagger
- How to deploy an application using `dagger up`
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
## Deploy an Application Locally
2021-06-10 15:52:10 +02:00
2021-10-01 23:11:15 +02:00
The following instructions assume you are working locally, but could just as easily be run on a remote machine into which you have a shell.
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
### Install Dagger
2021-06-10 15:52:10 +02:00
2021-10-01 23:11:15 +02:00
First, make sure [you have installed Dagger ](../1001-install.md ). You can run `dagger version` to ensure you have the latest installed and working.
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
### Create a Dagger Project
2021-06-10 15:52:10 +02:00
2021-10-01 23:11:15 +02:00
First clone the [Dagger examples repository ](https://github.com/dagger/examples ), change directories to the `todoapp/` and list its contents:
> Note that all tutorials will operate from the todoapp directory.
```bash
git clone https://github.com/dagger/examples.git
cd examples/todoapp
ls -la
```
This React application will use Yarn to build a static website with the following directories and files.
```bash
-rw-r--r-- ... 794 Sep 7 10:09 package.json
drwxr-xr-x ... 256 Sep 7 10:09 public
drwxr-xr-x ... 192 Sep 29 11:17 src
-rw-r--r-- ... 465514 Sep 29 11:17 yarn.lock
```
2021-10-01 23:25:45 +02:00
Now we need to initialize this directory as a Dagger _project_ :
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
```bash
dagger init
2021-10-01 23:11:15 +02:00
ls -la
2021-06-10 15:52:10 +02:00
```
2021-10-01 23:11:15 +02:00
You will now see 2 new directories:
2021-06-10 15:52:10 +02:00
2021-10-01 23:11:15 +02:00
- The `.dagger` directory will store metadata about _environments_ , _inputs_ , and _outputs_ which we will cover later.
2021-09-24 23:43:22 +02:00
- The `cue.mod` directory stores libraries such as [dagger/universe ](https://github.com/dagger/universe ) which can be _imported_ into your Dagger _plan_ .
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
Dagger will load all `.cue` files recursively in the current Dagger project. More directories can be added to help organize code.
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
> Note that Dagger, like the CUE CLI command, will only load CUE files from the `cue.mod` directory in response to `import` statements.
2021-06-10 15:52:10 +02:00
2021-09-24 23:43:22 +02:00
### Write a Dagger Plan
2021-06-10 15:52:10 +02:00
2021-10-01 23:11:15 +02:00
A Dagger _plan_ is written in CUE and defines the _resources_ , _dependencies_ , and _logic_ to deploy an application to an environment. Unlike traditional glue code written in a scripting language such as Bash or PowerShell, a Dagger plan is _declarative_ rather than _imperative_ . This frees us from thinking about the order of operations, since Dagger will infer dependendencies and calculate correct order on its own.
2021-09-27 20:33:01 +02:00
2021-10-01 23:11:15 +02:00
Let's first create a directory to hold our plan separately from our application code:
2021-09-27 20:33:01 +02:00
2021-10-01 23:11:15 +02:00
```bash
mkdir -p ./plans/local
2021-09-27 20:33:01 +02:00
```
2021-10-01 23:11:15 +02:00
We will now create the following files:
- `plans/todoapp.cue` which will define resources common to all environments
- `plans/local/local.cue` which will define resources specific to the local environment
Create the file `plans/todoapp.cue` with the following content:
2021-09-27 20:33:01 +02:00
```cue
package todoapp
import (
2021-10-01 23:11:15 +02:00
"alpha.dagger.io/dagger"
"alpha.dagger.io/os"
"alpha.dagger.io/docker"
"alpha.dagger.io/js/yarn"
2021-09-27 20:33:01 +02:00
)
// Build the source code using Yarn
app: yarn.#Package & {
2021-10-01 23:11:15 +02:00
"source": dagger.#Artifact & dagger.#Input
}
2021-10-01 23:25:45 +02:00
// package the static HTML from yarn into a Docker image
2021-10-01 23:11:15 +02:00
image: os.#Container & {
image: docker.#Pull & {
from: "nginx"
}
2021-10-01 23:25:45 +02:00
// app.build references our app key above
// which infers a dependency that Dagger
// uses to generate the DAG
2021-10-01 23:11:15 +02:00
copy: "/usr/share/nginx/html": from: app.build
}
// push the image to a registry
push: docker.#Push & {
// leave target as a string here so that
// different environments can push to different registries
target: string
2021-10-01 23:25:45 +02:00
// the source of our push resource
// is the image resource we declared above
2021-10-01 23:11:15 +02:00
source: image
}
```
2021-10-01 23:25:45 +02:00
This file will define the resources and relationships between them that are common across _all environments_ . For example, here we are deploying to our local Docker engine in our `local` environment, but for staging or production as examples, we would deploy the same image to some other container orchestration system such as Kubernetes hosted somewhere out there among the various cloud providers.
2021-10-01 23:11:15 +02:00
Create the file `plans/local/local.cue` with the following content:
```cue
package todoapp
import (
"alpha.dagger.io/dagger"
"alpha.dagger.io/docker"
)
// run our todoapp in our local Docker engine
todoapp: docker.#Run & {
ref: push.ref
name: "todoapp"
ports: ["8080:80"]
socket: dagger.#Stream & dagger.#Input
2021-09-27 20:33:01 +02:00
}
2021-10-01 23:11:15 +02:00
// push to our local registry
push: target: "localhost:5000/todoapp"
2021-09-27 20:33:01 +02:00
```
2021-10-01 23:11:15 +02:00
Notice that both files have the same `package todoapp` declared on the first line. This is crucial to inform CUE that they are to be loaded and evaluated together in the same context.
2021-10-01 23:25:45 +02:00
Our `local.cue` file now holds resources specific to our `local` environment. Also notice that we are defining a concrete value for the `target` key here. The entire `push` object is defined in both files and CUE will merge the values into a single struct with key:value pairs that are _complete_ with concrete values.
2021-10-01 23:11:15 +02:00
2021-09-27 20:33:01 +02:00
### Create an Environment
2021-10-01 23:11:15 +02:00
Before we can deploy the plan, we need to define an environment which is the specific plan to execute, as well as the context from which inputs are pulled and to which state is stored.
2021-10-01 23:25:45 +02:00
For our each environment we need to tell Dagger what CUE files to load, so let’ s create a `local` environment:
2021-10-01 23:11:15 +02:00
2021-09-27 20:33:01 +02:00
```shell
2021-10-01 23:11:15 +02:00
dagger new local -p ./plans/local
2021-09-27 20:33:01 +02:00
dagger list
```
2021-10-01 23:11:15 +02:00
The `list` command shows the current environments defined:
```bash
local ...todoapp/.dagger/env/local
```
2021-09-27 20:33:01 +02:00
### Define Input Values per Environment
2021-10-01 23:25:45 +02:00
Our Dagger plan includes a number of references to `dagger.#Input` which inform the Dagger engine that the concrete value should be pulled from inputs. While some things such as the registry target we saw above can be expressed purely in CUE, others such as directories, secrets, and sockets are required to be explicitly defined as _inputs_ to protect against malicious code being injected by third-party packages. If Dagger allowed such things to be stated in CUE, the entire package system could become a source of attacks.
2021-10-01 23:11:15 +02:00
List the inputs Dagger is aware of according to our plan:
2021-09-27 20:33:01 +02:00
```shell
2021-10-01 23:11:15 +02:00
dagger -e local input list
2021-09-27 20:33:01 +02:00
```
2021-10-01 23:11:15 +02:00
You should see the following output:
```bash
Input Value Set by user Description
app.source dagger.#Artifact false Application source code
todoapp.socket struct false Mount local docker socket
2021-09-27 20:33:01 +02:00
```
2021-10-01 23:11:15 +02:00
Notice that `Set by user` is false for both, because we have not yet provided Dagger with those values.
Let’ s provide them now:
2021-09-27 20:33:01 +02:00
```shell
2021-10-01 23:11:15 +02:00
dagger -e local input socket todoapp.socket /var/run/docker.sock
dagger -e local input dir app.source ./
```
2021-10-01 23:25:45 +02:00
This defines the `todoapp.socket` as a `socket` input type, and the `app.source` input as a `dir` input type.
2021-10-01 23:11:15 +02:00
Now let's replay the `dagger input list` command:
```bash
Input Value Set by user Description
app.source dagger.#Artifact true Application source code
todoapp.socket struct true Mount local docker socket
```
Notice that Dagger now reports that both inputs have been set.
### Deploy the Appplication
2021-10-01 23:25:45 +02:00
With our plan in place, our environment set, and our inputs defined, we can deploy the application as simply as:
2021-10-01 23:11:15 +02:00
```bash
dagger up
```
Once complete you should get logs, and a final output like this:
```bash
Output Value Description
app.build struct Build output directory
push.ref "localhost:5000/todoapp:latest@sha256:< hash > " Image ref
push.digest "sha256:< hash > " Image digest
todoapp.ref "localhost:5000/todoapp:latest@sha256:< hash > " Image reference (e.g: nginx:alpine)
todoapp.run.env.IMAGE_REF "localhost:5000/todoapp:latest@sha256:< hash > " -
2021-09-27 20:33:01 +02:00
```
2021-10-01 23:11:15 +02:00
Congratulations! You’ ve deployed your first Dagger plan! You can now open [http://localhost:8080 ](http://localhost:8080 ) in your browser!