Documentation Index
Fetch the complete documentation index at: https://ubicloud.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Windmill is an open-source platform that transforms scripts into UIs, APIs, and workflows. Supporting languages like Python and TypeScript, it simplifies internal tool creation, automation, and scaling for teams. This guide will help you set up Windmill on Ubicloud, with Ubicloud managed Kubernetes and PostgreSQL services.
Preparing the Ubicloud Environment
To prepare the Ubicloud environment for running Windmill, follow the steps outlined in the Ubicloud documentation:
Preparing Your Environment
Step 0: Ensure that your shell environment has kubectl and helm installed.
Use the commands to verify that kubectl and helm are installed:
kubectl version
helm version
Step 1: Obtain the kubeconfig File
- Download the kubeconfig: Access the Kubernetes cluster in the Ubicloud console and download the kubeconfig file.
- Copy the file to the default kubeconfig location (
$HOME/.kube/config) or set the KUBECONFIG environment variable to configure your Kubernetes client (e.g., kubectl).
Step 2: Create a Namespace for Windmill
Create a namespace for the Windmill deployment:
kubectl create namespace windmill
Step 3: Store the Database Connection String in a Secret
Retrieve the connection string for your PostgreSQL database from the Ubicloud console and create a secret:
kubectl create secret generic -n windmill pg-db-credentials \
--from-literal=url='<postgres connection string copied from Ubicloud console>'
Deploying Windmill
Add Windmill Helm repo:
helm repo add windmill https://windmill-labs.github.io/windmill-helm-charts/
Download the values.yaml file for the Windmill chart:
curl -O https://raw.githubusercontent.com/windmill-labs/windmill-helm-charts/refs/heads/main/charts/windmill/values.yaml
Disable the built-in PostgreSQL database in values.yaml:
postgresql:
enabled: false
Set the secret name for the database connection string:
windmill:
...
databaseUrlSecretName: pg-db-credentials
Install the Windmill chart with the modified values.yaml file:
helm -n windmill install my-windmill windmill/windmill -f values.yaml
Wait for all pods to start running:
kubectl -n windmill get pods
Exposing Windmill to the Internet
By default, Windmill chart restricts the windmill-app service to internal cluster access. To access the Windmill UI via a browser, expose the service externally using a load balancer:
kubectl -n windmill patch svc windmill-app -p '{"spec": {"type": "LoadBalancer"}}'
Wait for the service to get an external host assigned:
kubectl -n windmill get service windmill-app
Connecting to Windmill
The application will be accessible via your cluster’s load balancer URL at port 8000 a few minutes after the EXTERNAL-IP is assigned. Run the following command to retrieve the address for your Windmill deployment.
echo "http://$(kubectl -n windmill get service windmill-app --output jsonpath='{.status.loadBalancer.ingress[0].hostname}'):8000"
Congratulations—Windmill is now running on Ubicloud!
Configuring TLS for Secure Access
To expose Windmill securely via HTTPS, we’ll employ Nginx Gateway Fabric, cert-manager, and Let’s Encrypt using the Kubernetes Gateway API.
Installing NGINX Gateway Fabric & cert-manager
Use the following commands to install the Gateway API CRDs, NGINX Gateway Fabric, and cert-manager:
kubectl kustomize https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.5.1 | kubectl apply -f -
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \
--create-namespace -n nginx-gateway
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set crds.enabled=true \
--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \
--set config.kind="ControllerConfiguration" \
--set config.enableGatewayAPI=true
Next, create a ClusterIssuer to obtain certificates from Let’s Encrypt:
export CLUSTER_ISSUER_EMAIL=email@yourcompany.com
kubectl apply -f <(cat <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: $CLUSTER_ISSUER_EMAIL
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
gatewayHTTPRoute: {}
EOF
)
Configuring HTTPS with Gateway API
To expose Windmill securely, you first need the external domain for your cluster. You can find this “Service URL” (e.g., mycluster-services-0b1c1.k8s.ubicloud.com) in the Overview page of your Kubernetes cluster in the Ubicloud console. Alternatively, you can use the address retrieved in the previous step:
kubectl -n windmill get service windmill-app --output jsonpath='{.status.loadBalancer.ingress[0].hostname}'
If you prefer using a custom domain like windmill.yourdomain.com, create a CNAME record with your DNS provider pointing it to the Service URL mentioned above.
Updating Windmill Chart Values
Update the domain values and disable the built-in ingress in values.yaml, as we will manage the Gateway API resources manually:
windmill:
baseDomain: xxxxx-services-xxxxx.k8s.ubicloud.com # Replace with your Service URL or custom domain
baseProtocol: https
ingress:
enabled: false
Reverting Service Type
Since external traffic will now be handled by the Gateway, revert the windmill-app service back to ClusterIP:
kubectl -n windmill patch svc windmill-app -p '{"spec": {"type": "ClusterIP"}}'
Apply the updated values to the Windmill installation:
helm -n windmill upgrade my-windmill windmill/windmill -f values.yaml
Creating Gateway and HTTPRoute
Finally, create the Gateway and HTTPRoute resources to expose Windmill via HTTPS:
export WINDMILL_DOMAIN=xxxxx-services-xxxxx.k8s.ubicloud.com # Replace with your domain
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: windmill-gateway
namespace: nginx-gateway
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
gatewayClassName: nginx
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
- name: https
hostname: "$WINDMILL_DOMAIN"
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: windmill-tls-cert
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: windmill
namespace: windmill
spec:
parentRefs:
- name: windmill-gateway
namespace: nginx-gateway
sectionName: https
hostnames:
- "$WINDMILL_DOMAIN"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: windmill-app
port: 8000
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: windmill-redirect
namespace: windmill
spec:
parentRefs:
- name: windmill-gateway
namespace: nginx-gateway
sectionName: http
hostnames:
- "$WINDMILL_DOMAIN"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
EOF
Verifying the Certificate Status
It may take a few minutes for the certificate to be issued and the gateway to become fully operational. Check the readiness of the TLS certificate for the Windmill application:
kubectl -n nginx-gateway describe cert windmill-tls-cert
Once the certificate is ready, you can access your Windmill application securely at https://xxxxx-services-xxxxx.k8s.ubicloud.com or https://windmill.yourdomain.com.