Builds

When you deploy or build your application a "build" artifact is created. This consists of the Docker images that make up your application plus metadata stored in your Rack's database. Each build has a unique ID and is associated with one or more Releases.

Builds can either be created:

  • Manually from the CLI. convox build will create your build artifact, whereas convox deploy will create the artifact and also then promote the subsequent release.
  • As part of a Convox workflow. Workflows can connect to your code repository and initiate builds and subsequent activities from code pushes or pull requests.
  • As part of an external CI process. Convox has a CircleCI Orb as well as a set of Github Actions for integration. Other CI services can also integrate with Convox by installing the Convox CLI in your CI environment, utilising deploy keys to keep your credentials secure, and running the build or deploy commands as appropriate in your CI workflow.

You can see a list of all the builds for your App by running convox builds from the CLI.

$ convox builds
ID           STATUS    RELEASE      STARTED      ELAPSED  DESCRIPTION
BBLTITAIGHI  complete  ROCHMCOUESG  1 week ago   2m46s    build 7329df90c1 this is my commit message
BNNJBWFAWYJ  complete  RVUGSLANDXU  2 weeks ago  1m19s
BPNRIHAOQGM  failed                 2 weeks ago  11s
BRMUBCYGSWH  complete  RIHVPQXQWSR  3 weeks ago  1m8s

Creating a Build

Build your application by running convox build from the top-level directory:

$ convox build

When you run this command the following steps are executed:

  • The Convox CLI builds a tarball from all the files in your project (except the ones specified in .dockerignore)
  • The CLI uploads the tarball to your Rack
  • The Rack extracts the tarball and reads convox.yml
  • Docker images are built or pulled as specified by convox.yml
  • The images are tagged and pushed into your Rack's private Amazon ECR registry
  • Build metadata is saved to the Rack
  • A new Release is created from the build and its metadata is saved too

The newly created release will not be promoted (made active) until you run convox releases promote <release ID>.

If you'd like to build your App and promote the release in a single step, you can run convox deploy rather than convox build.

Inspecting Builds

Run convox builds info <build ID> to view metadata for a particular build.

Run convox builds logs <build ID> to view the logs for a particular build.

Moving Builds

It's possible to export a build from one App and import it to another App, even if the Apps are on different Racks.

To move a build, first export it:

$ convox builds export <build ID> -a <appname> > build.tgz

You can then import the build into another app, even on a different Rack:

$ convox builds import -a <appname> < build.tgz

You can even pipe these commands together directly:

$ convox builds export <build ID> -a <app1> -r <rack1> | convox builds import -a <app2> -r <rack2>

Build Options

The convox build and convox deploy commands accept several flags to customize the build process.

Flag Description
--build-args KEY=VALUE Pass Docker build arguments. Can be specified multiple times.
--description, -d Set a description for the Build and its Release. Defaults to the current git commit message.
--development Create a development Build. When set, the build automatically targets a Dockerfile stage named development (via --target development) if one exists.
--manifest, -m Specify an alternate manifest file (default: convox.yml).
--no-cache Build without using the Docker layer cache.
--wildcard-domain Enable wildcard domain support for the Release created from this Build. Adds *.<app>-<service>.<rack-host> listener rules and provisions a wildcard ACM certificate.

Build arguments

Convox also respects the ARG Dockerfile directive. For more information, see Dockerfile: ARG.

Build Cache

The --no-cache flag described above controls the Docker layer cache local to a single build host. Convox also supports a persistent build-layer cache that survives across builds. Layers produced by one build are stored in a dedicated ECR repository and reused by later builds, so unchanged Dockerfile stages do not have to be rebuilt each time. This is enabled at the Rack level, not per Build.

Enable the persistent cache by setting the BuildCache parameter on your Rack:

$ convox rack params set BuildCache=Yes

When BuildCache=Yes, Convox creates an ECR repository named {rack}-build-cache and points the builder at it. Cached layers are written to and read from that repository on subsequent builds. The cache works with both BuildMethod values:

  • On ec2 builds, the builder uses the Docker buildx plugin to push and pull a registry cache.
  • On fargate builds, the builder uses Kaniko with a remote cache repository.

Fargate caching is less aggressive than EC2 caching, so the speedup on Fargate builds is smaller. The buildx plugin used for EC2 caching is included in the default Convox build image, so EC2 caching works as soon as BuildCache=Yes is set. If you replace the build image with the BuildImage parameter and your image does not include buildx, the build logs print a warning and the build proceeds without the persistent cache.

Setting --no-cache on an individual convox build or convox deploy disables reuse of cached layers for that Build. On Fargate builds the persistent cache is skipped entirely. On EC2 builds the build does not read from the cache, but freshly built layers are still written back to the cache repository.

Expiring old cache images

By default the cache repository keeps every layer image indefinitely. Two companion parameters control automatic cleanup:

Parameter Default Effect
BuildCacheCleanup No When Yes, applies an ECR lifecycle policy that expires old cache images.
BuildCacheRetentionDays 30 Days to retain cache images before expiry (1 to 365). Only applies when BuildCacheCleanup=Yes.

Enable cleanup and set a retention window in a single call:

$ convox rack params set BuildCacheCleanup=Yes BuildCacheRetentionDays=14

When BuildCacheCleanup=No, cache images are never expired and the repository grows over time.

Generation 1 Apps

Gen1 Apps do not use the persistent build cache. They continue to build with the local Docker layer cache only, and no cache repository is provisioned for them even when BuildCache=Yes is set on the Rack.

See Also