»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:

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

»Build Methods

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

You can also create a plugin to extend Waypoint with your own builder.

»Choosing How to Build Your App

»Docker Build

Example configuration

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 it should work well the Waypoint Docker plugin.

Reference the Docker plugin for all configuration options.

»Docker Pull Build

Example configuration

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

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

Cloud Native Buildpacks 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.

»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 repository for more examples of this model.The Procfile syntax is web: <server process> <server file>. A sample Procfile with this syntax is below:

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

ProviderBuilder Image
Herokuheroku/buildpacks:18
Paketopaketobuildpacks/builder:base
Google Cloud Platformgcr.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.
  2. 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:

project = "example-java"

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

GCP buildpacks example waypoint.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.

»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

...
    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.

»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.