Windmill 개발 안내서

Windmill 개발 안내서

1. Windmill의 이해

1.1 Windmill의 정의: 단순한 워크플로우 엔진을 넘어선 개발자 플랫폼

Windmill은 스크립트를 웹훅(Webhook), 워크플로우(Workflow), 사용자 인터페이스(UI)로 신속하게 전환하여 전체 인프라를 강화하도록 설계된 오픈소스 개발자 플랫폼이다.1 이는 단순한 워크플로우 자동화 도구를 넘어, 개발자가 엔드포인트, 워크플로우, UI와 같은 포괄적인 내부 도구를 단일 플랫폼 내에서 구축할 수 있도록 지원하는 것을 목표로 한다.2 Retool, Superblocks, n8n, Airflow, Prefect, Temporal과 같은 기존 도구들의 대안으로 포지셔닝하며, 이들 각각이 제공하는 UI 빌딩, 워크플로우 오케스트레이션, 백그라운드 작업 실행 등의 기능을 통합적으로 제공한다.2

Windmill의 핵심 가치는 개발자가 작성한 단발성 스크립트를 프로덕션 환경에서 안정적으로 운영 가능한 애플리케이션으로 전환하는 과정의 복잡성을 제거하는 데 있다. 개발자는 종종 특정 작업을 해결하기 위해 자신의 컴퓨터에서 Python이나 Bash 스크립트를 작성하지만, 이를 팀원과 공유하거나 비개발자가 사용하도록 만들기 위해서는 API 엔드포인트 생성, UI 개발, 권한 관리, 로깅, 스케줄링 등 상당한 추가 엔지니어링 작업이 요구된다.4 Windmill은 이러한 ‘스크립트의 프로덕션화(Productionization of Scripts)’ 과정에서 발생하는 반복적이고 부가적인 오버헤드를 플랫폼 차원에서 해결한다.4 개발자는 핵심 비즈니스 로직이 담긴 스크립트 코드 자체에만 집중하면, 플랫폼이 나머지를 자동으로 처리하여 즉시 사용 가능한 도구로 만들어준다.3 이는 개발자의 생산성을 직접적으로 향상시키며, 특히 DevOps, 데이터 엔지니어링, 운영팀에서 빈번하게 발생하는 문제점을 효과적으로 해결한다.

1.2 핵심 철학: ’코드가 중요한 곳에만 집중’하는 접근 방식

Windmill은 로우코드(Low-code)의 개발 속도와 코드(Code)의 유연성 및 강력함 사이의 이상적인 지점, 즉 ’스위트 스폿(sweet spot)’을 지향한다.4 사용자는 시각적인 로우코드 빌더를 통해 신속하게 워크플로우나 UI를 구성하다가도, 언제든지 필요에 따라 코드 레벨로 전환하여 세밀하게 로직을 수정하고 제어할 수 있다.4

이러한 접근 방식은 복잡한 비즈니스 로직, 데이터 변환, 특수한 API 연동과 같이 코드를 통해 가장 명확하고 효율적으로 표현될 수 있는 부분은 개발자가 직접 코드로 작성하도록 장려한다. 동시에 UI 구성이나 스크립트 간의 연결처럼 반복적이고 정형화된 작업은 로우코드 인터페이스를 통해 처리함으로써 전체 개발 속도를 극대화한다. 이 철학은 조직 내 다양한 기술 수준을 가진 구성원 간의 협업을 촉진하는 기반이 된다. 전문 개발자는 Python, Go, Rust 등 선호하는 언어를 사용하여 복잡한 로직을 담은 핵심 스크립트를 작성하고 플랫폼에 등록한다.7 일단 스크립트가 등록되면, UI가 자동으로 생성되어 재사용 가능한 ‘블록’ 또는 ’모듈’이 된다.1 이후 고객 지원팀이나 재무팀과 같이 기술 이해도가 상대적으로 낮은 현업 담당자들은 이 블록들을 로우코드 Flow 에디터에서 시각적으로 조합하여 자신들의 업무에 필요한 자동화 워크플로우를 직접 구축할 수 있다.8 결과적으로 Windmill은 전문 개발자가 핵심 기능을 제공하는 ‘플랫폼 엔지니어’ 역할을, 현업 담당자가 이를 활용하는 ‘시티즌 개발자(Citizen Developer)’ 역할을 수행하는 협업 모델을 가능하게 한다. 이는 IT 부서의 병목 현상을 줄이고 현업의 민첩성을 높이는 효과를 가져온다.

2. Windmill 핵심 구성 요소: Scripts, Flows, Apps

Windmill의 기능은 Scripts, Flows, Apps라는 세 가지 핵심 구성 요소를 중심으로 구성된다. 이들은 상호 유기적으로 연결되어 단순한 코드 조각에서 완전한 내부 애플리케이션에 이르기까지 점진적인 개발을 지원한다.10

2.1 Scripts: 자동화의 최소 단위

스크립트는 Windmill 플랫폼의 모든 기능의 기초를 이루는 가장 기본적인 빌딩 블록이다.10 단일 작업을 수행하는 코드 단위로, 독립적으로 실행되거나 Flows의 구성 요소로 사용될 수 있다.

Windmill은 다국어(Polyglot) 환경을 지원하여 Python, TypeScript (Deno, Bun, Node.js), Go, Bash, SQL, Rust, C#, PHP 등 현대적인 개발에서 널리 사용되는 대부분의 언어를 지원한다.1 또한, Docker 이미지를 실행하는 기능을 통해 사실상 모든 언어와 환경을 스크립트로 활용할 수 있는 무한한 확장성을 제공한다.2

Windmill의 가장 독창적인 기능 중 하나는 스크립트 코드로부터 UI를 자동으로 생성하는 것이다. 플랫폼은 스크립트의 main 함수 시그니처, 즉 매개변수의 이름과 타입 어노테이션을 정적으로 분석하여 해당 스크립트를 실행하는 데 필요한 입력 폼을 웹 UI로 즉시 생성한다.1 예를 들어, Python 스크립트에서 def main(user_name: str, age: int):와 같이 함수를 정의하면, Windmill은 ’user_name’이라는 문자열 입력 필드와 ’age’라는 숫자 입력 필드를 가진 UI를 자동으로 만들어준다.

