---
layout: docs
page_title: 'Lifecycle: Build'
description: |-
  Waypoint build lifecycle documentation
---

# Build

A **build** takes application source and converts it to an _artifact_.

An artifact is the packaged form of an application required for deployment on
your target platform: a container image, VM image, or maybe a simple zip file.
The build process may also include an optional **push** operation to push
the built artifact to a registry so that it is available for the deployment
platform.

A build is triggered during a `waypoint up` or using the dedicated
`waypoint build` command.

## Configuration

The build is configured using the `build` stanza within an `app` stanza:

```hcl
app "my-app" {
  build {
    use "docker" {}
  }
}
```

### Build Methods

Waypoint includes these builtin plugins to build a Docker image for your app.

- [Docker Build](/plugins/docker#docker-builder)
- Docker Pull Build
- [Cloud Native Buildpacks](/plugins/pack)

You can also create a [plugin](/plugins) to extend Waypoint with your own builder.

### Choosing How to Build Your App

#### Docker Build

**Example configuration**

```hcl
app "my-app" {
  build {
    use "docker" {}
  }
}
```

The Docker plugin leverages the application `Dockerfile` to create a container
image. If you application works with the `docker build`
[Docker command](https://docs.docker.com/engine/reference/commandline/build/)
it should work well the Waypoint Docker plugin.

Reference the [Docker plugin](/plugins/docker) for all configuration options.

#### Docker Pull Build

**Example configuration**

```hcl
app "my-app" {
  build {
    use "docker-pull" {
      image = "hashicorp/http-echo"
      tag   = "latest"
    }
  }
  deploy {
    use "docker" {
      command = ["-listen", ":3000","-text", "hello"]
    }
  }
}
```

The Docker Pull plugin is ideal when you prefer to use an existing Docker image as-is
without rebuilding it.
This plugin performs a `docker pull`. The plugin injects the Waypoint Entrypoint by
default, which can be disabled.

#### Cloud Native Buildpacks

**Example configuration**

```hcl
app "my-app" {
  build {
    use "pack" {}
  }
}
```

[Cloud Native Buildpacks](https://buildpacks.io/) are a fast way to get started
creating a containerized application without writing a `Dockerfile`. Buildpacks
take application source and build a container for you if there are matching
buildpacks. The "pack" plugin defaults to Heroku Buildpacks with a builder image
located on Docker Hub at
[heroku/buildpacks:18](https://hub.docker.com/r/heroku/buildpacks/tags).

#### Customizing the Buildpack Launch Command

When using the default Heroku Buildpack, you can customize the command that
starts your server process within the workload. This is done by using
adding a `Procfile` to the project directory.

An example of this model in practice would be the build process generating
the static binaries for your web service within your application image, and
then executing the necessary commands to start ExpressJS to host those static files.

See the [waypoint-examples](https://github.com/hashicorp/waypoint-examples)
repository for more examples of this model. The `Procfile` syntax
is `web: <server process> <server file>`. A sample Procfile with this syntax is below:

```bash
web: node server.js
```

You will need to include a file that can be executed by a server
process (`server.js` above) in order to use this capability.

The ability to use a Procfile is dependent on the Buildpack provider. This capability
can be added to alternative buildpack providers, however you will need to build your
own builder image and store it in an accessible repository. Please see the Buildpack
provider's documentation for further details around this capability.

#### Configuring an Alternative Buildpack Provider

| Provider              | Builder Image                 |
| --------------------- | ----------------------------- |
| Heroku                | heroku/buildpacks:18          |
| Paketo                | paketobuildpacks/builder:base |
| Google Cloud Platform | gcr.io/buildpacks/builder:v1  |

Several `waypoint.hcl` adjustments may be required to enable alternative builders.

1. The `builder` variable of the `pack` build plugin should explicitly specify the
   buildpacks builder image like `paketobuildpacks/builder:base`.
1. The `service_port` variable of the deploy plugin must match the buildpacks port.
   Paketo buildpacks commonly use `8080` and the default Waypoint `service_port` is `3000`.

Paketo buildpacks example `waypoint.hcl`:

```hcl
project = "example-java"

app "example-java" {
    build {
        use "pack" {
            builder="paketobuildpacks/builder:base"
        }
    }
    deploy {
        use "docker" {
            service_port=8080
        }
    }
}
```

GCP buildpacks example `waypoint.hcl`:

```hcl
project = "example-java"

app "example-java" {
    build {
        use "pack" {
            builder="gcr.io/buildpacks/builder:v1"
        }
    }
    deploy {
        use "docker" {}
    }
}
```

#### Buildpack Troubleshooting

If you have a problem using Cloud Native Buildpacks, try using the `pack` CLI
directly with Docker
[similar to this example](https://buildpacks.io/docs/app-journey/).

## Registry

A build may optionally specify a registry to push the built artifact to.
This is sometimes required so that the build artifact is accessible to the
deployment platform.

If a registry is specified, the deployment step will use the artifact
in the registry. If a registry is not specified, the deployment step will
use the artifact that is the result of the build.

Example Docker Registry Configuration

```hcl
...
    build {
        use "docker" {}
        registry {
          use "docker" {
            image = "registry.example.com/image"
            tag   = "latest"
          }
        }
    }
...
```

Reference `aws-ecs` plugin documentation for an [AWS Elastic Container Registry example](/plugins/aws-ecs#examples).

### Scenarios for a Registry

**An example of a scenario requiring a registry:** Kubernetes deployments
need access to the Docker image that is built, but a Docker build process often
produces a local Docker image. The registry configuration is used to push
the locally built Docker image to the remote registry.

**An example of a scenario that does not require a registry:** AMIs (Amazon
Machine Images) are registered directly with Amazon and are never local
artifacts. Therefore, a separate registry configuration is not required since
the build/registry phases are one and the same.

### Private Registries

When using the docker plugin to push images to private container registries, the
registry authentication may either be configured explicitly or "out of band"
from Waypoint.

#### Explicit Authentication

Create a file with the registry authentication:

```json
{
  "username": "YOURUSERNAME",
  "password": "YOURPASSWORD",
  "email": "YOUREMAIL@EXAMPLE.COM"
}
```

Reference the file in `waypoint.hcl`:

```hcl
...
    build {
        use "docker" {}
          registry {
            use "docker" {
              image = "registry.example.com/image"
              tag = "latest"
              encoded_auth = filebase64("/path/to/dockerAuth.json")
            }
          }
        }
    }
...
```

#### Out of Band Authentication

Waypoint invokes Docker APIs, so if you have authentication configured with
`docker login` or similar, then Waypoint does not need to authenticate directly
to the private registry. Here is an example:

```shell
cat /path/to/mysecret | docker login registry.example.com -u USERNAME --password-stdin
```

where `/path/to/mysecret` is a file with your secret as contents and `USERNAME`
is replaced with your actual registry username. Therefore Waypoint does not need
to know the private registry credentials since it invokes the Docker API, which
is configured with the private registry credentials. Here is an example
`waypoint.hcl` registry configuration when relying on Docker's authentication:

```hcl
...
    build {
        use "docker" {}
        registry {
          use "docker" {
            image = "registry.example.com/image"
            tag = "latest"
          }
        }
    }
...
```

#### Platforms and Private Registries

Reference [Deploy Private Registry
documentation](/docs/lifecycle/deploy#private-registries) for details on how to
configure deployment for private registries.
