Amazing concept, thank you
My first questions with any new tool of this kind is immediately:
- Can I run/validate branch versions of the scripts non-destructively, for example as part of pre-merge checks in an IaC CD workflow?
- Can I run my scripts locally without a lot of drama, while developing?
If the answer to either of these questions is no, then the tool is the moral equivalent of directly editing PHP files on the prod machine, unless you're committed to deploying an entire second instance of the tool for staging/dev purposes.
Not just for servers and infrastructure, but does it bother anyone else that for example, the Linux desktop has robust APIs for managing powerful service daemons like systemd, but relatively few applications that use them and provide useful UIs/control panels/dashboards? Somehow for many of the tools we DO have, the Linux desktop is stuck in the age of using popen and regex against command output even though we really ought to be able to do better. It's an odd blindspot in a lot of open source work, maybe it is deceptively difficult!
That's mostly nothing to do with this project though, but the two problems are intertwined in my head as problems where a little bit of engineering could really go a long way.
We are fully open-source (AGPLv3) with just one ee plugin for syncing the cache of the workers at large scale (more on that below). You can deploy it on a small ec2 instance with our docker-compose or on very large clusters with our helm charts: https://docs.windmill.dev/docs/advanced/self_host
We are an onion of 3 layers, which are usually separated verticals and the closest services we replace in each vertical are: Lambda + n8n/temporal + Retool:
- Workers implemented in Rust that can run any scripts from source in python/typescript(deno)/go/bash. They are extremely efficient, with most typescript scripts being able to run in 40ms e2e. This can be seen as a self-hosted lambda except it works very differently. Lambdas spawn microvms using firecracker and launch http servers within those micro-vms. We run the scripts bare (with isolation using nsjail on our multi-tenant instance) but cache very aggressively the dependencies. For instance, in python we analyze the dependencies using the AST: https://github.com/windmill-labs/windmill/blob/main/backend/..., infer the dependencies from there, have them go through pip-compile to generate a lockfile (and cache the result), then create a pathset similar to how virtualenv behave with the version of each dependency locked. For typescript, we leverage the very well made immutable deno cache. The cache works well but if you scale your cluster to more than 10 workers, the likelihood of having your worker see dependencies for the first time increase, which is why we reimplemented a pip scheme backed by s3 that is extremely fast (we do not compress, just tar individual wheels and s3 is very fast on local networks). For all the supported languages, we parse the signatures of the main function to infer the corresponding json schema of the payload to trigger them, and from that jsonschema we can then generate automatically the UI and infer the input shape required in the flows for that particular step.
- A workflow engine re-implemented from scratch which can be seen as a distributed FSM and whose state is stored in postgresql and every transition done through postgres transactions. Every worker is picking a job and progressing the fsm at completion. The full spec is at: https://docs.windmill.dev/docs/openflow. We support branches, for loop, suspend/sleep, approval steps, sharing the same folder between steps and everything you would expect from a temporal like engine (retries, error handlers).
- A dashboard/app builder that is very similar to Retool but much faster because it's implemented in Svelte and which can also run python scripts directly leveraging the 1st layer. We also support full react apps: https://github.com/windmill-labs/windmill-react-template
We have a CLI that allows you to sync from github directly: https://github.com/windmill-labs/windmill-sync-example or your local filesystem. Our scripts are absolutely normal scripts so there is no lock-in, and they are executable locally https://docs.windmill.dev/docs/advanced/local_development so you do not have to use our webeditor if you do not want to but our editor supports pyright and deno lsp through our dedicated backend communicating to monaco using websockets.
We also support worker groups to run some jobs on hardware accelerated machines (GPU) and a lot of other features (oauth syncing of the resources, schedules, granular permissioning, groups and folders).
Every script/flow deployed has a dedicated webhook endpoint to run synchronously and asynchronously. Scripts are never overwritten, they keep a lineage of hash for each version and have per-hash dedicated webhook to ensure their behavior never change.
We also have a hub for sharing re-usable scripts https://hub.windmill.dev to be used in flows to have some of the same convenience you can find in Pipedream or Zapier.
Our closest alternative would be Airplane.dev, but they're not open-source, not self-hostable air-gapped, less performant, less-featured and much more expensive. You can self-host us fully free.
We are used in production at scale in clusters of 50 nodes+ and thanks to the reliability of Rust and Postgresql have had no downtime to report.
I'm a solo founder, YC S22. The MVP got some attention at the very beginning: https://news.ycombinator.com/item?id=31272793 but was very bare. Now we're ready to bring this to the next level and enable all engineers to spend more time building and less time reinventing the wheel thanks to it :)
2) yes, https://docs.windmill.dev/docs/advanced/local_development
1) since you can run them locally, you can also run tests as part of your CI. You can also deploy a full windmill as part of your CI, deploy to that local instance, run some e2e tests by calling the webhooks, and then only deploy once those work.
Note that we have a full drafting system baked in into the webeditor as well: https://docs.windmill.dev/docs/core_concepts/draft_and_deplo... and have support for folders with different permissions and you can create workspaces so you may implement dev/staging/prod in any fashion you like (different folder, workspace, instances)
Any support for docker based workers?
To be clear, the workers can run in docker, but do not run docker jobs.
1. Can I see list of all executions, their parameters and complete stdout, with handy URL I can refer too?
2. Can I get notifications (email etc) when script fails or certain conditions are met (something appears in the output)?
3. Can you set execution timeout?
2. yes (our flows have optional error handlers)
3. yes (TIMEOUT is an env variable of the workers)
Looks like you're a new y combinator startup. Kool. I would suggest you find away to allow existing code to be reused. Deno market share is very small and experienced/larger teams are not going to want to rewrite and learn that stack. They would have to depend on you, a small new company. Too much risk.
One nitpick: In my humble opinon, you should switch from Discord chat to Zulip.
It's completely open-source (Apache 2, self-hostable, free full cloud plan for open-source projects) and has an excellent threads-first (called "topics" model): https://zulip.com/why-zulip/
It can run fully in the browser, but it has desktop and mobile clients as well.
It also supports public channels which AFAIK discord doesn't. So you can link to specific messages inside a GitHub issue and anyone who doesn't even have an account can see the relevant messages and context.
Interestingly it's what the Rust language team (and community) uses for comms: https://rust-lang.zulipchat.com
(I'm not affiliated in any way with Zulip btw, I just love the product)
It's different in those fashions. Windmill can run python but also typescript, go and bash. Airflow/Prefect etc uses code annotation which mean the code is actually specific to the platform. We actually have the steps be directly scripts/code with a main function, and then have a low-code builder to compose them into powerful workflows. That low-code builder produces a yaml like that one: https://github.com/windmill-labs/windmill-sync-example/blob/... which you could theoretically write by hand.
The low-code builder is intuitive and similar to n8n except it has the feature-set of the above framework. It's easy to test the individual steps or to test the whole flow. The workflow engine is very efficient and running 50 steps will essentially have about 1s overhead total, and the steps are executed bare so it will take as much time as if you were running them without windmill on your node directly. They can be hardware accelerated easily in that fashion. We also support some features borrowed from temporal like the ability to suspend at no-cost flows until they are resumed by an external event such as an approval from slack.
As a sidenote: is the windmill hub open-source too? Does it make use of the base product to operate? I think it might be a good candidate for showing what your product is capable of, as an actual example of use in production
- Allow manage users via Keycloak or similar tools.
- Allow embed UI to external React application.
Choice is better than "one true way".
That said, I don't take the UNIX philosophy to be gospel, and frankly, very little of the Linux kernel or desktop really seems to. That seems to be closer to what the *BSD derivatives would steer towards. I just want a functional operating system, and the specific ideology or design of packages isn't too big of a concern so as long as the end result seems solid.
What does windmill do that script-server can't? Or is windmill targeting a completely different area, and is thus irrelevant to me and my pile of 500+ python, shell, Golang, and java bin dir.
Completely Agree
>> [...] the specific ideology or design of packages isn't too big of a concern so as long as the end result seems solid.
The framework of thinking, while I agree is not gospel, is helpful in guiding design thinking towards a shared goal.
From the README. It sounds like a commercial license is needed for SSO and that the free version has a limited number of users.
One suggestion: I think you could do improve the docs by (a) providing a direct comparison to Airplane and (b) providing more code-oriented documentation.
Most of you docs highlight the web editor which, frankly, I have little interest in. I want to write my scripts and views in my IDE and store them in GitHub. This is something Airplane really nails: their docs are clearly about how to use this as a developer. Compare your flows quick start [0] with their tasks quick start [1] and it really feels like Airplane is more suited to a developer audience. I'm worried I will be locked into static control flow with yours, whereas Airplane makes it clear I can do ~any code I want, as long as it runs in Temporal.
Of course, totally fair if you are trying to target more no-code use cases.
[0]: https://docs.windmill.dev/docs/getting_started/flows_quickst... [1]: https://docs.airplane.dev/getting-started/orchestration
You don't want everyone wasting too much time handrolling slightly-differing monstrosities instead of a cohesive design if it's not a business or engineering differentiator.
The updated paragraph:
> In addition, a commercial license grants you a dedicated engineer to transition your current infrastructure to Windmill, support with tight SLA, and our global cache sync for high-performance/no dependency cache miss of cluster from 10+ nodes to 200+ nodes.
For the temporal thing, that's absolutely fair and completely understand the worry but since most workflows are about the steps and not the glue between them, you will be able to reuse most of your code. However, temporal is quite an heavy format for writing workflows so of course it will still be a bit of work.
Our views support our retool like builder but also full react apps, or svelte, or vue, or anything that can compile to an iife. The example provided above can be iterated on with just a simple 'npm run dev': https://github.com/windmill-labs/windmill-react-template
print_the_cat_fact(get_a_cat_fact())
Doesn’t seem like a big pain?Looks like that page overcomplicate it by describing every underlying layer and old history of it.
res = requests.get(url)
ti.xcom_push(key="cat_fact", value=json.loads(res.text)["fact"])
...
cat_fact = ti.xcom_pull(key="cat_fact", task_ids="get_a_cat_fact")Besides, how do you think a competing product should rise then?
interview highlights (4min): https://www.youtube.com/watch?v=_jsl0k7LX34
full interview (33min): https://www.youtube.com/watch?v=rPLVwFRjw7o
I was trying to provide a contrary opinion because I often see the HN hivemind hate on Discord heavily for no reason, while it's become a ubiquitous piece of software used by younger people that the older generations have been completely sleeping on and still think it's some niche version of IRC for gamers. Discord has hundreds of millions of users, it's a behemoth rivaling the big social networks.
As a random user, if I were trying to ask a question about this piece of software, I want to open the Discord server and ask it, I don't want to start researching whatever Zulip is and how to use it and figuring out how a new interface works
A few questions, just in case:
1. Does Windmill support long-running workflows? Our use case has our customers being in a workflow for years (as long as they have a relationship with us) and events moving them around states.
2. Does it support rule-based state transitions? Everything I've seen is "when this webhook comes, go to that state", but we want something that will trigger the evaluation of a set of rules (with an event or webhook), and the rules will contact APIs to judge whether everything is satisfied for a transition to some next state.
3. Does it support synchronous calls? We usually want the customer to ask "OK where am I now?" and the system to trigger evaluation, transition them to the state they should be in, and tell them where they are. This is for use cases like the website asking "the user has just submitted the data we wanted, where should I redirect them now?".
Those were the biggest things we couldn't find.
2. The webhook can contain a payload, and you can but the suspend step into a for-loop. You could literally say, for-loop forever the suspend until the result of the suspend step (which can be the result of the evaluation of the webhook payload by your rule is true). For that, you will need to use another primitive that we expose which is "Break" that will break out of the for-loop
3. I'm a bit unsure of the term synchronous call. We have a long list of APIs https://app.windmill.dev/openapi.html#/ and you fetch the status of the flow or trigger a flow in a synchronous http webhook to wait for the result. As to force the state of the workflow. We do not expose something like that but it could be added easily.
Happy to chat if we could be a good fit for your needs: ruben@windmill.dev
For the second point, the idea is that we don't want to rely on webhooks at all, except as evaluation triggers. The rules are built in to each state, so even if we've missed a webhook/event, the customer can still proceed.
For an example, one of our flows requires the user to have filled out a consent form in the last three months. As I understand it, with your design, we need to send a webhook when a user has given consent, and then we can proceed to the next state, so we'd have to somehow check for previous consent in some different state? With our design, when the user reaches the state, the rules will be evaluated, and "has given consent within the last three months" will be true, and the user will proceed to the next state without ever seeing the consent form.
For the synchronous bit, it kind of follows from the above feature, and it is so we evaluate state transitions while the user is waiting. We run the workflow synchronously, in the request (since no workflow needs external events to continue), and return the new state to the user.
Since this is synchronous, it avoids races or long waits for events to be delivered.
Thanks for listening, maybe you'll find some of the above helpful in your design!
For the second part, you can just iframe the whole public app and we will provide a React component soon.
See https://github.com/windmill-labs/windmill-sync-example
it should be trivial to push that to a self-hosted setup if you need it.
I have not tried to take my entire workspace from self-hosted to cloud. But I have been exporting and importing individual scripts/flows/apps from self-hosted to cloud.
(no affiliation, just a happy user)
Why? it’s like they’re going out of their way to add friction here.
And we have workflows and a retool alternative/app builder baked-in. And granular permissions and a lot of other things... The UI of script-server looks a bit bare.
But like with a lot of those tools, if you're happy with script-server then that's probably the most important!
I reviewed the examples section, but didn't see one (a webhook?) as a good place to start. Do you have a suggestion?
These might be good qualities for a gamer guild or YouTuber community, but it's a real barrier to participating in open source software communities.
Zulip is open, and doesn't have these restrictions (and already had many bridges and accessibility integrations). I participated in the Oil Zulip, and it was less of a hassle tHan to join a new Discord guild and navigating their adhoc rules bots.
https://docs.windmill.dev/docs/core_concepts/webhooks#trigge... seems to cover a hello world for hooks.
Thinking about it as an alternative to scripted workflows with Rundeck, it seems like the main gap here is getting scripts to run on a specific machine without needing to have set that machine up to run worker processes.
(I could be misunderstanding here, because I haven't spotted anything in the docs that talks about the minimum deployment necessary just to allow a particular machine to run workers.)
Really simple example: there's an administrative command on a mailserver, which can be used to create a new mailbox. I want to make that operation part of some workflow. With Rundeck, I can script this and I just have to make sure Rundeck has ssh credentials onto the mailserver; at execution time it'll deploy the script, substitute in whatever variables, run it and capture the output.
I'm not clear on how I would achieve that with Windmill. Would it involve installing Windmill (or some component of it) on the mailserver, and setting it up as an individual worker group?
And you would do exactly what you suggest in the last paragraph
I wonder which kind of organizations adopt tools of this kind?
How does this play in the long run with maintenance and upgrades?
It would be great to hear from someone that ran such thing for a few years and has some insights to share..
or maybe just the Small Clojure Interpreter: https://github.com/babashka/SCI if it's a requirement for proper sandboxing
Assuming you mean this:
> Would it involve installing Windmill (or some component of it) on the mailserver, and setting it up as an individual worker group?
I was looking at Windmill as a replacement for Rundeck as well and this is exactly the point I was trying to figure out too.
I get why you need to install the worker. And there are lots of tools out there to automate this, from putting it in a custom AMI to tools like chef to building it as part of your base container image.
But one thing that's really nice about Rundeck (maybe the only thing) is that you can have it connect to any host and run commands with just some SSH credentials.
It also feels like worker groups maybe work for this use case but aren't the actual intention. Worker groups feel like "this script does some work and I want to make sure it runs on a machine with the resources that it needs to support its work". Whereas Rundeck scripts on remote hosts are more about "I want to run this command on this specific host because I'm doing maintenance on this host."
You could also use the inline script endpoints to ask the worker to execute bash commands directly. But this probably does not compare well to rundeck. If you had time, I'd be very interested to chat and understand what is the optimal experience you'd be looking for: ruben@windmill.dev