이 기능은 단순한 편의성을 넘어 코드의 가독성과 재사용성을 높이는 중요한 역할을 한다. 함수 시그니처는 그 자체로 해당 스크립트가 어떤 입력을 필요로 하는지에 대한 명시적인 ’계약(contract)’이자 문서가 된다.13 개발자는 동료가 이 스크립트를 사용할 것을 염두에 두고 더 명확한 변수명과 타입을 사용하도록 자연스럽게 유도되며, 이는 코드 품질 향상과 유지보수 비용 감소로 이어지는 선순환 구조를 만든다.

2.2 Flows: 스크립트의 오케스트레이션

Flows는 여러 스크립트를 하나의 논리적인 작업 흐름으로 엮어주는 오케스트레이션 도구다. 이는 방향성 비순환 그래프(DAG, Directed Acyclic Graph) 구조로 표현되며, 로우코드 기반의 시각적 에디터를 통해 스크립트들을 연결하여 구성한다.11

Flow 에디터 내에서 각 스크립트는 하나의 ’스텝(step)’이 된다. 한 스텝의 출력 결과는 다음 스텝의 입력으로 손쉽게 전달될 수 있어, 복잡한 데이터 파이프라인을 직관적으로 구축할 수 있다.16 또한, 단순한 순차 실행을 넘어 조건에 따른 분기(Branches), 특정 횟수나 조건 만족 시까지 반복하는 루프(For/While loops), 사용자의 개입을 기다리는 승인(Approval), 그리고 오류 발생 시 자동으로 재시도(Retries)하는 등 정교한 제어 흐름을 구현하기 위한 고급 기능을 제공한다.11

Windmill의 Flow는 특히 성능 면에서 기존 워크플로우 엔진과 차별화된다. Rust로 작성된 고성능 백엔드와 효율적인 아키텍처 덕분에 스텝 간의 실행 지연(overhead)이 약 20ms에 불과하여, 다른 오케스트레이션 엔진에 비해 월등히 빠른 실행 속도를 보인다.16 이러한 저지연성은 대규모 데이터 처리와 같은 전통적인 배치 작업뿐만 아니라, 거의 실시간에 가까운 응답성이 요구되는 대화형 워크플로우나 API 엔드포인트 처리에도 Windmill을 적합하게 만드는 핵심 요소다.

2.3 Apps: 워크플로우를 위한 사용자 인터페이스

Apps는 Scripts와 Flows를 기반으로 최종 사용자를 위한 맞춤형 대시보드나 내부 관리 도구를 제작하는 기능이다. Windmill은 드래그 앤 드롭 방식의 로우코드 앱 에디터를 제공하여, 개발자가 복잡한 프론트엔드 코드 없이도 신속하게 UI를 구축할 수 있도록 지원한다.11

앱 에디터는 테이블, 차트, 버튼, 입력 폼 등 60개 이상의 다양한 내장 컴포넌트 라이브러리를 제공한다.11 개발자는 이 컴포넌트들을 캔버스에 배치하고, 각 컴포넌트의 동작을 특정 스크립트나 플로우에 연결할 수 있다.18 예를 들어, 버튼을 클릭하면 특정 스크립트가 실행되도록 하거나, 테이블 컴포넌트가 주기적으로 데이터베이스 조회 스크립트를 실행하여 최신 데이터를 표시하도록 구성할 수 있다. 또한, CSS나 Tailwind CSS를 직접 편집하여 앱의 스타일을 조직의 브랜드 가이드라인에 맞게 자유롭게 변경할 수 있다.10

Apps 기능은 내부 도구 개발의 민주화에 기여한다. 전통적으로 내부 도구 개발은 프론트엔드와 백엔드에 대한 전문 지식을 모두 요구하는 시간 소모적인 작업이었다. Windmill은 백엔드 로직(Scripts, Flows)과 프론트엔드(Apps) 개발을 단일 플랫폼으로 통합하여 이 과정을 단순화한다. 백엔드 개발자는 API 설계나 엔드포인트 노출에 대한 고민 없이 핵심 로직 개발에만 집중할 수 있으며, 이렇게 만들어진 스크립트와 플로우는 앱 빌더에서 재사용 가능한 부품처럼 기능한다. 이를 통해 프론트엔드 개발 경험이 부족한 인력도 필요한 도구를 직접 조립하여 신속하게 현업에 배포할 수 있게 된다.10

3. 기술 아키텍처 심층 분석

Windmill의 아키텍처는 성능, 확장성, 보안이라는 현대적인 개발 플랫폼의 핵심 요구사항을 충족시키기 위해 신중하게 설계되었다. 최신 기술 스택의 전략적 채택과 효율적인 실행 모델은 Windmill의 강력한 경쟁력의 기반이 된다.

3.1 시스템 구성 요소 및 기술 스택

Windmill은 성능과 안정성을 극대화하기 위해 현대적인 기술 스택을 채택했다. 주요 구성 요소는 다음과 같다 1:

  • 백엔드 (Backend): Rust로 작성되었다. Rust는 메모리 안전성과 높은 동시성 처리 능력을 보장하는 시스템 프로그래밍 언어로, Windmill의 워크플로우 엔진이 매우 빠르고 안정적으로 동작하는 핵심적인 이유다. 이는 경쟁 솔루션과의 성능 벤치마크에서 우위를 점하는 기반이 된다.1

  • 프론트엔드 (Frontend): Svelte로 구축되었다. Svelte는 가상 DOM(Virtual DOM)을 사용하지 않고, 코드를 컴파일하여 효율적인 순수 JavaScript 코드를 생성하는 프레임워크다. 이를 통해 웹 IDE, 플로우 에디터, 앱 빌더 등 복잡한 UI가 매우 빠르고 가볍게 동작하여 사용자 경험을 향상시킨다.

  • 데이터베이스 (Database): PostgreSQL을 사용하여 플랫폼의 모든 상태 정보(스크립트, 실행 이력, 사용자 정보 등)를 저장한다. 특히, PostgreSQL을 단순한 데이터 저장소뿐만 아니라 작업 큐(Job Queue)로도 활용하여 아키텍처를 단순화하고 외부 메시지 큐 시스템에 대한 의존성을 제거했다.1

  • 스크립트 런타임 (Script Runtimes): TypeScript 실행을 위해 BunDeno를, Python 실행을 위해 Python 3를 사용한다. 이들은 모두 성능과 현대적인 개발 경험에 초점을 맞춘 런타임이다.

