How to use Tilt to improve developer experience
In this activity created by Alex Soto Bueno, you get a hands-on introduction to Tilt, a tool that automates the inner-loop operations to boost the developer experience.
When it comes to software development, understanding the development lifecycle is crucial. The development lifecycle is the process software goes through from its initial conception and development to its deployment and maintenance. The first phase is known as the inner loop, and the second (when the application is deployed) is the outer loop. Tilt is a tool that automates the inner-loop operations thereby improving the developer experience.
Figure 1 illustrates both phases.
The inner loop phase
Let’s focus on the inner loop. If the application is simple enough, it’s easy to develop, test, or even deploy it locally (for example, using Quarkus dev mode). A developer would want to test the application manually or make a change to the code and see this change reflected automatically to the running instance. But nowadays, these applications are containerized and deployed to Kubernetes. So what works locally might not work when containerized (i.e., permissions, configuration, directory layout).
Moreover, sometimes it’s impossible to deploy the application locally because of the complexity of the dependencies (i.e., databases, other services, third-party services). So you might want to use a personal Kubernetes cluster to test the application.
At this point, to test the application in a cluster, the developer must compile and package the application, containerize (either with a Dockerfile or using a tool like Jib) and push it to the registry, then apply the Kubernetes manifests to deploy the application to the Kubernetes cluster.
Consider the following example:
mvn clean package docker build -t quay.io/lordofthejars/hello:latest . docker push quay.io/lordofthejars/hello:latest kubectl apply -f kubernetes.yaml
The same process should be executed for any change developed in the code to be tested in a cluster. Although the process is straightforward, the developer needs to repeatedly execute every time a change needs to be tested.
Tilt automates inner loop operations
Tilt simplifies this process by automation. For every change detected on a specific directory, Tilt will execute commands to compile, containerize, push, and deploy the application.
To install Tilt, I recommend following an alternative method described in this installation guide because there is no local Kubernetes cluster used.
To validate the correct installation of Tilt, run the following command in a terminal window:
And the output should show you the installed version of Tilt, such as this:
v0.32.1, built 2023-04-14
Example: Kubernetes cluster and Quarkus application
We will use a remote Kubernetes cluster and a Quarkus Java application for this example. Tilt also works with a local Kubernetes cluster, such as
KinD. You only need to adapt the configuration parameters of Tilt.
How to register for the Developer Sandbox for Red Hat OpenShift
The Developer Sandbox for Red Hat OpenShift is a free Kubernetes cloud environment in a shared, multi-tenant OpenShift cluster preconfigured with developer tools. The Developer Sandbox is active for 30 days and renewable once it expires.
IMPORTANT: If you already have a Kubernetes cluster installed locally or have remote access, you can skip this step.
To register for the Developer Sandbox, click the red button, Start your sandbox for free, as shown in Figure 2.
Log in with your existing Red Hat account or create a new one. Follow the instructions on the screen. Then you will be redirected to the Developer Sandbox page again, but this time, you should see the Start using your sandbox button (Figure 3).
On the OpenShift login screen, click the DevSandbox button (Figure 4).
This opens your new OpenShift cluster console (Figure 5).
Now you can log into the cluster from your computer.
The first step is to download the
oc tool to execute the login command and configure the Kubernetes context locally.
Click the question mark icon in the top-right corner, and select the Command line tools option from the menu, as shown in Figure 6.
Then select the
oc version, depending on your platform. Download, copy, and add it to your PATH variable.
The final step: Log into the cluster by clicking on your username in the Developer Sandbox screen and select the Copy login command option (Figure 7).
A new window will open. Log in again and click on the Display Token link to show the
oc command to use.
oc login --token=sha256~n3GHmBJfSAwbW55555558iyoDuPBp8KJINGTuWQnLar --server=https://api.sandbox-m2.ll9k.p1.openshiftapps.com:6443
Execute this command in a terminal window.
After this step, you can use the
kubectl command as usual and execute the commands in the remote Developer Sandbox cluster.
However, we want to use Tilt, so there will be no manual
Red Hat Quay
We also need a container image registry to store the generated images. If you are using the Developer Sandbox for Red Hat OpenShift, you can use the same account to log in to quay.io and use it as a container registry.
Of course, Docker Hub is still a valid option. The only thing you will need to do is change the container image name to point it out to Docker Hub.
In the case of Quay, create a new repo by clicking Create a New Repository link, as shown in Figure 8:
Then create a new public repository with the name
tiltdemo (Figure 9).
With this in place, it’s time to develop a simple Quarkus application.
Quarkus simplifies containerization
It’s not necessary to use a Quarkus application because any other application is valid. But you’ll see that with Quarkus, it’s so smooth to containerize and Kubernetize an application.
Let’s create a Quarkus application with two extensions:
- Jib extension: The creation of the container occurs in a dockerless way where no docker is required.
- Kubernetes extension: Quarkus automatically scaffolds a Kubernetes deployment file without developing YAML files.
mvn io.quarkus.platform:quarkus-maven-plugin:3.0.1.Final:create \ -DprojectGroupId=org.acme \ -DprojectArtifactId=tiltdemo \ -Dextensions='resteasy-reactive,jib,kubernetes' cd tiltdemo
Next, we need to configure the image name for this project. Open the
src/main/resources/application.properties file, and add the following line:
Substitute the image name part of the username (in this case,
lordofthejars) for your username. If you are using Docker Hub, then it is not necessary to specify the host, as it will be the default value.
To validate that everything works as expected, run the following command:
./mvnw clean package -DskipTests -Dquarkus.container-image.push=true
Run docker login quay.io to set the Quay credentials to push the container image.
When the build is completed, Quarkus has scaffolded a Kubernetes YAML file to deploy the application. Moreover, Jib created a container image and pushed it to the Quay repository we configured in the previous step.
Create a Tilt file
Now that you have installed Tilt and created the Quarkus application, it’s time to make a Tiltfile to configure Tilt for the Quarkus application. This file contains instructions for building, containerizing, and deploying the application into the Kubernetes cluster.
Create a file in the root directory of the project named
Tiltfile with the following content:
default_registry('quay.io/lordofthejars') k8s_yaml('target/kubernetes/kubernetes.yml') allow_k8s_contexts('asotobue-dev/api-sandbox-m2-ll9k-p1-openshiftapps-com:6443/asotobue') custom_build( 'quay.io/lordofthejars/tiltdemo', deps=['src'], skips_local_docker = True, command='./mvnw package -DskipTests -Dquarkus.container-image.image=$EXPECTED_REF -Dquarkus.container-image.push=true', ) k8s_resource('tiltdemo', port_forwards=)
Defining the commands
Let’s explain each of the commands step by step.
- The following command defines the registry location:
lordofthejarswith your username.)
- Quarkus automatically generates these deployment files in
target/kubernetesfolder. This defines where the Kubernetes deployment files are stored:
- By default, Tilt only supports connecting to local Kubernetes clusters. You need to configure the context if you connect to an external one. If you don’t know the context, no problem, don’t set it, as the error message will tell you which context needs to be set.
- The following command configures the container base name and the command to run to containerize the application. Tilt generates a random tag for each image; the final container image name with the random tag is stored in the
custom_build( 'quay.io/lordofthejars/tiltdemo', deps=['src'], skips_local_docker = True, command='./mvnw package -Dquarkus.profile=tilt -DskipTests -Dquarkus.container-image.image=$EXPECTED_REF -Dquarkus.container-image.push=true',
- The last line defines the Deployment name to modify with the value of the
EXPECTED_REFvariable and the forward port value:
Let’s see Tilt in action.
First, run the
tilt up command in the terminal and push the letter s to stream the output.
When Tilt notifies that the pod is ready, list the pods in another terminal as follows:
kubectl get pods NAME READY STATUS RESTARTS AGE tiltdemo-84678f679d-4whv4 1/1 Running 0 28s
Also, since Tilt executes a port forwarding operation, cURL the service using
curl localhost:8080/hello Hello from RESTEasy Reactive
To see Tilt in action, open the
src/main/java/org/acme/GreetingResource.java class file, change the returned String to
Hello from Tilt, and save the file.
You’ll see that automatically, Tilt starts doing something.
Rerun the following cURL command when Tilt finishes the redeployment to check if the message has changed.
curl localhost:8080/hello Hello from Tilt
Thanks to Tilt, the developer experience is improved when developing applications for the Kubernetes cluster. Although this has been a brief introduction to Tilt, it offers much more, making it easy to use with projects shared among different developers.
Tiltfile is a Python file, so you can always use Python statements for creating more complex logic.