Hooks
DevSpace allows you to define certain actions that should be executed during the pipeline. This makes it possible to customize the deployment and development process with DevSpace. The following actions can be executed with hooks:
- Execute a command on the local machine (in a golang shell or directly on the system)
- Execute a command in a container
- Upload a file or folder into a container
- Download a file or folder from a container
- Wait for a container to start or terminate
- Print the logs of container
Hooks can be defined in the hooks
section of devspace.yaml
:
hooks:
# Execute the hook in a golang shell (cross operating system compatible)
- name: "pre-image-build-hook"
command: "echo before image building"
events: ["before:build"]
# Execute the hook in a golang shell (cross operating system compatible)
- name: "post-image-build-hook"
command: |
echo Built Image image(image-1):tag(image-1)
events: ["after:build:image-1"]
# Execute the hook directly on the system (echo binary must exist)
- command: "echo"
args: ["before image building"]
events: ["before:build:image-1", "before:build:image-2"]
# Execute the hook only on windows
- command: "echo before each image"
os: windows
events: ["before:build:*"]
This tells DevSpace to execute the command echo before image building
before any image will be built.
Lifecycle Events
You are able to define hooks for the following lifecycle events:
before:deploy
,after:deploy
,before:deploy:[name]
,after:deploy:[name]
,error:deploy:[name]
,skip:deploy:[name]
: executed while DevSpace deploysdeployments
.[name]
can be replaced with the config name of a deployment or*
to match all.before:render
,after:render
,before:render:[name]
,after:render:[name]
,error:render:[name]
: executed while DevSpace rendersdeployments
duringdevspace render
.[name]
can be replaced with the config name of a deployment or*
to match all.before:purge
,after:purge
,before:purge:[name]
,after:purge:[name]
,error:purge:[name]
: executed while DevSpace purgesdeployments
duringdevspace purge
.[name]
can be replaced with the config name of a deployment or*
to match all.before:build
,after:build
,before:build:[name]
,after:build:[name]
,error:build:[name]
,skip:build:[name]
: executed while DevSpace buildsimages
.[name]
can be replaced with the config name of an image or*
to match all.start:sync:[name]
,stop:sync:[name]
,error:sync:[name]
,restart:sync:[name]
,before:initialSync:[name]
,after:initialSync:[name]
,error:initialSync:[name]
: executed while DevSpace syncs files withdev.sync
.[name]
can be replaced with the config name of a sync configuration or*
to match all.start:portForwarding:[name]
,restart:portForwarding:[name]
,error:portForwarding:[name]
,stop:portForwarding:[name]
: executed while DevSpace port forwards withdev.ports
.[name]
can be replaced with the config name of a port forwarding configuration or*
to match all.start:reversePortForwarding:[name]
,restart:reversePortForwarding:[name]
,error:reversePortForwarding:[name]
,stop:reversePortForwarding:[name]
: executed while DevSpace reverse port forwards withdev.ports
.[name]
can be replaced with the config name of a port forwarding configuration or*
to match all.before:createPullSecrets
,after:createPullSecrets
,error:createPullSecrets
: executed while DevSpace createspullSecrets
If any hook returns a non-zero exit code, DevSpace will abort and print an error message.
For error:
events the actual error will be passed to the hook via the environment variable DEVSPACE_HOOK_ERROR
. For example:
# This will print the error to the console that has occured during a deployment
hooks:
- events: ["error:deploy:*"]
command: "echo The following error has occurred during deploying $DEVSPACE_HOOK_DEPLOY_NAME: $DEVSPACE_HOOK_ERROR"
os: darwin,windows
name: "error-hook"
Execute hooks in a container
DevSpace allows you to execute commands directly in a container instead of the local system. You can specify this in the container
section of the hook:
...
hooks:
- command: |
echo Hello World!
echo From within the container!
container:
imageSelector: nginx
# Or select via labelSelector etc.
# labelSelector: ...
# namespace: ...
# containerName: ...
# pod: ...
events: ["after:deploy:my-deployment"]
...
By default, DevSpace will wait for all pods / containers that were selected with the given selector to come up. As soon as all targets are running, DevSpace will execute the hook and wait for it to finish. You can define if DevSpace should wait and how long it should wait with wait
and timeout
:
...
hooks:
- command: "echo"
args: ["Hello from within the container!"]
container:
imageSelector: image(app):tag(app)
# Or select via labelSelector etc.
# labelSelector: ...
# namespace: ...
# containerName: ...
# pod: ...
wait: true # This is the default
timeout: 300 # Timeout in seconds
events: ["after:deploy:my-deployment"]
...
Upload or Download files from a container
Hooks can be used to upload or download files from a container. In the background, DevSpace will basically do a kubectl cp
to the specified container. Example:
hooks:
# Upload the complete local bin folder to the container path ./bin
- upload:
localPath: bin
containerPath: bin
container:
imageSelector: image(test):tag(test)
events: ["after:deploy:my-deployment"]
name: "upload-hook"
# Download a single file from the container to the local path
- download:
localPath: build/artifact.jar
containerPath: /abs/path/build/artifact-test.jar
container:
imageSelector: image(java):tag(java)
events: ["after:deploy:my-deployment-2"]
name: "download-hook"
Wait for a pod to be running
This hook action can be useful if you want to ensure a certain pod is running before you continue with the pipeline. An example configuration could look like this:
...
deployments:
my-database:
helm:
chart:
name: component-chart
repo: https://charts.devspace.sh
values:
...
hooks:
# This hook will ensure that every time the deployment
# my-database is deployed that DevSpace will wait until
# all pods and containers that match the labelSelector
# app.kubernetes.io/component: my-database are running
- wait:
# DevSpace will wait for all containers that match the label selector below to become running.
# If there are init containers, make sure to set terminatedWithCode as well.
running: true
# This can be needed if there are for example init containers
# that terminate instead of become running.
terminatedWithCode: 0
container:
labelSelector:
app.kubernetes.io/component: my-database
# You could also select just a specific container with
# containerName: database-container
events: ["after:deploy:my-database"]
name: "wait-for-pod-hook"
...
Print the logs of a container
This action can be useful to print logs of jobs or print the logs of init containers that would not be printed otherwise during devspace dev
. An example configuration could look like this:
job.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app.kubernetes.io/component: my-job
spec:
restartPolicy: Never
containers:
- command: ["sh"]
args: ["-c", "echo 'Job Start' && sleep 5 && echo 'Doing Things...' && sleep 5 && echo 'Job End'"]
image: alpine
name: job
devspace.yaml
:
version: ...
deployments:
my-job:
kubectl:
manifests:
- job.yaml
hooks:
# This hook will wait until the selected container is either running or already
# terminated and then print the logs of it until it terminates.
- logs: {}
container:
labelSelector:
app.kubernetes.io/component: my-job
events: ["after:deploy:my-job"]
name: "print-logs-hook"
Execute hooks in the background
By default, DevSpace will wait for a hook to finish and then move on with the pipeline. However, in some cases it might be desired that a hook is executed in the background to speed up a process. You can specify a background hook with the background
option:
...
hooks:
- command: "sh"
args: ["-c", "sleep 10 && echo 'Hello, I was run inside the background!'"]
background: true
events: ["after:deploy"]
name: "background-hook"
...
If you do not want to stream the output of the hook to the console, you can also mark the hook as silent, which will prevent any hook output:
...
hooks:
- command: "sh"
args: ["-c", "sleep 10 && echo 'Hello, I was run inside the background!'"]
background: true
silent: true
events: ["after:deploy"]
name: "silent-background-hook"
...
Execute hooks only on certain operating systems
Hooks can be executed only on certain operating systems:
hooks:
- command: echo before image building on windows
os: windows
events: ["after:build"]
name: windows-hook
- command: echo before image building on mac and linux
os: darwin,linux
events: ["after:build"]
name: darwin-linux-hook
Execute hooks once
Hooks can be executed only once for each targeted container. This means as long as the container where the hook was executed stays running, the hook will not be executed for this container again until it restarts. This can be useful for running one-time development tasks without using init containers. In the following example, the command would only run once for the newest container running with the image nginx:1.21
.
...
hooks:
- command: |
echo Hello World!
echo From within the container!
container:
imageSelector: nginx:1.21
once: true
events: ["after:deploy"]
name: one-time-hook
...
If you run devspace dev
or devspace deploy
now multiple times and the container is not replaced or restarted, the hook is only executed once.
Hook Context Information
DevSpace passes certain environment variables to the hook execution:
- DEVSPACE_HOOK_KUBE_CONTEXT: the name of the kube context that was used
- DEVSPACE_HOOK_KUBE_NAMESPACE: the name of the kube namespace that was used
- DEVSPACE_HOOK_OS_ARGS: json encoded os.Args that were used to call devspace
- DEVSPACE_HOOK_ERROR: if an error has occured contains the error string (only for onError hooks)
- DEVSPACE_HOOK_EVENT: the event that has triggered the hook
Depending on the hook there will be other context variables set that are prefixed with DEVSPACE_HOOK_
.
Config Reference
hooks
required object[]
Hooks are actions that are executed at certain points within the pipeline. Hooks are ordered and are executed
in the order they are specified. They are deprecated and pipelines should be used instead.
hooks
required object[] name
required string
Name is the name of the hook
name
required string disabled
required boolean false
Disabled can be used to disable the hook
disabled
required boolean false events
required string[]
Events are the events when the hook should be executed
events
required string[] command
required string
Command is the base command that is either executed locally or in a remote container.
Command is mutually exclusive with other hook actions. In the case this is defined
together with where.container, DevSpace will until the target container is running and
only then execute the command. If the container does not start in time, DevSpace will fail.
command
required string args
required string[]
Args are additional arguments passed together with the command to execute.
args
required string[] os
required string
If an operating system is defined, the hook will only be executed for the given os.
All supported golang OS types are supported and multiple can be combined with ','.
os
required string upload
required
If Upload is specified, DevSpace will upload certain local files or folders into a
remote container.
upload
required download
required
Same as Upload, but with this option DevSpace will download files or folders from
a remote container.
download
required logs
required
If logs is defined will print the logs of the target container. This is useful for containers
that should finish like init containers or job pods. Otherwise this hook will never terminate.
logs
required tailLines
required integer
If set, the number of lines from the end of the logs to show. If not specified,
logs are shown from the creation of the container
tailLines
required integer wait
required
If wait is defined the hook will wait until the matched pod or container is running or is terminated
with a certain exit code.
wait
required running
required boolean false
If running is true, will wait until the matched containers are running. Can be used together with terminatedWithCode.
running
required boolean false terminatedWithCode
required integer
If terminatedWithCode is not nil, will wait until the matched containers are terminated with the given exit code.
If the container has exited with a different exit code, the hook will fail. Can be used together with running.
terminatedWithCode
required integer timeout
required integer
The amount of seconds to wait until the hook will fail. Defaults to 150 seconds.
timeout
required integer background
required boolean false
If true, the hook will be executed in the background.
background
required boolean false silent
required boolean false
If true, the hook will not output anything to the standard out of DevSpace except
for the case when the hook fails, where DevSpace will show the error including
the captured output streams of the hook.
silent
required boolean false container
required
Container specifies where the hook should be run. If this is omitted DevSpace expects a
local command hook.
container
required labelSelector
required <labelSelector_name>:string
LabelSelector to select a container
labelSelector
required <labelSelector_name>:string pod
required string
Pod name to use
pod
required string namespace
required string
Namespace to use
namespace
required string imageSelector
required string
ImageSelector to select a container
imageSelector
required string containerName
required string
ContainerName to use
containerName
required string wait
required boolean false
Wait can be used to disable waiting
wait
required boolean false timeout
required integer 150
Timeout is how long to wait (in seconds) for the container to start. Default is 150 seconds.
timeout
required integer 150 once
required boolean false
Once only executes an hook once in the container until it is restarted
once
required boolean false