이러한 기술 스택 선택은 Windmill이 레거시 기술의 제약에서 벗어나, 현대적인 클라우드 네이티브 환경에 최적화된 플랫폼을 구축하려는 명확한 방향성을 보여준다. 이는 최신 기술에 익숙한 개발자들에게 매력적으로 다가가며, 장기적으로 더 나은 성능과 유지보수성을 제공할 잠재력을 가진다.

3.2 실행 모델: 작업 큐와 분산 작업자(Worker)

Windmill의 실행 아키텍처는 상태를 저장하지 않는(Stateless) API 백엔드와, 작업을 실제 수행하는 다수의 분산 작업자(Worker)로 명확하게 분리되어 있다.1

  1. 작업 생성: 사용자가 스크립트나 플로우 실행을 요청하면, API 백엔드는 이 요청을 ’작업(Job)’으로 변환하여 PostgreSQL 데이터베이스 내의 작업 큐에 저장한다.

  2. 작업 가져오기 (Pull): 유휴 상태의 작업자들은 주기적으로 작업 큐를 폴링(polling)하여 실행할 작업이 있는지 확인하고, 작업이 있으면 가져와서 실행한다. 이 ‘풀(Pull)’ 방식은 중앙 스케줄러가 작업자에게 작업을 할당하는 ‘푸시(Push)’ 방식에 비해 시스템의 복잡성을 낮추고, 작업자 장애 발생 시에도 전체 시스템이 탄력적으로 운영될 수 있도록 한다.

  3. 작업 실행: 각 작업자는 CPU와 메모리 전체를 사용하는 격리된 자율 프로세스로, 한 번에 하나의 스크립트를 실행한다.11 작업 실행이 완료되면 결과는 다시 데이터베이스에 저장되고, API 백엔드는 이 결과를 사용자에게 전달한다.

이 아키텍처는 수평적 확장성(Horizontal Scalability)을 보장한다. 작업량이 증가하면 단순히 작업자 컨테이너의 수를 늘리는 것만으로 전체 시스템의 처리량을 선형적으로 증가시킬 수 있다.11 또한, ‘Worker Groups’ 기능을 통해 특정 사양(예: GPU, 고용량 메모리)을 가진 머신에서 특정 스크립트를 실행하도록 지정할 수 있다.15 이는 머신러닝 학습과 같이 고사양이 필요한 작업을 필요할 때만 해당 자원을 할당하여 실행하고, 평소에는 저렴한 범용 인스턴스를 활용함으로써 클라우드 인프라 비용을 최적화할 수 있게 한다.

3.3 보안 모델: Google nsjail을 통한 스크립트 실행 샌드박싱

Windmill은 멀티테넌트 환경에서의 보안을 매우 중요하게 고려하며, 이를 위해 Google에서 개발한 nsjail을 사용하여 스크립트 실행 환경을 강력하게 격리한다.1

nsjail은 리눅스 커널의 네임스페이스(namespaces)와 제어 그룹(cgroups) 기능을 활용하여 각 스크립트가 실행되는 프로세스를 샌드박싱한다.

이 샌드박싱을 통해 스크립트는 호스트 시스템의 파일 시스템, 네트워크, 프로세스 목록 등에 대한 접근이 원천적으로 차단된다. 따라서 신뢰할 수 없는 코드가 포함된 스크립트가 실행되더라도 호스트 시스템이나 다른 사용자의 데이터에 영향을 미치는 것이 불가능하다. 이는 Windmill Cloud와 같이 여러 사용자가 자원을 공유하는 환경의 보안을 보장하는 핵심 기술이다.1

이러한 강력한 보안 모델은 사용자들이 스크립트를 공유하고 재사용하는 커뮤니티 공간인 ’Windmill Hub’의 신뢰성을 뒷받침한다.4 사용자들은 Hub에 공유된 스크립트에 악의적인 코드가 포함되어 있을 가능성을 걱정하지 않고, 샌드박스가 제공하는 안전한 환경 내에서 안심하고 자신의 워크플로우에 통합할 수 있다. 결국, 강력한 보안은 단순한 방어 체계를 넘어, 커뮤니티 기반의 개방형 생태계를 활성화하고 플랫폼 전체의 가치를 높이는 핵심 동력이 된다.

4. Windmill 구현 가이드

Windmill의 강력한 기능을 활용하기 위해서는 Scripts, Flows, Apps를 실제로 구현하는 방법을 이해하는 것이 중요하다. 이 섹션에서는 각 구성 요소에 대한 실용적인 예제를 통해 구현 방법을 단계별로 안내한다.

4.1 스크립트 작성: 언어별 핵심 예제

Windmill은 다양한 프로그래밍 언어를 지원하며, 각 언어의 wmill 클라이언트 라이브러리를 통해 플랫폼의 변수, 리소스 등의 기능에 접근할 수 있다.13

4.1.1 Python: CSV 데이터 처리

데이터 분석 및 엔지니어링 작업에 널리 사용되는 Python과 pandas 라이브러리를 활용한 예제이다. 이 스크립트는 CSV 형식의 문자열을 입력받아 데이터프레임으로 변환하고, 기본적인 통계 정보를 요약하여 반환한다.

# py: >=3.11
import pandas as pd
from io import StringIO

def main(csv_data: str):
"""    CSV 데이터를 입력받아 Pandas DataFrame으로 변환하고    기본 통계 정보를 반환한다.    """
# StringIO를 사용하여 문자열을 파일처럼 취급
csv_file = StringIO(csv_data)

# CSV 데이터를 DataFrame으로 읽기
df = pd.read_csv(csv_file)

# 데이터프레임의 기본 정보와 통계 요약 생성
summary = {
"shape": df.shape,
"columns": df.columns.tolist(),
"description": df.describe().to_dict()
}

print("Data processed successfully.")
return summary

