---
title: "Deploy Windmill"
description: "Turn scripts into scheduled jobs, APIs and internal apps"
category: "Automation"
url: https://railway.com/deploy/windmill-automatio-1
---

# Deploy Windmill

Turn scripts into scheduled jobs, APIs and internal apps

**[Deploy Windmill on Railway](https://railway.com/template/windmill-automatio-1)**

- **Creator:** A3A
- **Category:** Automation
- **Total deploys:** 1

## Template content

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### windmill-server https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/windmill.svg

- **Source:** https://github.com/gridalpha/windmill-railway
- **Health check:** /api/version

### windmill-extra https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/windmill.svg

- **Source:** https://github.com/gridalpha/windmill-railway

### windmill-worker-native https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/windmill.svg

- **Source:** https://github.com/gridalpha/windmill-railway

### windmill-worker https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/windmill.svg

- **Source:** https://github.com/gridalpha/windmill-railway

### caddy https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/caddy.svg

- **Source:** https://github.com/gridalpha/windmill-railway
- **Health check:** /healthz
- **Public domain:** Yes

## Documentation

![Windmill logo](https://cdn-1.webcatalog.io/catalog/windmill/windmill-social-preview.png?v=1714777427857)

# Deploy and Host Windmill on Railway

Windmill is an open-source developer platform that turns ordinary scripts into production infrastructure. Write a function in Python, TypeScript, Go, Bash, PHP or plain SQL, and Windmill gives it an auto-generated input form, a REST endpoint, a webhook, a cron schedule, retries, logging and permissions — without you building any of it. Those scripts compose into multi-step flows with branching, loops and error handlers, and into internal apps. Teams reach for it when cron jobs have outgrown a single box, when Airflow is too heavy for a set of small tasks, and when a low-code tool like Zapier cannot express the logic they need. Every runnable is just code, so it stays reviewable and versioned.

Self-hosting Windmill takes more than one container, and this template wires up the shape upstream documents for production. A Caddy proxy holds the public domain and is the only service exposed to the internet. Behind it, the server runs the frontend, API and migrations; a general worker tier executes jobs in its own container; a native worker tier takes lightweight jobs so they never queue behind a slow Python build; an extra-services container supplies the editor's language servers and debugger; and Postgres holds all state, including the queue. No separate queue or cache is needed, and capacity grows by adding worker replicas or groups.

![Windmill server, workers, LSP gateway, Caddy and Postgres on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1787230590/windmill-architecture.png)

## Getting Started with Windmill on Railway

Open the public URL and you land on a sign-in screen. Windmill seeds one superadmin, `admin@windmill.dev`, and this template replaces the well-known default password with the value you set in `WM_ADMIN_PASSWORD`. Your first step is creating a workspace — everything in Windmill lives inside one. From the workspace home, click **New script** and pick a language; the editor gives you autocomplete backed by the language-server container. Give your `main` function typed arguments and Windmill builds an input form from them automatically — the feature that best explains the tool: your function's parameters become the UI. Deploy and run it, and the run page shows the inputs, the JSON result, the logs and the worker that picked the job up — confirmation that jobs execute on the worker tier, not the web server. The **Workers** page shows both groups reporting in; from there, attach a schedule or webhook trigger.

![Completed Windmill Python job showing its JSON result and logs](https://res.cloudinary.com/rroe4rtk/image/upload/v1787230592/windmill-job-result.png)
![Windmill script page with the input form generated from its parameters](https://res.cloudinary.com/rroe4rtk/image/upload/v1787230594/windmill-script-form.png)
![Windmill workers page listing the default and native worker groups](https://res.cloudinary.com/rroe4rtk/image/upload/v1787230599/windmill-worker-groups.png)

## About Hosting Windmill

Windmill sits between a job scheduler and an internal-tools builder. Self-hosting makes sense when your automations touch private databases, internal APIs or credentials you would rather not hand a SaaS vendor, and when per-task pricing looks expensive next to a server you run anyway.

Key features:

- Scripts in Python, TypeScript (Deno and Bun), Go, Bash, PHP, Rust, C# and direct SQL against Postgres, MySQL, BigQuery, Snowflake and DuckDB
- Auto-generated input forms and documented webhook endpoints for every script
- A flow editor with branching, for-loops, parallelism, retries and error handlers
- An app builder for internal dashboards backed by your own scripts
- Schedules, triggers, a secrets store, audit logs and role-based permissions
- Worker groups and tags, so heavy jobs run on their own machines

The Railway services map onto that cleanly. **Caddy** is the public entry point, splitting traffic by path between the extra-services container and the server. **windmill-server** answers the API, serves the UI and runs migrations. **windmill-worker** is the general execution tier and carries a volume for the dependency cache, so Python wheels and Go modules survive restarts. **windmill-worker-native** takes only lightweight jobs, keeping quick tasks fast while long builds occupy the general tier. **windmill-extra** supplies autocomplete, type checking and the debugger. **Postgres** stores scripts, flows, apps, secrets, run history and the queue.

## Why Deploy Windmill on Railway

Railway removes the operational work self-hosting Windmill usually implies:

- Private networking between server, workers and Postgres, no VPC to configure
- Managed Postgres with backups, so the queue and history are not your problem
- Worker replicas scale from the dashboard, not a compose file
- A persistent volume keeps the dependency cache across deploys
- HTTPS and a domain out of the box

## Common Use Cases

- **Internal automation:** nightly reports, SaaS-to-SaaS syncs, and provisioning routines needing branching and error handling
- **ETL and data pipelines:** pulling from APIs, transforming with Python or DuckDB, loading into a warehouse on a schedule
- **Internal tools:** small apps over your production database, with a backend your team can read
- **AI agent backends:** scripts exposed as webhooks or tools, secrets central, every run logged

## Dependencies for Windmill

- `ghcr.io/windmill-labs/windmill` — server and both worker tiers run this Community Edition image, switched by `MODE`
- `ghcr.io/windmill-labs/windmill-extra` — language servers, multiplayer and debugger behind one gateway
- `caddy:2-alpine` — path-based reverse proxy giving the deployment one origin
- Railway managed Postgres 18 — application state and the job queue

### Environment Variables Reference

| Variable | Service | Purpose |
|---|---|---|
| `DATABASE_URL` | server, workers | Postgres connection string, `?sslmode=disable` on the private network |
| `MODE` | server, workers | `server` or `worker` — the role the image starts in |
| `BASE_URL` | server | Public URL used in webhook links and emails |
| `WM_ADMIN_PASSWORD` | server | Password set on the seeded superadmin at first boot |
| `REQUIRE_SIGNED_DEBUG_REQUESTS` | extra | Keep `true`; `false` exposes an unauthenticated debugger |

### Deployment Dependencies

- Source and compose reference: [github.com/windmill-labs/windmill](https://github.com/windmill-labs/windmill)
- Self-hosting docs: [windmill.dev/docs/advanced/self_host](https://www.windmill.dev/docs/advanced/self_host)
- Script library: [hub.windmill.dev](https://hub.windmill.dev)

## Hardware Requirements for Self-Hosting Windmill

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU total | 4+ vCPU, ~1 per worker process |
| RAM | 2 GB | 4–8 GB; upstream suggests 1–2 GB per worker |
| Storage | 1 GB Postgres + 2 GB cache | 10 GB+ if jobs install big dependencies |
| Database | PostgreSQL 14+ | PostgreSQL 16 or newer |

## Self-Hosting Windmill with Docker

Upstream ships a compose file with the same shape this template deploys. This pulls it down and starts everything locally:

```
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/docker-compose.yml -o docker-compose.yml
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/Caddyfile -o Caddyfile
curl https://raw.githubusercontent.com/windmill-labs/windmill/main/.env -o .env
docker compose up -d
```

To add capacity, scale the worker service rather than the server:

```
docker compose up -d --scale windmill_worker=6
```

One caveat with a managed database: Windmill creates a `windmill_admin` role with `BYPASSRLS` on first boot, which needs a Postgres superuser. Providers that withhold it need those roles created by hand first, with upstream's `init-db-as-superuser.sql`. Railway's managed Postgres grants superuser, so no extra step is needed.

## How Much Does Windmill Cost to Self-Host?

Windmill's Community Edition is free to run internally with no seat or execution limits, and it is what this template deploys, with the core source under AGPLv3. A paid Enterprise Edition adds collaborative editing, full-text job-log search, distributed dependency caching and worker autoscaling. On Railway you pay only for the compute, storage and bandwidth used.

## FAQ

**What is Windmill?**
Windmill is an open-source platform that turns scripts into scheduled jobs, APIs, multi-step flows and internal apps. It is written in Rust, and runs your code in Python, TypeScript, Go, Bash, SQL and other languages.

**What does this Railway template deploy?**
Six services: a Caddy proxy on the public domain, the Windmill server, a general worker tier, a native worker tier, the language-server and debugger container, and Postgres.

**Why does Windmill need Postgres?**
Postgres is not just storage here — it is the job queue. Scripts, flows, apps, secrets and run history live in it, and workers poll it for work, which is why there is no Redis or RabbitMQ.

**What is the default login for self-hosted Windmill?**
Upstream seeds `admin@windmill.dev` with the password `changeme`. This template sets your own password on that account during first boot, so the published default never works on a fresh deployment.

**How do I scale Windmill workers on Railway?**
Raise the replica count on the worker service, or raise `NUM_WORKERS` to run more processes per container — one per vCPU is upstream's guidance. For heavier isolation, add a worker service with a different `WORKER_GROUP` and route jobs to it with tags.

**Do the server and worker images have to be the same version?**
Yes. Every Windmill service shares one database schema, so upgrade the server, both worker tiers and the extra-services container together.


## Similar templates

- [N8N Main + Worker](https://railway.com/deploy/n8n-main-worker) — Deploy and Host N8N with Inactive worker.
- [Evolution API with n8n](https://railway.com/deploy/evolution-api-with-n8n) — Automate WhatsApp workflows with Evolution API, n8n, and Postgres.
- [Postgres Backup](https://railway.com/deploy/postgres-s3-backups) — Cron-based PostgreSQL backup to bucket storage

Open this page in a browser: https://railway.com/deploy/windmill-automatio-1
