Deploying Windmill.dev on a VPS: The Ultra-Fast Workflow Engine to Replace n8n and Temporal
Introduction: The Evolution of Workflow Automation
In the modern enterprise landscape, workflow automation and internal tooling have become critical drivers of operational efficiency. For years, development teams have relied on two primary paradigms: low-code graphical platforms like n8n or Make, and heavy-duty, code-first orchestration engines like Temporal or Airflow.
While n8n excels at quick API integrations, it often falls short when handling complex logic, heavy data processing, or custom coding requirements. Conversely, Temporal provides unparalleled reliability for distributed systems but introduces significant architectural overhead, a steep learning curve, and complex state management. Enter Windmill.dev—a rising open-source contender that bridges this gap. Windmill is an ultra-fast, developer-first workflow engine and internal UI builder designed to turn scripts (written in Python, TypeScript, Go, Bash, or Rust) into production-ready workflows and applications instantly.
This comprehensive guide will explore why Windmill is emerging as the premier alternative to both n8n and Temporal, followed by a production-ready, step-by-step technical guide to deploying Windmill on a Virtual Private Server (VPS).
---Why Windmill.dev? The Best of Both Worlds
Windmill.dev does not just iterate on existing workflow principles; it redefines them by optimizing for developer velocity, raw performance, and resource efficiency. Here is why engineering teams are migrating their core automation infrastructure to Windmill:
### 1. Blazing Fast Execution EngineUnlike Node.js-based platforms that can struggle under heavy asynchronous loads, Windmill's core worker infrastructure is built in Rust. It leverages a highly optimized PostgreSQL-backed queue system that can process thousands of tasks per second with minimal CPU and memory overhead. This makes it significantly faster than n8n and more resource-efficient than Temporal's multi-service stack.
### 2. Multi-Language Native SupportIn Windmill, every step of your workflow is just a script. You are not confined to a single language or forced to write custom modules. Windmill natively supports:
- TypeScript/JavaScript (executed via Deno or Bun for near-instant startup times)
- Python (with automatic dependency resolution via pip)
- Go, Rust, and Bash (for low-level system operations and high-performance scripts)
One of Windmill's greatest advantages over Temporal and n8n is its built-in low-code UI builder. Once you create a script or a workflow, Windmill automatically generates an input form. You can then drag and drop components to build comprehensive internal dashboards, admin panels, or client-facing portals powered directly by your automated backend workflows.
### 4. Enterprise-Grade Security and State ManagementWindmill provides native secret management, granular Role-Based Access Control (RBAC), and full audit logs out of the box. It handles complex control flows like loops, branching, error retries, and parallel executions effortlessly, storing state transitions safely within your database.
---System Requirements and Prerequisites
Before initiating the deployment process on your VPS, ensure your server meets the following minimum requirements to guarantee stability under production workloads:
- Operating System: Ubuntu 22.04 LTS or Ubuntu 24.04 LTS (recommended)
- CPU: Minimum 2 vCPUs (4 vCPUs recommended for heavy parallel workloads)
- Memory: 4GB RAM minimum (8GB RAM recommended)
- Disk Space: 20GB SSD/NVMe storage
- Software: Docker Engine v20.10+ and Docker Compose v2.0+ installed
- Network: A public static IP address and a domain name (e.g.,
windmill.yourcompany.com) pointed to your VPS via A records.
Step-by-Step Production Deployment Guide
Note: We will use Docker Compose for this deployment as it encapsulates Windmill's multi-component architecture (frontend, server, workers, and database) into an easily maintainable configuration.### Step 1: Server Preparation and Security Update
First, access your VPS via SSH and update the system packages to their latest versions:
sudo apt update && sudo apt upgrade -yEnsure that necessary tools like curl, git, and ufw are installed and configured. Open the required ports for web traffic (80 and 443) along with SSH (usually 22):
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable### Step 2: Directory Architecture SetupCreate a dedicated directory structure for Windmill to isolate its configuration files and persistent database volumes:
mkdir -p /opt/windmill && cd /opt/windmill### Step 3: Configure the Environment VariablesCreate an .env file to store sensitive credentials, database keys, and domain specifications. Use a secure text editor like nano:
nano .envPaste and modify the following configuration block. Ensure you replace the placeholder values with highly secure, randomly generated strings:
# Database Configuration
POSTGRES_PASSWORD=SuperSecurePassword123!
DATABASE_URL=postgres://windmill_user:SuperSecurePassword123!@db:5432/windmill?sslmode=disable
# Windmill Enterprise & Community Settings
WM_BASE_URL=[https://windmill.yourcompany.com](https://windmill.yourcompany.com)
RUST_LOG=info
# Encryption Key (Must be 32 bytes/characters long for credential security)
DATABASE_ENCRYPTION_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6### Step 4: Crafting the Docker Compose FileWindmill relies on a database backend, a central API server, and worker nodes. Create a docker-compose.yml file to define these services:
nano docker-compose.ymlInsert the following production-grade configuration:
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
server:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- DATABASE_ENCRYPTION_KEY=${DATABASE_ENCRYPTION_KEY}
- WM_BASE_URL=${WM_BASE_URL}
- RUST_LOG=${RUST_LOG}
- MODE=server
depends_on:
db:
condition: service_healthy
worker:
image: ghcr.io/windmill-labs/windmill:main
restart: unless-stopped
environment:
- DATABASE_URL=${DATABASE_URL}
- DATABASE_ENCRYPTION_KEY=${DATABASE_ENCRYPTION_KEY}
- RUST_LOG=${RUST_LOG}
- MODE=worker
depends_on:
db:
condition: service_healthy
volumes:
db_data:### Step 5: Launching the ServicesWith your environment and composition files ready, pull the docker images and initialize the cluster in detached mode:
docker compose up -dVerify that all containers are functioning optimally by checking the runtime logs:
docker compose logs -f --tail=50---Configuring Nginx Reverse Proxy and SSL Certificates
To safely expose Windmill to the internet via HTTPS, you should configure Nginx as a reverse proxy coupled with Let's Encrypt SSL certificates.
### 1. Install Nginx and Certbotsudo apt install nginx certbot python3-certbot-nginx -y### 2. Configure Nginx BlockCreate a server block configuration file for your domain:
sudo nano /etc/nginx/sites-available/windmillAdd the following configuration block, replacing the domain name appropriately:
server {
listen 80;
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;
# WebSocket support for log streaming
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}### 3. Activate and Secure with TLSLink the site configuration to enable it, test Nginx for syntax anomalies, and reload the web service:
sudo ln -s /etc/nginx/sites-available/windmill /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxExecute Certbot to generate and install trusted SSL certificates automatically:
sudo certbot --nginx -d windmill.yourcompany.comFollow the interactive prompts to complete the process. Certbot will manage auto-renewals flawlessly via a systemd timer.
---Initial Dashboard Onboarding
Navigate to [https://windmill.yourcompany.com](https://windmill.yourcompany.com) in your browser. On your first initialization, log in using the default superadmin credentials:
- Username:
[email protected] - Password:
changeme
CRITICAL: Immediately access the user profile settings panel to change the default email and password to secure credentials. Leaving default values active exposes your entire automated infrastructure to absolute compromise.
---Conclusion
Windmill.dev represents a paradigm shift in workflow orchestration. By replacing code-obscured visual blocks with powerful native scripts, and resource-heavy state engines with light, lightning-fast Rust-based processing layers, it empowers developers to build bulletproof automations and internal tooling in record time.
Deploying Windmill on a dedicated VPS gives your team complete data sovereignty, predictable infrastructure expenses, and near-infinite scalability. As your operational footprint expands, you can scale horizontally by spinning up additional isolated worker containers across separate infrastructure layers, allowing your automations to grow seamlessly alongside your enterprise.