이 스크립트를 Windmill에 배포하면 csv_data라는 이름의 큰 텍스트 입력 필드를 가진 UI가 자동으로 생성된다. 사용자가 여기에 CSV 데이터를 붙여넣고 실행하면, 데이터의 형태, 컬럼 목록, 기술 통계량이 포함된 JSON 객체가 결과로 출력된다.

4.1.2 TypeScript: 외부 API 호출

서비스 통합에 자주 사용되는 TypeScript와 fetch API를 사용하여 GitHub API를 호출하는 예제이다. 특정 GitHub 저장소의 정보를 가져와 일부 데이터를 반환한다.

// typescript
// deno
// 이 스크립트는 GitHub API를 호출하여 저장소 정보를 가져온다.

type RepoInfo = {
id: number;
name: string;
full_name: string;
html_url: string;
description: string;
stargazers_count: number;
watchers_count: number;
forks_count: number;
open_issues_count: number;
};

export async function main(
owner: string = "windmill-labs",  repo: string = "windmill"
): Promise<RepoInfo> {
const url = `https://api.github.com/repos/${owner}/${repo}`;
console.log(`Fetching data from: ${url}`);

const response = await fetch(url);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const data = await response.json();

// 필요한 정보만 선택하여 반환
return {
id: data.id,
name: data.name,
full_name: data.full_name,
html_url: data.html_url,
description: data.description,
stargazers_count: data.stargazers_count,
watchers_count: data.watchers_count,
forks_count: data.forks_count,
open_issues_count: data.open_issues_count,
};
}

이 스크립트는 ownerrepo라는 두 개의 문자열 입력 필드를 가진 UI를 생성한다. 사용자가 값을 입력하고 실행하면 해당 GitHub 저장소의 주요 정보가 담긴 JSON 객체가 반환된다.

4.1.3 Go: 동시성(Concurrency)을 활용한 URL 상태 확인

Go 언어의 강력한 동시성 기능인 고루틴(goroutine)과 채널(channel)을 활용하여 여러 웹사이트의 상태를 동시에 확인하는 예제이다.

package inner

import (
"fmt"
"net/http"
"strings"
)

type SiteStatus struct {
URL    string `json:"url"`
Status string `json:"status"`
}

func checkStatus(url string, c chan SiteStatus) {
resp, err := http.Get(url)
if err!= nil {
c <- SiteStatus{URL: url, Status: fmt.Sprintf("Error: %s", err)}
return
}
defer resp.Body.Close()
c <- SiteStatus{URL: url, Status: resp.Status}
}

// main 함수는 (interface{}, error)를 반환해야 한다.
func main(urls string) (interface{}, error) {
// 쉼표로 구분된 URL 문자열을 슬라이스로 변환
urlList := strings.Split(urls, ",")

// 결과를 수신할 채널 생성
c := make(chan SiteStatus)

for _, url := range urlList {
// 각 URL에 대해 고루틴 생성
go checkStatus(strings.TrimSpace(url), c)
}

var resultsSiteStatus
for i := 0; i < len(urlList); i++ {
// 채널에서 결과 수신
result := <-c
results = append(results, result)
}

return results, nil
}

이 스크립트는 쉼표로 구분된 URL 목록을 입력받는 urls 텍스트 필드를 생성한다. 실행 시, 각 URL에 대한 HTTP GET 요청을 동시에 보내고 모든 응답이 완료되면 각 URL의 상태 코드가 포함된 JSON 배열을 반환한다. 이는 DevOps 및 인프라 모니터링 작업에 유용하다.

4.2 워크플로우(Flow) 구축: 실용적 예제 - GitOps 파이프라인

Windmill은 외부 도구와의 연동을 통해 강력한 자동화 파이프라인을 구축할 수 있다. GitHub Actions와 Windmill의 Git Sync 기능을 결합하여 Staging 환경의 변경 사항을 검토 후 Production 환경에 자동으로 배포하는 GitOps 워크플로우를 구현하는 예제는 Windmill의 실제적인 DevOps 자동화 능력을 잘 보여준다.21

이 워크플로우는 다음과 같은 단계로 구성된다:

  1. Staging 환경에서 변경 및 배포:
  • 개발자는 staging Windmill 워크스페이스에서 스크립트나 플로우를 수정하고 배포(Deploy)한다.
  1. 자동 커밋 및 Pull Request 생성:
  • Trigger: staging 워크스페이스에 연결된 Windmill의 Git Sync 기능이 이 변경 사항을 감지한다.22

  • Action: Windmill은 ’Promotion mode’로 설정되어 있어, 변경된 스크립트/플로우에 대한 새로운 브랜치(wm_deploy/...)를 생성하고 해당 변경 사항을 연결된 GitHub 저장소에 자동으로 커밋 및 푸시한다.21

  • GitHub Action: 이 새로운 브랜치 푸시를 트리거로, 미리 설정된 GitHub Action 워크플로우(open-pr-on-commit.yaml)가 실행된다. 이 액션은 main 브랜치로 향하는 Pull Request(PR)를 자동으로 생성한다.21

  1. 코드 리뷰 및 병합 (수동 단계):
  • Approval: 팀 동료들이 GitHub에서 생성된 PR을 검토한다. 코드 리뷰가 완료되고 승인되면, PR을 main 브랜치에 병합(Merge)한다.
  1. Production 환경에 자동 배포:
  • Trigger: main 브랜치로의 병합 이벤트를 트리거로, 또 다른 GitHub Action 워크플로우(push-on-merge.yaml)가 실행된다.21

  • Action: 이 액션은 Windmill CLI(wmill)를 사용하여 GitHub 저장소의 main 브랜치 내용을 production Windmill 워크스페이스로 푸시(sync push)한다.23 이 과정에서 production 워크스페이스의 스크립트/플로우가 최신 버전으로 업데이트된다.

이 예제는 Windmill이 단순히 플랫폼 내부의 기능만으로 동작하는 폐쇄적인 시스템이 아니라, GitHub Actions와 같은 표준 CI/CD 도구와 유기적으로 결합하여 성숙한 개발 및 배포 파이프라인을 구축할 수 있는 개방형 플랫폼임을 보여준다.

5. 배포 및 운영 전략

