# Build a platform for internal tools with Windmill

# Goldilocks effect

Over time, we all end up with a collection of scripts tucked away in a `scripts` directory or git repo. Often these are written for a specific purpose and do not belong to a single category. In my case, I have Python scripts that configure infra, check for pre-requisite in clusters, generate data, query internal APIs and more. My teammates have their collection and other teams must have theirs too.

Scripts can become complex to run with many args while remaining trivial to be turned into full-fledged apps.

Fundamentally, they take`input` as args, perform actions and return an `output.`This is where `Windmill` shines. It generates UI which can be deployed as app using only the code. If you are concerned about running code on the cloud app, you can self-host on a Kubernetes cluster.

Here's my experience deploying Windmill on Kubernetes.

# Windmill

[Windmill docs](https://docs.windmill.dev/docs/advanced/self_host) are pretty good and straightforward. [Helm chart](https://github.com/windmill-labs/windmill-helm-charts) makes it easy to deploy. You can start with minikube and then try on Kubernetes.

## Preparation

### Configure External database

It is better to have a hosted database instance ready in advance. You can disable the default `postgresql` in values.yaml, `minio` is also optional. However, ensure the database is configured correctly before proceeding. Otherwise, app pods will end up in a `crashloop` (as the docs mention). The database credentials are not secret but try to use `sslmode=require`.

### Configure Ingress

The default ingress works well on minikube but you need to configure Ingress as per your k8s. Remember to set`baseDomain` and `baseProtocol` (http to https) accordingly.

### Workaround for private registry

If your k8s cannot access `ghcr.io/windmill-labs` registry then you can copy the images to a private registry. Luckily, they use only 2 images (as of version 1.109)

```bash
# <tag> should be same as release.
docker pull ghcr.io/windmill-labs/windmill:<tag>
docker pull ghcr.io/windmill-labs/windmill-lsp:<tag>
# Now tag and push them to the private registry
```

This is not ideal but a workaround if you are out of options. Next, clone the helm chart and replace these `image:` values. You can install this chart:

```bash
❯ cd windmill-helm-charts
❯ helm install mywindmill ./charts/windmill
```

You can also use a private `pipIndexUrl` This would speed up Python code execution, as the script installs required packages.

## Deployment

Deployment is easy as the docs say:

```bash
# add the Windmill helm repo
helm repo add windmill https://windmill-labs.github.io/windmill-helm-charts/
# install chart with default values
helm install windmill-chart windmill/windmill  \
      --namespace=windmill \
      --create-namespace
```

Navigate to URL and login with `admin@windmill.dev` / `changeme`

# Generate UI from code

Start with a sample script which has a main function like this:

```bash
def main(
    no_default: str,
    #db: postgresql,
    name="Nicolas Bourbaki",
    age=42,
    obj: dict = {"even": "dicts"},
    l: list = ["or", "lists!"],
    file_: bytes = bytes(0),
):
```

Arguments to `main` are used to generate UI elements based on the type. On execution, imported packages are installed. All `print` or log statements are displayed in a log section and `return` values are shown in output.

Each script gets a unique path and you can see execution history, re-use previous inputs, and even schedule runs.

The Web IDE provides a decent editing experience. For Python, support for assistants (Pyright, Black, Ruff) helps keep the code clean.

### Advanced Features

Auto-generated UI is one of the features of Windmill. It can create complex Workflow and comes with a decent drag-and-drop App builder. However, the code is the basic building block.

# Conclusion

Windmill is an awesome open-source option to turn code into apps with reasonable deployment and configuration options. However, I could not find an easy way to enable authentication without using `oauth` integrations (which may be plenty for most people). Many [integrations](https://docs.windmill.dev/docs/integrations/integrations_on_windmill) might work better out of the box in the cloud app.
