Kestra is language agnostic — you can use any programming language inside your workflows.
Kestra works with any programming language, with some having dedicated plugins and libraries that make it easier to send outputs and metrics back to Kestra.
Dedicated Plugins
Kestra currently supports the following programming languages with dedicated plugins:
Each of these plugins provides two task types:
- Commands: Execute scripts using a command-line interface (ideal for longer, pre-written files).
- Script: Write your code directly in YAML (best for short inline scripts).
Script example
An example of an inline Python script:
id: myflow
namespace: company.team
tasks:
- id: script
type: io.kestra.plugin.scripts.python.Script
beforeCommands:
- pip install requests kestra
script: |
from kestra import Kestra
import requests
response = requests.get('https://google.com')
print(response.status_code)
Kestra.outputs({'status': response.status_code, 'text': response.text})
Commands example
An example using Shell commands, similar to a terminal session:
id: myflow
namespace: company.team
tasks:
- id: commands
type: io.kestra.plugin.scripts.shell.Commands
outputFiles:
- first.txt
- second.txt
commands:
- echo "1" >> first.txt
- echo "2" >> second.txt
Run any language using the Shell task
With the Commands
task, you can execute arbitrary commands inside a Docker container. This means you can run any language, as long as:
- Its dependencies can be included in a Docker image.
- It can be executed from a Shell command.
For handling outputs and metrics, use the same ::{}::
syntax as the Shell
task.
Read more in Shell outputs and metrics.
Rust
Here is an example flow that runs a Rust file inside of a container using a rust
image:
id: rust
namespace: company.team
tasks:
- id: rust
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: rust:latest
namespaceFiles:
enabled: true
commands:
- rustc hello_world.rs
- ./hello_world
The Rust code is saved as a namespace file called hello_world.rs
:
fn main() {
println!("Hello, World!");
}
When executed, the print statement is displayed in the Kestra logs:
Check out the full guide which includes using outputs and metrics.
Java
You can build custom plugins in Java which enable you to add custom tasks to your workflows. If you're looking to execute something simpler, you can use the Shell
task with a Docker container.
Here is an example flow that runs a Java file inside of a container using a eclipse-temurin
image:
id: java
namespace: company.team
tasks:
- id: java
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: eclipse-temurin:latest
namespaceFiles:
enabled: true
commands:
- javac HelloWorld.java
- java HelloWorld
The Java code is saved as a namespace file called HelloWorld.java
:
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
When executed, the print statement is displayed in the Kestra logs:
C
Here is an example flow that runs a C file inside of a container using a gcc
image:
id: c
namespace: company.team
tasks:
- id: c
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: gcc:latest
namespaceFiles:
enabled: true
commands:
- gcc hello_world.c
- ./a.out
The C code is saved as a namespace file called hello_world.c
:
#include <stdio.h>
int main() {
printf("Hello, World!");
return 0;
}
When executed, the print statement is displayed in the Kestra logs:
C++
Here is an example flow that runs a C++ file inside of a container using a gcc
image:
id: cplusplus
namespace: company.team
tasks:
- id: cpp
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: gcc:latest
namespaceFiles:
enabled: true
commands:
- g++ hello_world.cpp
- ./a.out
The C++ code is saved as a namespace file called hello_world.cpp
:
#include <iostream>
int main() {
std::cout << "Hello World!";
return 0;
}
When executed, the print statement is displayed in the Kestra logs:
TypeScript
You can execute TypeScript using the NodeJS plugin. To do so, you need to install TypeScript and compile our code to JavaScript using tsc
.
Once done, you can then execute with NodeJS. However, do note that the file is now a .js
file.
id: typescript
namespace: company.team
tasks:
- id: ts
type: io.kestra.plugin.scripts.node.Commands
namespaceFiles:
enabled: true
commands:
- npm i -D typescript
- npx tsc example.ts
- node example.js
This example can be found in the Node.js docs. The file is saved as example.ts
.
type User = {
name: string;
age: number;
};
function isAdult(user: User): boolean {
return user.age >= 18;
}
const justine: User = {
name: 'Justine',
age: 23,
};
const isJustineAnAdult: boolean = isAdult(justine);
console.log(isJustineAnAdult)
When executed, the print statement is displayed in the Kestra logs:
For more information, you can read more about Node.js with TypeScript on their official site.
PHP
Here is an example flow that runs a PHP file inside of a container using a php
image:
id: php
namespace: company.team
tasks:
- id: php
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: php:8.4-rc-alpine
namespaceFiles:
enabled: true
commands:
- php hello_world.php
The PHP code is saved as a namespace file called hello_world.php
:
<?php
echo "Hello, World!";
?>
When executed, the print statement is displayed in the Kestra logs:
As of Kestra version 0.24, there is a dedicated PHP plugin. An example flow might look like the following using a script task:
id: php_script
namespace: company.team
tasks:
- id: script
type: io.kestra.plugin.scripts.php.Script
script: |
#!/usr/bin/php
<?php
echo "Hello, World!\\n";
?>
Check out the following example for the commands task:
id: php_commands
namespace: company.team
tasks:
- id: commands
type: io.kestra.plugin.scripts.php.Commands
inputFiles:
main.php: |
#!/usr/bin/php
<?php
echo "Hello, World!\\n";
?>
commands:
- php main.php
Scala
Here is an example flow that runs a Scala file inside of a container using a sbtscala/scala-sbt
image:
id: scala
namespace: company.team
tasks:
- id: scala
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: sbtscala/scala-sbt:eclipse-temurin-17.0.4_1.7.1_3.2.0
namespaceFiles:
enabled: true
commands:
- scalac HelloWorld.scala
- scala HelloWorld
The Scala code is saved as a namespace file called HelloWorld.scala
:
object HelloWorld {
def main(args: Array[String]) = {
println("Hello, World!")
}
}
When executed, the print statement is displayed in the Kestra logs:
Perl
Here is an example flow that runs a Perl file inside of a container using a perl
image:
id: perl
namespace: company.team
tasks:
- id: perl
type: io.kestra.plugin.scripts.shell.Commands
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
containerImage: perl:5.41.2
namespaceFiles:
enabled: true
commands:
- perl hello_world.pl
The Perl code is saved as a namespace file called hello_world.pl
:
#!/usr/bin/perl
use warnings;
print("Hello, World!\n");
When executed, the print statement is displayed in the Kestra logs:
As of Kestra version 0.24, there is a dedicated Perl plugin. An example flow might look like the following using a script task:
id: perl_inline
namespace: company.team
tasks:
- id: perl_script
type: io.kestra.plugin.scripts.perl.Script
script: |
my $message = "Hello from an inline Perl script!";
print $message . "\\n";
Check out the following example for the commands task:
id: perl_commands
namespace: company.team
tasks:
- id: perl
type: io.kestra.plugin.scripts.perl.Commands
commands:
- perl -e 'print "Hello from Kestra!
Run any language using a custom Docker image
You can pre-install any language using a custom Docker image and use the Process Task Runner to execute it. Example using Go:
FROM kestra/kestra:latest
USER root
# Install Go
RUN apt-get update -y && apt-get install -y wget && \
wget -qO- https://go.dev/dl/go1.24.3.linux-amd64.tar.gz | tar -C /usr/local -xzf - && \
echo 'export PATH=$PATH:/usr/local/go/bin' > /etc/profile.d/golang.sh
# Set Go environment variables for Docker
ENV PATH="/usr/local/go/bin:${PATH}"
Then, point to that Dockerfile in your docker-compose.yml
file:
services:
kestra:
build:
context: .
dockerfile: Dockerfile
image: kestra-go:latest
Once you start Kestra using docker compose up -d
, you can create a flow that directly runs Go tasks with your custom dependencies using the io.kestra.plugin.core.runner.Process
task runner:
id: golang_process
namespace: company.team
tasks:
- id: go_custom_dependencies
type: io.kestra.plugin.scripts.go.Script
taskRunner:
type: io.kestra.plugin.core.runner.Process
beforeCommands:
- go mod init go_script
- go get github.com/go-gota/gota/dataframe
- go mod tidy
script: |
package main
import (
"os"
"github.com/go-gota/gota/dataframe"
"github.com/go-gota/gota/series"
)
func main() {
names := series.New([]string{"Alice", "Bob", "Charlie"}, series.String, "Name")
ages := series.New([]int{25, 30, 35}, series.Int, "Age")
df := dataframe.New(names, ages)
file, _ := os.Create("output.csv")
df.WriteCSV(file)
defer file.Close()
}
outputFiles:
- output.csv
Was this page helpful?