开源的内部工具开发基础设施(API、后台任务、工作流和用户界面)。可自托管的Retool、Pipedream、Superblocks替代品,以及简化版的Temporal,具有自动生成的用户界面和自定义用户界面,用于触发工作流和脚本作为内部应用。
脚本自动转换为可共享的用户界面,可以组合成流程或用于构建更丰富的低代码应用。支持的脚本语言包括:Python、TypeScript、Go、Bash、SQL和GraphQL。
试用 - 文档 - Discord - Hub - 贡献者指南
Windmill - API、后台任务、工作流和用户界面的开发者平台
Windmill 是完全开源的(AGPLv3),Windmill Labs 提供专用实例、商业支持和许可证。
https://github.com/windmill-labs/windmill/assets/122811744/0b132cd1-ee67-4505-822f-0c7ee7104252
主要概念
-
用Python、TypeScript、Go或Bash定义一个最小化和通用的脚本,解决特定任务。代码可以在提供的Web IDE中定义,或者与您自己的GitHub仓库同步(例如通过VS Code扩展):
-
您的脚本参数会自动解析并生成前端。
-
让它流动起来!您可以链接您的脚本或社区在WindmillHub上共享的脚本。
-
在您的脚本和流程之上构建复杂的用户界面。
脚本和流程也可以通过cron调度(例如 '*/5 * * * *')或webhooks触发。
您可以在Windmill之上构建整个基础设施!
展示一些实际的脚本代码
//从npm导入任何依赖
import * as wmill from "windmill-client"
import * as cowsay from 'cowsay@1.5.0';
// 填写类型,或使用+Resource类型获取资源的类型安全引用
type Postgresql = {
host: string;
port: number;
user: string;
dbname: string;
sslmode: string;
password: string;
};
export async function main(
a: number,
b: "my" | "enum",
c: Postgresql,
d = "从默认参数推断的字符串类型",
e = { nested: "object" }
//f: wmill.Base64
) {
const email = process.env["WM_EMAIL"];
// 变量是有权限的,按路径
let variable = await wmill.getVariable("f/company-folder/my_secret");
const lastTimeRun = await wmill.getState();
// 日志会被打印并始终可检查
console.log(cowsay.say({ text: "你好 " + email + " " + lastTimeRun }));
await wmill.setState(Date.now());
// 返回值序列化为JSON
return { foo: d, variable };
}
命令行界面
我们有一个强大的命令行界面(CLI)可以与Windmill平台交互,并从本地文件、GitHub仓库同步您的脚本,以及通过本地命令在实例上运行脚本和流程。查看更多详情。
本地运行脚本
您可以轻松地在本地运行脚本,只需为wmill
客户端库传递正确的环境变量,以便在需要时从您的实例获取资源和变量。详情请见:
https://www.windmill.dev/docs/advanced/local_development。
为了在本地开发和测试脚本和流程,我们推荐使用Windmill VS Code扩展:https://www.windmill.dev/docs/cli_local_dev/vscode-extension。
技术栈
- Postgres作为数据库。
- 后端使用Rust,具有以下高可用性和水平可扩展的架构:
- 无状态API后端。
- 从Postgres队列(后续可能是Kafka或Redis)中拉取作业的工作器。 如果感兴趣,请为#173投票。
- 前端使用Svelte。
- 脚本执行使用Google的nsjail进行沙箱隔离。
- JavaScript运行时使用deno_core rust库(该库本身使用rusty_v8,因此底层是V8)。
- TypeScript运行时是Bun和deno。
- Python运行时是python3。
- Golang运行时是1.19.1。
最快的可自托管工作流引擎
我们将Windmill与其他可自托管的工作流引擎(Airflow、Prefect和Temporal)进行了比较,Windmill在两个基准测试中都是性能最佳的解决方案:一个由40个轻量级任务组成的流程,以及一个由10个长时间运行任务组成的流程。
所有方法论和结果可在我们的基准测试页面上查看。
安全性
沙箱隔离
Windmill可以使用nsjail。它具有生产级多租户安全性。不要相信我们的话,请参考fly.io的评价。
密钥、凭证和敏感值
每个工作区都有一个加密密钥,用于加密存储在Windmill的键值存储中的凭证和密钥。
此外,我们强烈建议您加密整个Postgres数据库。这正是我们在https://app.windmill.dev上所做的。
性能
一旦作业开始,与在节点上使用相应运行器(Deno/Go/Python/Bash)运行相同脚本相比,没有额外开销。从队列中拉取作业、启动作业,然后将结果发送回数据库的额外延迟约为50毫秒。一个典型的轻量级deno作业总共需要大约100毫秒。
架构
如何自托管
这里我们只提供docker-compose设置。对于更高级的设置,如从源代码编译或不使用postgres超级用户,请参阅自托管文档。
Docker compose
Windmill可以使用3个文件(docker-compose.yml、Caddyfile和.env)通过一个命令部署。
确保Docker已启动,然后运行:
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
默认的超级管理员用户是:admin@windmill.dev / changeme。
从这里,您可以按照设置应用程序创建其他用户。
更多详情请参阅自托管文档。
Kubernetes(k8s)和Helm charts
我们在以下地址发布helm charts: https://github.com/windmill-labs/windmill-helm-charts。
从二进制文件运行
每个发布版本都包含相应的x86_64二进制文件。您可以使用以下一组bash命令简单地下载最新的windmill
二进制文件。
BINARY_NAME='windmill-amd64' # 或windmill-ee-amd64(企业版)
LATEST_RELEASE=$(curl -L -s -H 'Accept: application/json' https://github.com/windmill-labs/windmill/releases/latest)
LATEST_VERSION=$(echo $LATEST_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
ARTIFACT_URL="https://github.com/windmill-labs/windmill/releases/download/$LATEST_VERSION/$BINARY_NAME"
wget "$ARTIFACT_URL" -O windmill
OAuth、SSO和SMTP
Windmill社区版允许直接从UI的超级管理员设置中配置OAuth、SSO(包括Google Workspace SSO、Microsoft/Azure和Okta)。请注意,社区版的SSO用户数量限制为10个。
查看文档。
商业许可
要自托管Windmill,您必须遵守AGPLv3许可的条款,对于个人使用您不需要担心。对于商业用途,如果您不以任何方式向用户重新暴露Windmill,并且对AGPLv3感到满意,那么您应该没问题。
要将任何Windmill部分重新暴露给您的用户作为产品功能,或在Windmill之上构建功能,为了遵守AGPLv3,您的产品必须是AGPLv3,或者您必须获得商业许可。如果您有任何疑问,请联系ruben@windmill.dev。
此外,商业许可还为您提供专门的工程师,帮助您将当前基础设施过渡到Windmill,提供严格SLA的支持,以及我们的全局缓存同步,用于10+节点到200+节点集群的高性能/无依赖缓存未命中。
集成
在Windmill中,集成被称为资源和资源类型。每个资源都有一个资源类型,定义了资源需要实现的模式。
在自托管实例上,您可能希望从WindmillHub导入所有已批准的资源类型。设置脚本将提示您是否要每天自动同步。
环境变量
环境变量名称 | 默认值 | 描述 | 适用于API服务器/工作器/全部 |
---|---|---|---|
DATABASE_URL | Postgres数据库URL。 | 全部 | |
WORKER_GROUP | default | 工作器所属的工作组,并从中获取其配置。 | 工作器 |
MODE | standalone | 二进制文件的模式。可能的值:standalone、worker、server | 全部 |
METRICS_ADDR | None | (仅限企业版)在/metrics路径上暴露Prometheus指标的套接字地址。设置为"true"则在8001端口上暴露。 | 全部 |
JSON_FMT | false | 以JSON格式而不是logfmt格式输出日志。 | 全部 |
BASE_URL | http://localhost:8000 | 公开访问您实例的基础URL。如果有实例设置,则会被覆盖。 | 服务器 |
SCRIPT_TOKEN_EXPIRY | 900 | 脚本开始时生成的临时令牌的默认有效期。 | 工作器 |
ZOMBIE_JOB_TIMEOUT | 30 | 如果工作器未发送关于正在处理作业的ping,则认为作业成为僵尸的超时时间(服务器每30秒检查一次僵尸作业)。 | 服务器 |
RESTART_ZOMBIE_JOBS | true | 如果为true,则重启僵尸作业(使用相同的uuid和一些日志进行原地重启);如果为false,则使僵尸作业失败。 | 服务器 |
SLEEP_QUEUE | 50 | 在数据库中检查新作业之间睡眠的毫秒数。它会乘以NUM_WORKERS,使得平均而言,对于一个工作器实例,每SLEEP_QUEUE毫秒有一次拉取。 | 工作器 |
MAX_LOG_SIZE | 500000 | 作业可以发出的最大字符数(日志+结果)。 | 工作器 |
DISABLE_NUSER | false | 如果启用了Nsjail,则禁用nsjail的clone_newuser 设置。 | 工作器 |
KEEP_JOB_DIR | false | 作业完成后保留作业目录。用于调试。 | 工作器 |
LICENSE_KEY(仅限企业版) | None | Windmill企业版在启动时检查的许可证密钥。 | 工作器 |
S3_CACHE_BUCKET(仅限企业版) | None | 用于同步工作器缓存的S3存储桶。 | 工作器 |
SLACK_SIGNING_SECRET | None | Slack应用的签名密钥。参见Slack文档 | 服务器 |
COOKIE_DOMAIN | None | Cookie的域。如果未设置,浏览器将根据完整的源设置Cookie。 | 服务器 |
DENO_PATH | /usr/bin/deno | Deno二进制文件的路径。 | 工作器 |
PYTHON_PATH | /usr/local/bin/python3 | Python二进制文件的路径。 | 工作器 |
GO_PATH | /usr/bin/go | Go二进制文件的路径。 | 工作器 |
GOPRIVATE | 用于私有Go模块的GOPRIVATE环境变量。 | 工作器 | |
GOPROXY | 要使用的GOPROXY环境变量。 | 工作器 | |
NETRC | 用于私有Go注册表的netrc内容。 | 工作器 | |
PIP_INDEX_URL | None | 传递给pip的索引URL。 | 工作器 |
PIP_EXTRA_INDEX_URL | None | 传递给pip的额外索引URL。 | 工作器 |
PIP_TRUSTED_HOST | None | 传递给pip的受信任主机。 | 工作器 |
PATH | None | 路径环境变量,通常是继承的。 | 工作器 |
HOME | None | 用于Go和Bash的主目录,通常是继承的。 | 工作器 |
DATABASE_CONNECTIONS | 50(服务器)/3(工作器) | 数据库连接池中的最大连接数。 | 全部 |
SUPERADMIN_SECRET | None | 允许调用者作为虚拟超级管理员superadmin@windmill.dev行事的令牌。 | 服务器 |
TIMEOUT_WAIT_RESULT | 20 | 'run_wait_result'端点超时前等待的秒数。 | 工作器 |
QUEUE_LIMIT_WAIT_RESULT | None | 在'run_wait_result'端点立即拒绝请求之前队列中的最大作业数。优先于查询参数。如果未指定,则没有限制。 | 工作器 |
DENO_AUTH_TOKENS | None | 传递给工作器以允许使用私有模块的自定义DENO_AUTH_TOKENS。 | 工作器 |
DISABLE_RESPONSE_LOGS | false | 禁用响应日志 | 服务器 |
运行本地开发设置
仅前端
这将使用 https://app.windmill.dev 的后端,但使用您自己的前端,并支持热代码重载。
- 安装 caddy
- 进入
frontend/
目录:- 运行
npm install
,npm run generate-backend-client
,然后npm run dev
- 在另一个shell中运行
sudo caddy run --config CaddyfileRemote
- 运行
- 大功告成,windmill 应该可以在
http://localhost/
访问
后端 + 前端
有关所有运行选项,请参阅 ./frontend/README_DEV.md 文件。
- 为Windmill创建一个Postgres数据库,并在Postgres设置中创建一个管理员角色。
获得工作数据库的最简单方法是运行
这也将避免sqlx的cargo install sqlx-cli env DATABASE_URL=<YOUR_DATABASE_URL> sqlx migrate run
query!
宏在编译时出现问题 - 安装 nsjail 并确保它可以在您的PATH中访问
- 安装deno和python3,将二进制文件放在
/usr/bin/deno
和/usr/local/bin/python3
- 安装 caddy
- 安装 lld linker
- 进入
frontend/
目录:- 运行
npm install
,npm run generate-backend-client
,然后npm run dev
- 您可能需要为node运行时设置一些额外的堆空间
export NODE_OPTIONS="--max-old-space-size=4096"
- 在另一个shell中运行
npm run build
,否则后端将找不到frontend/build
文件夹并且无法编译。 - 在另一个shell中运行
sudo caddy run --config Caddyfile
- 运行
- 进入
backend/
目录: 运行env DATABASE_URL=<DATABASE_URL_TO_YOUR_WINDMILL_DB> RUST_LOG=info cargo run
- 大功告成,windmill 应该可以在
http://localhost/
访问
贡献者
版权
Windmill Labs, Inc 2023