Windmill은 사용자의 다양한 요구사항과 환경에 맞춰 유연한 배포 옵션을 제공한다. 관리형 클라우드 서비스부터 자체 인프라에 직접 설치하는 방식까지, 각 옵션은 뚜렷한 장단점을 가지며 프로젝트의 성격에 따라 전략적으로 선택할 수 있다.

5.1 배포 옵션: Windmill Cloud vs. 자체 호스팅

Windmill은 크게 두 가지 배포 모델을 제공한다: Windmill Cloud와 자체 호스팅(Self-hosting).2

  • Windmill Cloud: Windmill Labs에서 직접 운영하고 관리하는 SaaS(Software as a Service) 형태의 서비스다. 사용자는 인프라 설정, 업데이트, 유지보수에 대한 부담 없이 즉시 플랫폼을 사용할 수 있다.2 신용카드 등록 없이 가입할 수 있으며, 매월 일정량의 실행을 제공하는 무료 커뮤니티 플랜이 있어 소규모 프로젝트나 기능 테스트에 적합하다.2 빠른 시작과 최소한의 운영 부담을 원하는 팀에게 최적의 선택이다.

  • 자체 호스팅 (Self-hosting): Windmill의 오픈소스 버전을 사용자의 자체 서버나 클라우드 인프라에 직접 설치하여 운영하는 방식이다.11 이 방식은 데이터 주권, 엄격한 보안 규정 준수, 네트워크 정책 등 기업의 특수한 요구사항을 충족시키기 위해 인프라에 대한 완전한 제어가 필요할 때 필수적이다. Windmill의 핵심 기능은 AGPLv3 라이선스 하에 무료로 제공되므로, 초기 비용 부담 없이 강력한 워크플로우 엔진을 구축할 수 있다.1

이 두 배포 옵션은 상호 배타적이지 않다. 예를 들어, 개발팀은 빠른 프로토타이핑과 아이디어 검증을 위해 Windmill Cloud를 사용하고, 검증이 완료된 안정적인 워크플로우는 wmill CLI나 Git Sync 기능을 통해 프로덕션 환경인 자체 호스팅 인스턴스로 마이그레이션하는 하이브리드 전략을 채택할 수 있다.25 이는 개발 속도와 운영 안정성을 모두 확보할 수 있는 효과적인 접근 방식이다.

5.2 자체 호스팅 가이드

자체 호스팅은 배포 환경과 규모에 따라 Docker Compose와 Kubernetes(Helm 사용) 두 가지 주요 방법을 권장한다.

5.2.1 Docker Compose를 이용한 배포

단일 서버 환경이나 소규모 팀에 적합한 가장 간단하고 빠른 배포 방식이다.24

docker-compose.yml, Caddyfile, .env 단 세 개의 설정 파일을 통해 몇 분 안에 Windmill 인스턴스를 실행할 수 있다.1

배포 절차:

  1. Docker 설치 확인: 시스템에 Docker와 Docker Compose가 설치되어 있는지 확인한다.

  2. 설정 파일 다운로드: 다음 명령어를 실행하여 필요한 파일을 다운로드한다.

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
  1. Windmill 실행: 다음 명령어로 Windmill 컨테이너들을 백그라운드에서 실행한다.
docker compose up -d
  1. 접속: 웹 브라우저에서 http://localhost로 접속하면 Windmill 로그인 화면을 볼 수 있다. 초기 관리자 계정은 admin@windmill.dev / changeme 이다.1

프로덕션 환경에서는 내장된 PostgreSQL 대신 Amazon RDS나 Google Cloud SQL과 같은 외부 관리형 데이터베이스를 사용하는 것이 권장된다. 이 경우, .env 파일의 DATABASE_URL 환경 변수를 외부 데이터베이스 연결 문자열로 수정하고 docker-compose.yml 파일에서 db 서비스를 비활성화하면 된다.24

5.2.2 Kubernetes (Helm Chart)를 이용한 배포

높은 가용성과 자동 확장성(auto-scaling)이 요구되는 대규모 프로덕션 환경에서는 Kubernetes에 배포하는 것이 가장 이상적이다.24 Windmill은 공식 Helm 차트(Chart)를 제공하여 Kubernetes 클러스터에 복잡한 구성 요소들을 쉽고 일관되게 배포할 수 있도록 지원한다.1

배포 절차:

  1. Helm 및 kubectl 설치 확인: 로컬 환경에 Helm과 kubectl이 설치 및 구성되어 있는지 확인한다.

  2. Windmill Helm 저장소 추가: 다음 명령어로 Windmill의 공식 Helm 저장소를 추가한다.

helm repo add windmill https://windmill-labs.github.io/windmill-helm-charts/
helm repo update
  1. Windmill 배포: windmill이라는 네임스페이스를 생성하고 Helm 차트를 설치한다.
helm install windmill-chart windmill/windmill \
--namespace=windmill \
--create-namespace
  1. 상태 확인: kubectl get pods -n windmill 명령어로 모든 파드(Pod)가 정상적으로 실행 중인지 확인한다.

Helm 차트는 values.yaml 파일을 통해 데이터베이스 연결 정보, 복제본 수(replicas), 인그레스(Ingress) 설정 등 매우 상세한 부분까지 커스터마이징할 수 있다.27 Windmill의 상태 비저장(Stateless) 서버와 분산 작업자 아키텍처는 Kubernetes의 확장 및 자기 회복(self-healing) 기능과 매우 잘 부합하여, 안정적인 엔터프라이즈급 워크로드를 운영하기 위한 견고한 기반을 제공한다.

6. 고급 기능 활용

Windmill은 기본적인 스크립트 실행과 워크플로우 구성을 넘어, 성숙한 개발 및 운영 환경을 지원하기 위한 다양한 고급 기능을 제공한다. GitOps 워크플로우 연동을 위한 Git Sync와 정교한 접근 제어를 위한 권한 관리 기능은 그중에서도 핵심적인 기능이다.

6.1 Git Sync: GitOps 워크플로우 연동

Git Sync는 Windmill 워크스페이스의 모든 자산(스크립트, 플로우, 앱, 리소스 등)을 Git 저장소와 동기화하는 기능이다.22 이는 단순한 코드 백업을 넘어, Windmill의 모든 구성을 ’코드로 관리(as Code)’하는 GitOps 철학을 실현하게 해준다.

