Skip to main content
Version: 6.x (Latest)

Image Building with DevSpace

DevSpace can build images using a variety of build engines.

Do Not Build Images During Development

Because image building can waste a lot of time and slows down developers, we recommend that you only build images when running DevSpace in your CI/CD pipelines using devspace build/deploy but not when a developer runs devspace dev.

Instead of image building, use the following workflow for devspace dev:

  1. Deploy your application using prod/stable images
  2. Use the devImage feature to swap out the prod/stable images in runtime using a prebuilt dev-optimized image.
  3. Use the sync feature for hot reloading your containers

Building Images

1. Define Images

In build images with DevSpace, we need to add them to the images section of devspace.yaml:

devspace.yaml
version: v2beta1
images:
api:
image: ghcr.io/loft-sh/devspace-example-api
payments:
image: ghcr.io/loft-sh/devspace-example-payments
dockerfile: ./payments/Dockerfile
context: ./payments/
auth:
image: ghcr.io/loft-sh/devspace-example-auth
dockerfile: ./auth/Dockerfile
context: ./auth/
target: production
buildArgs:
SOME_ARG: "value"
ANOTHER_ARG: "some other value"

The example above defines 3 images:

  • api with Dockerfile in ./Dockerfile and build context in ./ (default values)
  • payments with Dockerfile in ./payments/Dockerfile and build context in ./payments/
  • auth with Dockerfile in ./auth/Dockerfile and build context in ./auth/
    Additionally, the image auth also defines a few buildArgs and a build target for multi-stage builds.

2. Call build_images in Pipeline

DevSpace builds images when the build_image function is called within pipelines as shown in this example:

devspace.yaml
version: v2beta1
pipelines:
build: |-
build_images --all
build-api: |-
build_images api
build-ordered: |-
build_images auth
build_images api payments

images:
api: ... # see example above
payments: ... # see example above
auth: ... # see example above

3. Run Pipeline

Given the example above, you can now run:

  • devspace build to build all 3 images in parallel
  • devspace run-pipeline build-api to build only the image named api
  • devspace run-pipeline build-ordered to
    1. First build the image auth (blocking)
    2. Then build the images api and payments in parallel

Build Configuration

DevSpace lets you customize the build process for each image using the following config fields:

Build Configuration

dockerfile required string ./Dockerfile

Dockerfile specifies a path (relative or absolute) to the dockerfile. Defaults to ./Dockerfile.

context required string ./

Context is the context path to build with. Defaults to the current working directory

buildArgs required <buildArg_name>:string

BuildArgs are the build args that are to the build

target required string

Target is the target that should get used during the build. Only works if the dockerfile supports this

network required string

Network is the network that should get used to build the image

rebuildStrategy required string default default
always
ignoreContextChanges

RebuildStrategy is used to determine when DevSpace should rebuild an image. By default, devspace will rebuild an image if one of the following conditions is true:

  • The dockerfile has changed
  • The configuration within the devspace.yaml for the image has changed
  • A file within the docker context (excluding .dockerignore rules) has changed This option is ignored for custom builds.

buildArgs

Your Dockerfile can use the ARG instruction to define arguments that will be used in other build instructions as this example shows:

Dockerfile
ARG  JDK_VERSION=17
FROM maven:3-openjdk-${JDK_VERSION}-slim

By default, this Dockerfile uses maven:3-openjdk-7-slim as base image but you can pass the build arg JDK_VERSION to change this dynamically.

There are two options to provide build args in devspace.yaml:

1. Setting buildArgs in the images section

devspace.yaml
version: v2beta1
images:
auth:
image: ghcr.io/loft-sh/devspace-example-auth
buildArgs:
JDK_VERSION: 8
ANOTHER_ARG: "some other value"

2. Calling build_images with the --set flag to dynamically add or override the buildArgs at runtime

devspace.yaml
version: v2beta1
pipelines:
build: |-
build_images --set buildArgs.JDK_VERSION=11 --set "buildArgs.SOME_ARG_NAME=some value"
images:
auth:
image: ghcr.io/loft-sh/devspace-example-auth

target For Multi-Stage Builds

Some Dockerfiles contain multiple FROM instructions that define build stages optionally using the AS <stage-name> suffix as shown below:

Dockerfile
FROM golang:1.17-bullseye AS builder
ADD . /go/src/app
RUN go build -o /go/bin/app

FROM gcr.io/distroless/base-debian11
COPY --from=builder /go/bin/app /
CMD ["/app"]

Without defining a build target, DevSpace (just like Docker and most other build engines) would build the entire image. However, for developerment, you may not want to use the fully built image because in this case it is a distroless container that only contains the final Go binary but no development tooling, not even sh to be able to open a terminal inside the container via devspace enter.

If you want the image building process to only build the builder stage (line 1-4), then you have two options to pass a build target:

1. Setting target in the images section

devspace.yaml
version: v2beta1
images:
auth:
image: ghcr.io/loft-sh/devspace-example-auth
target: builder

2. Calling build_images with the --set flag to dynamically add or override the target at runtime

devspace.yaml
version: v2beta1
pipelines:
build: |-
build_images auth --set target=builder
images:
auth:
image: ghcr.io/loft-sh/devspace-example-auth

Dockerfile Overwrites

DevSpace provides several config options to make in-memory changes to the build process without the need to change your Dockerfile:

In-Memory Overwrites

entrypoint required string[]

Entrypoint specifies an entrypoint that will be appended to the dockerfile during image build in memory. Example: ["sleep", "99999"]

cmd required string[]

Cmd specifies the arguments for the entrypoint that will be appended during build in memory to the dockerfile

appendDockerfileInstructions required string[]

AppendDockerfileInstructions are instructions that will be appended to the Dockerfile that is build at the current build target and are appended before the entrypoint and cmd instructions

Rebuild Strategy

By default, DevSpace tries to skip building images as much as possible. Once any of your images is built once, DevSpace will only rebuild it if one of the conditions is true:

  • The dockerfile has changed
  • Any file within the build context folder has changed (while respecting .dockerignore rules)
  • The image configuration within the devspace.yaml has changed (including values set in the pipeline scripe, e.g. via --set)
  • The image was not been built before or the .devspace/ folder has been deleted/manipulated

You can explicitly override this behavior using the rebuildStrategy field:

rebuildStrategy required string default default
always
ignoreContextChanges

RebuildStrategy is used to determine when DevSpace should rebuild an image. By default, devspace will rebuild an image if one of the following conditions is true:

  • The dockerfile has changed
  • The configuration within the devspace.yaml for the image has changed
  • A file within the docker context (excluding .dockerignore rules) has changed This option is ignored for custom builds.

You can also set the rebuildStrategy during runtime using the --set flag:

devspace.yaml
version: v2beta1
pipelines:
build: |-
build_images auth --set rebuildStrategy=always
.devspace/ Folder

DevSpace stores the information about each previously built image inside the .devspace/ folder within your project. Do not commit this folder via git. It should always be listed in .gitignore.

--skip-build Flag

If you call devspace [dev/deploy/build/run-pipeline] using the --skip-build flag, DevSpace will skip any build_images instructions defined in your pipeline script.

Parallel vs Sequential Builds

When calling build_images --all or build_images [image1] [image2], DevSpace builds all specified images in parallel.

To execute image building sequentially, call build_images multiple times as shown below:

devspace.yaml
version: v2beta1
pipelines:
build: |-
build_images auth
build_images api payments

images:
api: ... # see example above
payments: ... # see example above
auth: ... # see example above