Deploying Windmill on a VPS: The Ultimate Ultra-Fast, Open-Source Alternative to Retool and Temporal Using TypeScript and Python
Introduction: The Modern Internal Tool Dilemma
In the rapidly evolving landscape of enterprise software development, engineering teams frequently encounter a dual challenge: building internal user interfaces rapidly while simultaneously orchestrating complex, asynchronous background workflows. For years, the industry standards for these tasks have been fragmented. Teams often combine Retool for low-code UI building with Temporal or Airflow for robust stateful orchestration. While powerful, this stack introduces significant overhead, licensing costs, and cognitive friction due to fragmented context.
Enter Windmill—a disruptive, open-source developer platform that unifies internal UI building and advanced workflow orchestration into a single, ultra-fast ecosystem. By natively supporting TypeScript, Python, Go, and Bash, Windmill allows developers to turn simple scripts into production-grade workflows and auto-generated user interfaces. In this comprehensive guide, we will explore why Windmill is turning heads in the DevOps space and provide a step-by-step blueprint to deploy it on your own Virtual Private Server (VPS).
Why Windmill? The Convergence of UI and Orchestration
Windmill is not just another low-code clone; it is a highly optimized developer platform designed with a code-first philosophy. It bridges the gap between raw backend scripts and user-friendly internal applications. Here is how it replaces and enhances the functionalities of established market giants:
1. Replacing Retool: From Code to UI Instantly
Retool is famous for its drag-and-drop interface components, but managing complex state and custom code within its UI can quickly become messy. Windmill approaches this problem from the opposite direction. You write a clean, typed script in Python or TypeScript, and Windmill automatically generates a matching frontend form based on your script's type signatures or parameters. For more advanced needs, it includes a highly responsive, reactive App Builder that lets you compose dashboards using code components natively.
2. Replacing Temporal: Lightweight, High-Performance Orchestration
While Temporal is an incredibly robust tool for durable execution, it possesses a notoriously steep learning curve and heavy infrastructure footprints. Windmill offers stateful, distributed workflow orchestration capable of handling millions of tasks. It supports complex branching, loops, error-handling policies, and human-in-the-loop approvals, all managed via an intuitive visual builder or written entirely in code via TypeScript/Python SDKs. Built on a highly optimized Rust backend, its execution latency is remarkably low.
Prerequisites for VPS Deployment
Before initiating the installation process, ensure your Virtual Private Server meets the following baseline specifications to ensure stable production performance:
- Operating System: Ubuntu 22.04 LTS or newer recommended.
- Hardware Specs: Minimum 2 vCPUs and 4GB RAM (8GB+ RAM recommended for heavy production workloads with concurrent Python/TypeScript execution).
- Software: Docker Engine v20.10+ and Docker Compose v2.20+ installed.
- Network: A domain name (e.g.,
windmill.yourcompany.com) pointing to your VPS IP address, with ports 80 and 443 open.
Step-by-Step Guide: Deploying Windmill via Docker Compose
Self-hosting Windmill gives you absolute control over your data security, compliance, and operational costs. We will use the official community stack, which includes the Windmill server, workers, a PostgreSQL database, and a reverse proxy.
Step 1: Preparing the Server Directory
Connect to your VPS via SSH and create a dedicated workspace for Windmill:
mkdir -p /opt/windmill && cd /opt/windmillStep 2: Configuring the Environment Variables
Create an .env file to store crucial configuration keys, database credentials, and security parameters. Use the following baseline template, ensuring you replace placeholder values with strong, randomly generated keys:
Security Note: Never use default passwords in a production environment. Generate secure strings using openssl rand -hex 32.# Database Configuration
POSTGRES_PASSWORD=super_secure_db_password_here
DATABASE_URL=postgres://windmill_user:super_secure_db_password_here@db:5432/windmill?sslmode=disable
# Windmill Enterprise/Community Configurations
WM_SECRET_KEY=your_random_32_character_secret_key
BASE_URL=[https://windmill.yourcompany.com](https://windmill.yourcompany.com)
# Administrative Setup
[email protected]
INITIAL_ADMIN_PASSWORD=your_secure_admin_passwordStep 3: Creating the Docker Compose Specification
Create a docker-compose.yml file in the same directory. This configuration orchestrates the Windmill web server, the asynchronous multi-language workers, and the persistent PostgreSQL layer.
version: '3.8'
services:
db:
image: postgres:15-alpine
restart: unless-stopped
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: windmill
POSTGRES_USER: windmill_user
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U windmill_user -d windmill"]
interval: 5s
timeout: 5s
retries: 5
windmill-server:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- WM_SECRET_KEY=${WM_SECRET_KEY}
- BASE_URL=${BASE_URL}
- INITIAL_ADMIN_USERNAME=${INITIAL_ADMIN_USERNAME}
- INITIAL_ADMIN_PASSWORD=${INITIAL_ADMIN_PASSWORD}
windmill-worker:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
command: worker
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=${DATABASE_URL}
- WM_SECRET_KEY=${WM_SECRET_KEY}
- NUM_WORKERS=4
volumes:
db_data:Step 4: Launching the Stack
Execute the following command to download the optimized Docker images and initialize the services in detached mode:
docker compose up -dVerify that all containers are functioning as intended by monitoring the execution logs:
docker compose logs -f --tail=50Configuring Reverse Proxy and SSL with Nginx
To ensure enterprise-grade security, encrypt all inbound traffic using TLS. Install Nginx and Let's Encrypt Certbot on your host VPS machine to act as a secure reverse proxy gateway.
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx -yConfigure an Nginx server block for your domain at /etc/nginx/sites-available/windmill:
server {
server_name windmill.yourcompany.com;
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Critical for Windmill WebSockets and SSE
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}Enable the site config and provision a free, auto-renewing SSL certificate via Certbot:
sudo ln -s /etc/nginx/sites-available/windmill /etc/nginx/sites-enabled/
sudo systemctl restart nginx
sudo certbot --nginx -d windmill.yourcompany.comBuilding Your First Script and Flow in Windmill
Now that your instance is securely up and running, navigate to your domain and authenticate using your admin credentials. Let's create a functional example showcasing how effortlessly Python or TypeScript integrations work.
Writing a Type-Safe Python Script
Navigate to Scripts -> New Script and select Python. Input a script that fetches user information and automatically exposes an input UI:
# Wwindmill scripts utilize standard type hinting to auto-generate inputs
def main(username: str, account_tier: str = "Premium"):
"""
Processes user onboarding pipeline automatically.
"""
print(f"Processing onboarding for {username} with tier: {account_tier}")
# Business logic goes here...
return {
"status": "success",
"message": f"User {username} successfully synced to CRM."
}Windmill instantly parses the username and account_tier parameters, generating a crisp, clean user input form. No drag-and-drop UI configurations required.
Enterprise Best Practices for Production Windmill
To operate Windmill seamlessly at scale within an enterprise or fast-growing startup infrastructure, adhere to these operational paradigms:
- Horizontal Worker Scaling: Windmill separates the API server from execution workers. If your background data processing queues grow, simply spin up more worker containers across different VPS instances pointing to the central database.
- Git Integration: Windmill features built-in, native Git sync. All scripts, applications, and workflows can be versioned automatically inside a GitHub or GitLab repository, enabling proper CI/CD pipelines and peer reviews.
- Resource Constraints: Limit memory usage per script execution within the Windmill settings dashboard to prevent a single rogue Python loop from exhausting your VPS host memory resources.
Conclusion
Windmill is a formidable evolution in developer tooling. By combining the immediate visual satisfaction of low-code UI builders like Retool with the bulletproof, developer-centric state execution of systems like Temporal, it delivers an unprecedented developer experience. Deploying it via Docker Compose on a single VPS gives you a hyper-efficient, highly secured, and scalable automation stack completely free from expensive platform locks.