주요 기능 및 장점:

  • 버전 관리 및 협업: 모든 변경 사항이 Git 커밋으로 기록되므로, 변경 이력을 추적하고 특정 시점으로 롤백하는 것이 용이하다. 개발자들은 익숙한 Git 기반의 코드 리뷰 및 협업 프로세스(예: Pull Request)를 그대로 활용할 수 있다.22

  • 환경 분리 및 승격: ’Promotion mode’를 사용하면 개발(dev), 스테이징(staging), 프로덕션(prod) 환경을 별도의 브랜치나 저장소로 관리할 수 있다.21 예를 들어, 스테이징 환경에서 변경된 내용은 자동으로 Pull Request를 생성하고, 코드 리뷰와 승인을 거쳐 main 브랜치에 병합되면 프로덕션 환경에 자동으로 배포되는 파이프라인을 구축할 수 있다.21

  • 구성의 코드화: wmill.yaml 파일을 통해 동기화할 대상(특정 폴더, 특정 유형의 자산 등)을 세밀하게 제어할 수 있다.22 이 설정 파일 자체도 Git으로 관리되므로, 동기화 정책의 변경 이력까지 추적할 수 있다.

Git Sync 기능은 Windmill을 기존의 성숙한 CI/CD 파이프라인에 완벽하게 통합시켜, 내부 도구와 자동화 워크플로우를 안정적이고 예측 가능하게 관리할 수 있도록 지원한다.

6.2 권한 관리: 역할 기반 접근 제어(RBAC) 심층 분석

여러 팀과 사용자가 하나의 Windmill 인스턴스를 공유하는 환경에서는 정교한 권한 관리가 필수적이다. Windmill은 역할 기반 접근 제어(RBAC) 모델을 통해 강력한 보안 및 데이터 격리 기능을 제공한다.29

주요 역할(Roles):

Windmill은 다음과 같은 시스템 수준 및 워크스페이스 수준의 역할을 정의한다 29:

  • Superadmin: 인스턴스 전체에 대한 모든 권한을 가진 최고 관리자다. 모든 워크스페이스에 관리자 권한으로 접근할 수 있다.

  • Admin: 특정 워크스페이스의 관리자다. 해당 워크스페이스 내의 모든 자산을 생성, 수정, 삭제하고 사용자 및 그룹의 권한을 관리할 수 있다.

  • Developer: 스크립트, 플로우, 앱을 생성하고 편집할 수 있는 개발자 역할이다. 자신이 생성했거나 권한을 부여받은 자산에 대해서만 접근할 수 있다.

  • Operator: 제한된 권한을 가진 실행 전용 사용자다. 스크립트나 플로우의 코드를 보거나 수정할 수 없으며, 공유받은 앱이나 스크립트를 실행하는 것만 가능하다. 이는 비개발 직군에게 안전하게 내부 도구를 공유하는 데 이상적이다.

접근 제어 목록(ACL) 및 경로(Path):

Windmill의 모든 자산은 u// 또는 f//와 같은 고유한 경로를 가진다. 접근 권한은 이 경로를 기반으로 정의된다. 기본적으로 자산은 생성한 사용자만 접근할 수 있지만, 폴더나 그룹을 통해 다른 사용자나 그룹에게 ‘뷰어(Viewer)’ 또는 ‘작성자(Writer)’ 권한을 명시적으로 부여할 수 있다.29

이처럼 역할(누가 무엇을 할 수 있는가)과 경로 기반 ACL(어떤 데이터에 접근할 수 있는가)을 조합한 권한 모델은 매우 세분화된 접근 제어를 가능하게 한다. 이는 민감한 데이터를 다루는 금융이나 헬스케어와 같은 산업 분야에서도 Windmill을 안전하게 도입할 수 있는 기술적 기반을 제공한다.

7. 경쟁 솔루션 비교 분석

Windmill은 워크플로우 자동화 및 내부 도구 개발 시장의 다양한 솔루션들과 경쟁 및 협력 관계에 있다. 각 도구는 고유한 철학과 아키텍처를 가지고 있으므로, 특정 요구사항에 가장 적합한 도구를 선택하기 위해서는 이들의 기술적 차이점을 명확히 이해하는 것이 중요하다.

기준WindmillAirflowPrefectTemporaln8n
핵심 패러다임스크립트 중심, 코드의 프로덕션화데이터 파이프라인의 스케줄링 (Configuration as Code)Pythonic API 기반의 동적 데이터플로우내구성 있는 실행 (Durable Execution)노드 기반 시각적 워크플로우 자동화
주요 언어다국어 (Python, TS, Go, Rust 등)PythonPython다국어 SDK (Go, Java, Python, TS)JavaScript/Python (제한적)
아키텍처Rust 백엔드, 분산 Worker (Pull)스케줄러, 메타데이터 DB, Worker (Push)에이전트(Pull), API 서버, UI클러스터 (Frontend, History, Matching, Worker)단일/분산 프로세스, 노드 실행기
데이터 전달JSON 직렬화, 공유 스토리지XComs (제한적), 외부 스토리지인메모리 객체 전달, 결과 저장소워크플로우 상태 및 시그널노드 간 JSON 객체 전달
UI 생성자동 생성 및 로우코드 앱 빌더제한적인 모니터링 UI모니터링 및 관측성 UI없음 (자체 구현 필요)없음 (워크플로우 에디터만 제공)
개발자 경험웹 IDE, VSCode 확장, CLI, Git SyncPython 파일 작성 및 DAG 관리Pythonic, 로컬 테스트 용이SDK 기반, 로컬 테스트 복잡시각적 드래그앤드롭, 코드 노드
라이선스AGPLv3 + Apache (EE 라이선스 별도)Apache 2.0Apache 2.0MITFair-code (상업적 제한)
최적 사용 사례내부 도구, DevOps 자동화, 대화형 워크플로우대규모 ETL/ELT 배치 파이프라인데이터 과학, ML 파이프라인핵심 비즈니스 로직, 장기 실행 트랜잭션SaaS API 통합, 비즈니스 프로세스 자동화
성능 (경량 작업)매우 빠름 (Airflow 대비 13배) 1느림 7Airflow보다 빠름 7매우 빠름 7작업 유형에 따라 다름

