Start Kestra using a single Docker container.


Once you have Docker running, you can start Kestra in a single command (if you're running on Windows, make sure to use WSL):

bash
docker run --pull=always --rm -it -p 8080:8080 --user=root -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp kestra/kestra:latest server local

Open http://localhost:8080 in your browser to launch the UI and start building your first flows.

Configuration

Using a configuration file

You can adjust Kestra's configuration using a file mounted to the Docker container as a bind volume.

First, create a configuration .yml file like the example below:

yaml
datasources:
  postgres:
    url: jdbc:postgresql://postgres:5432/kestra
    driverClassName: org.postgresql.Driver
    username: kestra
    password: k3str4
kestra:
  server:
    basicAuth:
      enabled: false
      username: "[email protected]" # It must be a valid email address
      password: kestra
  repository:
    type: postgres
  storage:
    type: local
    local:
      basePath: "/app/storage"
  queue:
    type: postgres
  tasks:
    tmpDir:
      path: "/tmp/kestra-wd/tmp"
  url: "http://localhost:8080/"

After creating the configuration file, update the command to mount the file to the container and start Kestra. We also adjust the Kestra command to start a standalone version, as we now have a PostgreSQL database as a backend.

bash
docker run --pull=always --rm -it -p 8080:8080 --user=root \
 -v $PWD/application.yaml:/etc/config/application.yaml \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /tmp:/tmp kestra/kestra:latest server standalone --config /etc/config/application.yaml

Using the KESTRA_CONFIGURATION environment variable

You can adjust the Kestra configuration by passing the KESTRA_CONFIGURATION variable to the Docker container via the -e option. This environment variable must be a valid YAML string.

Managing a large configuration via a single YAML string can be tedious. To simplify this, consider using a configuration file instead.

First, define an environment variable:

bash
export KESTRA_CONFIGURATION=$'
datasources:
  postgres:
    url: jdbc:postgresql://postgres:5432/kestra
    driverClassName: org.postgresql.Driver
    username: kestra
    password: k3str4
kestra:
  server:
    basicAuth:
      enabled: false
      username: "[email protected]" # it must be a valid email address
      password: kestra
  repository:
    type: postgres
  storage:
    type: local
    local:
      basePath: "/app/storage"
  queue:
    type: postgres
  tasks:
    tmpDir:
      path: /tmp/kestra-wd/tmp
  url: http://localhost:8080/'

Once configured, pass the KESTRA_CONFIGURATION environment variable in a Docker command and adjust the Kestra command to run the standalone server:

bash
docker run --pull=always --rm -it -p 8080:8080 --user=root \
 -e KESTRA_CONFIGURATION="$KESTRA_CONFIGURATION" \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /tmp:/tmp kestra/kestra:latest server standalone

Official Docker images

The official Kestra Docker images are available on DockerHub for both linux/amd64 and linux/arm64 platforms.

We provide two image variants:

  • kestra/kestra:*
  • kestra/kestra:*-no-plugins

Both variants are based on the eclipse-temurin:21-jre Docker image.

The kestra/kestra:* images include all Kestra plugins in their latest versions. The kestra/kestra:*-no-plugins images do not contain any plugins. We recommend using the kestra/kestra:* version to take advantage of all the available plugins in your flows.

Docker image tags

We provide the following tags for each Docker image (append -no-plugins to any image to exclude all but Kestra core plugins):

  • latest: The most recent stable release (rolling tag). Intended for trying new features; not an LTS. Support ends when the next stable release (~ 2 months) becomes available.
  • latest-lts: The current Long-Term Support (rolling tag). Tracks the active LTS line (updates roughly every 6 months to the new LTS) and receives fixes for ~1 year.
  • v<X.X>: Minor-series floating tag (e.g., v1.0) that always points to the latest patch of that series (e.g., v1.0.5). Use v<X.X> when you want automatic patch updates but to stay on a minor line.
  • v<X.X.X>: Immutable tag for an exact version (e.g., v1.0.1). Never changes; best for locked-down production.
  • develop: Nightly/continuous build from the develop branch. Unstable and not recommended for production, only for testing.

The default Kestra image kestra/kestra:latest already includes all plugins. To use a lightweight version of Kestra without plugins, add the suffix *-no-plugins.

For production deployments, we recommend one of the following:

Latest stable version for staying most up to date while also stable (make note that this is a rolling tag that changes quite frequently):

  • kestra/kestra:latest — latest stable with all plugins
  • kestra/kestra:latest-no-plugins — latest stable without plugins

Pinned versions for maximum stability:

  • kestra/kestra:v<X.X.X> — all plugins included
  • kestra/kestra:v<X.X.X>-no-plugins — no bundled plugins, only core to Kestra

LTS rolling tag if you want automatic updates within the LTS line:

  • kestra/kestra:latest-lts
  • kestra/kestra:latest-lts-no-plugins

For development or testing new features:

  • kestra/kestra:latest — latest stable with all plugins
  • kestra/kestra:latest-no-plugins — latest stable without plugins
  • kestra/kestra:develop / kestra/kestra:develop-no-plugins — daily builds with unreleased features, unstable

Build a custom Docker image

If the base or full image doesn't contain package dependencies you need, you can build a custom image by using the Kestra base image and adding the required binaries and dependencies.

Add custom binaries

The following Dockerfile creates a new image from the Kestra base image and adds the golang binary along with Python packages:

dockerfile
ARG IMAGE_TAG=latest
FROM kestra/kestra:$IMAGE_TAG

RUN mkdir -p /app/plugins && \
  apt-get update -y && \
  apt-get install -y --no-install-recommends golang && \
  apt-get install -y pip && \
  pip install pandas==2.0.3 requests==2.31.0 && \
  apt-get clean && rm -rf /var/lib/apt/lists/* /var/tmp/*

Add plugins to a Docker image

By default, the base Docker image kestra/kestra:latest contains all plugins (unless you use the kestra/kestra:latest-no-plugins version). You can add specific plugins to the base image and build a custom image.

The following Dockerfile creates an image from the base image and adds the plugin-notifications, storage-gcs and plugin-gcp binaries using the command kestra plugins install:

dockerfile
ARG IMAGE_TAG=latest-no-plugins
FROM kestra/kestra:$IMAGE_TAG

RUN /app/kestra plugins install \
  io.kestra.plugin:plugin-notifications:LATEST \
  io.kestra.storage:storage-gcs:LATEST \
  io.kestra.plugin:plugin-gcp:LATEST

Add custom plugins to a Docker image

The above Dockerfile installs plugins that have already been published to Maven Central. If you are developing a custom plugin, make sure to build it following our plugin developer guide. Once the shadowJar is built, add it to the plugins directory:

dockerfile
ARG IMAGE_TAG=latest
FROM kestra/kestra:$IMAGE_TAG

RUN mkdir -p /app/plugins

COPY /build/libs/*.jar /app/plugins

Add custom plugins from a Git repository

If you would like to build custom plugins from a specific Git repository, you can use the following approach:

dockerfile
FROM openjdk:17-slim as stage-build
WORKDIR /
USER root

RUN apt-get update -y
RUN apt-get install git -y && \
    git clone https://github.com/kestra-io/plugin-aws.git

RUN cd plugin-aws && ./gradlew :shadowJar

FROM kestra/kestra:latest

# https://github.com/WASdev/ci.docker/issues/194#issuecomment-433519379
USER root

RUN mkdir -p /app/plugins && \
  apt-get update -y && \
  apt-get install -y --no-install-recommends golang && \
  apt-get install -y pip && \
  pip install pandas==2.0.3 requests==2.31.0 && \
  apt-get clean && rm -rf /var/lib/apt/lists/* /var/tmp/*

RUN rm -rf /app/plugins/plugin-aws-*.jar
COPY --from=stage-build /plugin-aws/build/libs/plugin-aws-*.jar /app/plugins

This multi-stage Docker build allows you to override a plugin that has already been installed. In this example, the AWS plugin is by default already included in the kestra/kestra:latest image. However, it's overridden by a plugin built in the first Docker build stage.

Was this page helpful?