Deploy Kestra
Orchestration platform for data, AI, and infrastructure workflows
kestra-scheduler
Just deployed
kestra-webserver
Just deployed
kestra-worker
Just deployed
Just deployed
/var/lib/postgresql/data
kestra-executor
Just deployed
kestra-storage
Bucket
Just deployed
Deploy and Host Kestra on Railway
Kestra is an open-source orchestration platform that runs declarative YAML workflows on a schedule, on an event, or through its API. Teams adopt it as an Apache Airflow and Astronomer alternative because a flow is a versionable YAML file, not a Python DAG, so one workflow can chain a shell script, a Python job, a SQL query and any of Kestra's 1,900+ plugins. The Apache 2.0 core lets you self-host Kestra with no seat or execution limits.
Self-host Kestra on Railway in the distributed topology upstream documents for production. Six services deploy together: kestra-webserver serves the UI and REST API on the public domain, kestra-executor drives orchestration logic and flow triggers, kestra-scheduler evaluates schedules, and kestra-worker runs the tasks. Managed Postgres is the JDBC backend holding the queue and the repository; a managed object storage bucket is Kestra's internal storage. All four Kestra services build from one public repo, gridalpha/kestra-railway, wrapping kestra/kestra:v1.3.33 and taking each role from a single KESTRA_COMPONENT variable. There are no volumes: the shared bucket is the storage.

Getting Started with Kestra on Railway
Open the kestra-webserver domain once the deploy is green: you get a login page, not a setup wizard, because basic auth is mandatory in open-source Kestra and configured before first boot. Sign in with the KESTRA_BASIC_AUTH_USERNAME and KESTRA_BASIC_AUTH_PASSWORD you chose at deploy time — a valid email, and a password of 8+ characters with an uppercase letter and a digit. Flows already lists six tutorial flows loaded on first start — open one and click Execute for an end-to-end run. To write your own, choose Flows → Create and paste:
id: railway_deployment_check
namespace: company.team
tasks:
- id: shell
type: io.kestra.plugin.scripts.shell.Commands
commands:
- echo "user=$(whoami)" > inventory.txt
outputFiles:
- inventory.txt
Execute it, follow the run through the Gantt, Logs and Topology tabs, then download inventory.txt from Outputs — proof that shared storage works, since the worker wrote the file and the webserver, a different container, served it back. Unauthenticated, GET /ping returns pong while the API returns 401.