주요 비교 분석:

  • Windmill vs. Airflow: Windmill은 저지연성, 다국어 지원, 그리고 내장된 UI 생성 기능에서 Airflow를 크게 앞선다. Airflow는 방대한 커뮤니티와 성숙한 생태계를 바탕으로 대규모 데이터 배치 처리(ETL/ELT)에 여전히 강력한 입지를 가지고 있다.1 Windmill은 Airflow가 적합하지 않은, 더 동적이고 개발자 중심적인 사용 사례(예: 내부 도구, ChatOps)를 효과적으로 공략한다.

  • Windmill vs. Prefect: 두 도구 모두 현대적인 데이터 워크플로우를 지향하지만, Prefect는 Python 생태계에 더 깊이 통합되어 있으며 데이터 과학 및 머신러닝 워크플로우에 특화된 기능을 다수 제공한다.31 반면 Windmill은 다국어 지원과 완전한 내부 ’앱’을 구축할 수 있는 능력에서 더 넓은 범용성을 확보하고 있다.

  • Windmill vs. Temporal: Temporal은 워크플로우의 ’상태’를 안정적으로 보장하는 데 초점을 맞춘 순수한 실행 엔진에 가깝다.7 UI나 로우코드 기능은 제공하지 않으므로, 개발자가 모든 것을 코드로 구현해야 한다. Windmill은 Temporal과 유사한 내구성 있는 실행을 제공하면서도, UI 자동 생성과 로우코드 앱 빌더를 통합하여 완전한 애플리케이션을 만들 수 있는 플랫폼을 제공한다는 점에서 ’간소화되고 사용자 친화적인 Temporal’로 비유될 수 있다.1

  • Windmill vs. n8n: n8n은 비개발자도 쉽게 사용할 수 있는 시각적 노드 기반 자동화에 중점을 둔다. 수백 개의 사전 구축된 통합 노드를 제공하여 SaaS 애플리케이션 간의 연동을 쉽게 만든다.33 Windmill은 ‘코드 우선(code-first)’ 접근 방식을 취하며, 개발자에게 더 많은 제어권과 유연성을 제공한다.33 n8n이 Zapier의 오픈소스 대안이라면, Windmill은 Airplane이나 Retool의 오픈소스 대안에 더 가깝다고 볼 수 있다.

8. 결론: Windmill 도입을 위한 제언

Windmill은 스크립트 기반의 자동화와 내부 도구 개발이라는 특정 영역에서 기존 솔루션들의 한계를 극복하려는 명확한 비전을 가진 강력한 플랫폼이다. 도입을 고려하는 조직은 그 강점과 약점을 명확히 이해하고, 자신들의 프로젝트 요구사항과 부합하는지 신중하게 평가해야 한다.

8.1 Windmill의 강점과 약점 요약

강점:

  • 뛰어난 성능: Rust 기반 백엔드와 효율적인 아키텍처를 통해 경량 작업에서 Airflow 대비 13배 빠른 압도적인 성능을 제공한다.1

  • 다국어 지원: Python, TypeScript, Go, Rust 등 다양한 언어를 지원하여 팀의 기존 기술 스택을 그대로 활용할 수 있다.11

  • 스크립트의 즉각적인 도구화: 코드의 함수 시그니처만으로 자동으로 UI를 생성하여, 단순한 스크립트를 즉시 사용 가능한 도구로 변환한다.1

  • 통합 개발 환경: 스크립트 작성(Scripts), 워크플로우 구성(Flows), UI 구축(Apps)을 단일 플랫폼에서 완결적으로 수행할 수 있다.10

  • 개발자 친화적 생태계: 강력한 CLI, VS Code 확장 프로그램, Git과의 완벽한 연동(Git Sync)을 통해 개발자의 생산성을 극대화한다.1

약점:

  • 생태계 성숙도: Airflow와 같은 전통적인 강자에 비해 상대적으로 새로운 프로젝트이므로, 커뮤니티의 규모나 사전 구축된 통합 라이브러리가 아직 부족할 수 있다.

  • 라이선스: 핵심 기능이 AGPLv3 라이선스를 따르기 때문에, 소스 코드 수정 시 공개 의무에 민감한 일부 기업 환경에서는 도입에 제약이 될 수 있다.35

  • 로우코드 기능의 한계: UI 빌더는 매우 강력하지만, Retool과 같이 UI 구축에만 특화된 전문 솔루션에 비해서는 컴포넌트의 다양성이나 기능의 깊이가 부족할 수 있다.10

8.2 프로젝트 유형별 최적의 도입 시나리오

Windmill은 다음과 같은 시나리오에서 가장 큰 가치를 발휘할 수 있다:

  • 적합한 시나리오:

  • DevOps 및 SRE 자동화: 인프라 프로비저닝, 배포 파이프라인, 장애 대응 등 반복적인 운영 작업을 스크립트로 자동화하고 팀원들이 쉽게 실행할 수 있는 UI를 제공하는 경우.

  • 내부 관리 대시보드: 여러 데이터 소스(DB, API 등)에서 데이터를 가져와 표시하고, 특정 조작(사용자 비활성화, 데이터 수정 등)을 수행하는 관리자용 도구를 신속하게 구축해야 하는 경우.

  • 데이터 엔지니어링 보조 도구: 데이터 품질 검증, 간단한 데이터 변환, 특정 쿼리의 파라미터화된 실행 등 데이터 파이프라인의 보조적인 작업을 자동화하는 경우.

  • ChatOps: Slack이나 Microsoft Teams와 같은 협업 도구에서 특정 명령어를 통해 스크립트를 실행하고 결과를 받아보는 워크플로우를 구축하는 경우.36

  • 부적합한 시나리오:

  • 비개발자 중심의 자동화: 코드를 전혀 사용하지 않고, 사전 정의된 앱들 간의 연결만으로 자동화를 구현하려는 경우. 이 경우 n8n이나 Zapier가 더 적합하다.

  • 초대규모 배치 파이프라인: 수십억 건 이상의 데이터를 처리하는 대규모 ETL/ELT 작업이 주를 이루는 경우. 이 영역에서는 성숙한 생태계를 가진 Airflow나 Spark가 더 안정적인 선택일 수 있다.

  • 고객 대면 애플리케이션: 최종 고객에게 직접 제공되는 서비스의 핵심 백엔드를 구축하는 경우. 이 경우 범용 웹 프레임워크(예: Django, Spring, Express.js)가 더 적합하다.

