Image Building with DevSpace
DevSpace can build images using a variety of build engines.
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
:
- Deploy your application using prod/stable images
- Use the
devImage
feature to swap out the prod/stable images in runtime using a prebuilt dev-optimized image. - 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
:
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 imageauth
also defines a fewbuildArgs
and a buildtarget
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:
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 paralleldevspace run-pipeline build-api
to build only the image namedapi
devspace run-pipeline build-ordered
to- First build the image
auth
(blocking) - Then build the images
api
andpayments
in parallel
- First build the image
Build Configuration
DevSpace lets you customize the build process for each image using the following config fields:
dockerfile
required string ./Dockerfile
Dockerfile specifies a path (relative or absolute) to the dockerfile. Defaults to ./Dockerfile.
dockerfile
required string ./Dockerfile context
required string ./
Context is the context path to build with. Defaults to the current working directory
context
required string ./ buildArgs
required <buildArg_name>:string
BuildArgs are the build args that are to the build
buildArgs
required <buildArg_name>:string target
required string
Target is the target that should get used during the build. Only works if the dockerfile supports this
target
required string network
required string
Network is the network that should get used to build the image
network
required string 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.
rebuildStrategy
required string default defaultalways
ignoreContextChanges
buildArgs
Your Dockerfile can use the ARG
instruction to define arguments that will be used in other build instructions as this example shows:
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
buildArgs
in the images
sectionversion: 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
build_images
with the --set
flag to dynamically add or override the buildArgs
at runtimeversion: 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:
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
target
in the images
sectionversion: 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
build_images
with the --set
flag to dynamically add or override the target
at runtimeversion: 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:
entrypoint
required string[]
Entrypoint specifies an entrypoint that will be appended to the dockerfile during
image build in memory. Example: ["sleep", "99999"]
entrypoint
required string[] cmd
required string[]
Cmd specifies the arguments for the entrypoint that will be appended
during build in memory to the dockerfile
cmd
required string[] 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
appendDockerfileInstructions
required string[] 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.
rebuildStrategy
required string default defaultalways
ignoreContextChanges
You can also set the rebuildStrategy
during runtime using the --set
flag:
version: v2beta1
pipelines:
build: |-
build_images auth --set rebuildStrategy=always
.devspace/
FolderDevSpace 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:
version: v2beta1
pipelines:
build: |-
build_images auth
build_images api payments
images:
api: ... # see example above
payments: ... # see example above
auth: ... # see example above