About Hosting Kestra
Kestra separates what runs from how it runs: you declare tasks, triggers, inputs and outputs in YAML, and the platform handles queuing, concurrency, retries and observability. Teams self-host it when workflows touch private databases or regulated data.
- Schedule, webhook, polling and flow triggers, plus a REST API for programmatic runs
- Python, Node.js, Shell and R scripts as first-class tasks that pass files between them
- 1,900+ plugins across AWS, GCP, Azure, Postgres, Kafka, dbt, Terraform, Slack and LLM providers
The Railway layout mirrors Kestra's own distributed deployment: the webserver is the only public service and runs the embedded indexer the JDBC backend needs, the executor and scheduler decide what runs, the worker runs it, and all four coordinate through Postgres.
Why Deploy Kestra on Railway
Railway removes the infrastructure work of self-hosting a distributed orchestrator.
- Managed Postgres and an object storage bucket are provisioned and wired automatically
- Each component scales on its own — add worker capacity without touching the UI tier
- Private networking between services; only the webserver is publicly exposed
- HTTPS domain, TLS certificates and health checks handled for you
Common Use Cases
- Scheduled ETL and ELT pipelines — pull from APIs and databases, transform with Python or dbt, load to a warehouse, with retries and backfills
- Event-driven automation — trigger flows from webhooks, message queues or file arrivals in S3-compatible storage
- AI and LLM workflows — chain prompts, embeddings and retrieval into observable runs
Dependencies for Kestra
- kestra-webserver —
gridalpha/kestra-railwaywrappingkestra/kestra:v1.3.33; public on 8080,/ping. UI, REST API, embedded indexer. - kestra-executor — same image, private,
/health. Orchestration logic and flow triggers. - kestra-scheduler — same image, private,
/health. Schedules and triggers. - kestra-worker — same image, private,
/health. Runs every runnable task. - Postgres — managed PostgreSQL 18.6: queue and repository, migrated on boot.
- kestra-storage — managed bucket for task outputs and namespace files.
Environment Variables Reference
| Variable | Description |
|---|---|
KESTRA_COMPONENT | Server role: webserver, executor, scheduler or worker |
KESTRA_BASIC_AUTH_USERNAME | Login email; must be a valid address |
KESTRA_BASIC_AUTH_PASSWORD | Login password; 8+ chars, one uppercase, one digit |
KESTRA_SECRET_SEED | Seed for the key encrypting stored secrets |
KESTRA_URL | Public base URL used in UI links and notifications |
KESTRA_WORKER_THREADS | Worker concurrency; defaults to 8× the CPU count |
Deployment Dependencies
- Source repo: gridalpha/kestra-railway, wrapping
kestra/kestrav1.3.33 - Upstream: kestra-io/kestra
- Docs: kestra.io/docs, kestra.io/plugins
Hardware Requirements for Self-Hosting Kestra
Kestra documents 4 GiB of memory and 2 vCPUs for a standalone server; split across components, the worker wants the headroom.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU total | 4+ vCPU, weighted toward the worker |
| RAM | 4 GB total | 8 GB+, roughly 2 GB per component |
| Storage | Postgres plus the bucket; no volumes | Grows with history and task outputs |
| Runtime | JVM 21, PostgreSQL 12+ | PostgreSQL 15+, storage in the same region |
Scale kestra-worker first — it does all the real compute — keep the scheduler at one replica, and cap concurrency with KESTRA_WORKER_THREADS.
Self-Hosting Kestra
The fastest local trial is one container with an embedded database. The Docker command:
docker run --rm -it -p 8080:8080 kestra/kestra:v1.3.33 server local
Anything persistent needs Postgres and object storage, which this template wires up. A Docker Compose equivalent:
services:
postgres:
image: postgres:18
environment: {POSTGRES_DB: kestra, POSTGRES_USER: kestra, POSTGRES_PASSWORD: change_me}
kestra:
image: kestra/kestra:v1.3.33
command: server standalone
ports: ["8080:8080"]
environment:
KESTRA_CONFIGURATION: |
datasources: {postgres: {url: jdbc:postgresql://postgres:5432/kestra, username: kestra, password: change_me}}
kestra: {repository: {type: postgres}, queue: {type: postgres}}
Script tasks default to the Docker task runner, which needs a Docker socket. Railway has none, so shell, Python and Node script tasks here use io.kestra.plugin.core.runner.Process inside the worker container; Python 3.12 ships in the image. Flow authorship is therefore privileged — anyone who writes a flow can run commands in the worker.
How Much Does Kestra Cost to Self-Host?
Kestra's core is free and open source under Apache 2.0, with unlimited workflows and executions and no per-user fee. Self-hosting costs infrastructure only: four containers, a Postgres database and an object storage bucket, billed on usage. Cloud and Enterprise editions add SSO, fine-grained permissions and audit logs — none of it needed here.
FAQ
What is Kestra? An open-source workflow orchestration platform: workflows are YAML flows of tasks and triggers, and Kestra schedules them, retries failures and records every execution with logs and a topology graph.
What does this Railway template deploy?
Kestra v1.3.33 as webserver, executor, scheduler and worker, plus managed PostgreSQL and a managed object storage bucket. All four Kestra services build from one public repository and differ only by KESTRA_COMPONENT.
Why does the template include Postgres and an object storage bucket? PostgreSQL is the JDBC backend — the message queue between components and the repository of flows and executions. The bucket is internal storage: every component reads the same task outputs, and a volume attaches to only one service.
How do I log in to a self-hosted Kestra instance?
With the email and password set as KESTRA_BASIC_AUTH_USERNAME and KESTRA_BASIC_AUTH_PASSWORD at deploy time. Basic auth is required in open-source Kestra, so you get a login screen rather than an open setup page.
Can I run Python and shell scripts in self-hosted Kestra on Railway?
Yes — script tasks use the Process runner inside the worker container and Python 3.12 is bundled in the image. Docker-in-Docker runners are unavailable, so use Process or a remote runner such as Kubernetes.
Template Content
kestra-scheduler
gridalpha/kestra-railwaykestra-webserver
gridalpha/kestra-railwaykestra-worker
gridalpha/kestra-railwaykestra-executor
gridalpha/kestra-railwaykestra-storage
Bucket