8.3 향후 발전 방향 및 생태계 전망

Windmill은 개발자의 가장 기본적인 작업 단위인 ’스크립트’를 중심으로 한 강력한 생태계를 구축하고 있다. 향후 Windmill Hub 커뮤니티가 성장함에 따라 재사용 가능한 스크립트 라이브러리가 더욱 풍부해질 것이며, 이는 신규 프로젝트의 개발 속도를 더욱 가속화할 것이다.4 또한, 플랫폼에 내장된 AI 기반 코드 생성 및 워크플로우 추천 기능은 개발자의 진입 장벽을 낮추고 생산성을 높이는 방향으로 계속 발전할 것이다.11 엔터프라이즈 기능(감사 로그, SSO, 고급 권한 관리 등)의 지속적인 강화를 통해 대기업 시장에서도 신뢰할 수 있는 솔루션으로 자리매김할 것으로 예상된다.10

결론적으로 Windmill은 파편화된 내부 도구 및 자동화 시장에서 ’스크립트의 가치를 극대화’하는 독창적인 접근 방식을 통해, 개발자 생산성과 운영 효율성을 동시에 높이고자 하는 조직에게 매우 매력적인 통합 플랫폼이 될 잠재력을 가지고 있다.

9. 참고 자료

  1. windmill-labs/windmill: Open-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal. - GitHub, https://github.com/windmill-labs/windmill
  2. Getting started with Windmill, https://www.windmill.dev/docs/getting_started/how_to_use_windmill
  3. Windmill is a fast, open-source workflow engine and developer platform. It’s an alternative to the likes of Retool, Superblocks, n8n, Airflow, Prefect, Kestra and Temporal, designed to build comprehensive internal tools (endpoints, workflows, UIs). It supports coding in TypeScript, Python, Go, PHP, Bash, C#, SQL and Rust, or any Docker image, alongside intuitive low-code builders, featuring, https://www.windmill.dev/docs/intro
  4. Windmill: Open-source platform to turn scripts into internal apps & workflows | Y Combinator, https://www.ycombinator.com/companies/windmill
  5. Windmill: Scripts to applications and workflows with minimal code - Decibel VC, https://www.decibel.vc/articles/windmill-scripts-to-applications-and-workflows-with-minimal-code
  6. Windmill | Self-Host on Easypanel, https://easypanel.io/docs/templates/windmill
  7. 8 Alternatives to Airflow - Use Cases - Windmill, https://www.windmill.dev/blog/airflow-alternatives
  8. Windmill for Internal Admin Panels - Kahoot! Case Study, https://www.windmill.dev/blog/kahoot-case-study
  9. Windmill is fantastic. It manages to cover so much ground i.e. airflow, prefect - Hacker News, https://news.ycombinator.com/item?id=38383865
  10. What is Windmill? - tools.dev - Bold Tech, https://blog.boldtech.dev/what-is-windmill-dev/
  11. Windmill | Open-source developer platform and workflow engine, https://www.windmill.dev/
  12. Docker quickstart - Windmill, https://www.windmill.dev/docs/getting_started/scripts_quickstart/docker
  13. Python quickstart | Windmill, https://www.windmill.dev/docs/getting_started/scripts_quickstart/python
  14. Go quickstart | Windmill, https://www.windmill.dev/docs/getting_started/scripts_quickstart/go
  15. Core concepts | Windmill, https://www.windmill.dev/docs/core_concepts
  16. Flows quickstart - Windmill, https://www.windmill.dev/docs/getting_started/flows_quickstart
  17. Flow editor components | Windmill, https://www.windmill.dev/docs/flows/editor_components
  18. Apps quickstart | Windmill, https://www.windmill.dev/docs/getting_started/apps_quickstart
  19. App editor | Windmill, https://www.windmill.dev/docs/apps/app_editor
  20. TypeScript quickstart | Windmill, https://www.windmill.dev/docs/getting_started/scripts_quickstart/typescript
  21. Windmill Sync Example - GitHub, https://github.com/windmill-labs/windmill-sync-example
  22. Git sync | Windmill, https://www.windmill.dev/docs/advanced/git_sync
  23. windmill-sync-devstageprod-example - GitHub, https://github.com/windmill-labs/windmill-sync-devstageprod-example
  24. Self-host | Windmill, https://www.windmill.dev/docs/advanced/self_host
  25. Sync - Windmill, https://www.windmill.dev/docs/advanced/cli/sync
  26. Self-Host Windmill with Docker on localhost - YouTube, https://www.youtube.com/watch?v=NQP2A8RGyoo
  27. windmill-helm-charts, https://windmill-labs.github.io/windmill-helm-charts/
  28. windmill-labs/windmill-helm-charts - GitHub, https://github.com/windmill-labs/windmill-helm-charts
  29. Roles and permissions | Windmill, https://www.windmill.dev/docs/core_concepts/roles_and_permissions
  30. Windmill | Coolify Docs, https://coolify.io/docs/services/windmill
  31. Alternative to Prefect for building workflows | Windmill, https://www.windmill.dev/docs/compared_to/prefect
  32. Airflow to Prefect: Why Modern Teams Choose Prefect, https://www.prefect.io/blog/airflow-to-prefect-why-modern-teams-choose-prefect
  33. If you’re looking for an Open Source alternative, give Windmill a try. | Hacker News, https://news.ycombinator.com/item?id=43879428
  34. Windmill: A great addition to every low code stack - Thomas Martens, https://www.thomasmartens.eu/windmill-a-great-addition-to-every-low-code-stack/
  35. An open letter to the Windmill team · Issue #5014 - GitHub, https://github.com/windmill-labs/windmill/issues/5014
  36. Triggers | Windmill, https://www.windmill.dev/docs/getting_started/triggers