Example: Plain Old Static HTML
The best indicator of a healthy development workflow is a short feedback loop.
Kubernetes is a huge wrench in the works.
Let’s fix this.
In this example, we’re going to take you through a very simple shell script that serves static HTML.
We’ll use Tilt to:
- Run the server on Kubernetes
- Measure the time from a code change to a new process
- Optimize that time for faster feedback
Obviously, this is a silly example. But it can be a useful example to confirm that Tilt is working as expected in your environment.
All the code is in this repo:
To skip straight to the fully optimized setup, go to this subdirectory:
Step 0: The Simplest Deployment
Our server is a two-line shell script:
echo "Serving files on port 8000" busybox httpd -f -p 8000
To start this server on Kubernetes, we need three config files:
1) A Dockerfile that builds the image
2) A Kubernetes deployment that runs the image
3) And finally, a Tiltfile that ties them together:
docker_build('example-html-image', '.') k8s_yaml('kubernetes.yaml') k8s_resource('example-html', port_forwards=8000)
The first line tells Tilt to build an image with the name
in the current directory.
The second line tells Tilt to load the Kubernetes
YAML. The image name in the
docker_build call must match the container
reference in the
The last line configures port-forwarding so that your server is
localhost:8000. The resource name in the
must match the Deployment’s
Try it! Run:
git clone https://github.com/tilt-dev/tilt-example-html cd tilt-example-html/0-base tilt up
Tilt will open a browser showing the web UI, a unified view that shows you app status and logs. Your terminal will also turn into a status box if you’d like to watch your server come up there.
When it’s ready, you will see the status icon turn green. The logs in the bottom pane will display “Serving files on port 8000.”
Step 1: Let’s Add Benchmark Trickery
Before we try to make this faster, let’s measure it.
local_resource, you can direct Tilt to execute existing scripts or arbitrary shell commands on your own machine, and manage them from your sidebar like any other Tilt resource. We’re going to use this functionality to benchmark our deployments.
We added a
local_resource to our
that records when an update starts.
k8s_resource('example-html', port_forwards=8000, resource_deps=['deploy']) # Records the time from a code change to a new process. # Normally, you would let Tilt do deploys automatically, but this # shows you how to set up a custom workflow that measures it. local_resource( 'deploy', 'date +%s > start-time.txt')
local_resource() call creates a local resource named
deploy. The second
argument is the script that it runs.
We’ve also modified our server itself to read that start time and print the time elapsed.
Let’s click the button on the
deploy resource and see what happens!
If you look closely, the elapsed time displayed in the Tilt sidebar is different than the benchmark our app logged. That’s OK! In multi-service development, there are many benchmarks we care about – the time to build the image, the time to schedule the process, and the time until the server is ready to serve traffic.
Tilt offers you some default benchmarks, and the tools to capture your own.
Our benchmarks show this is a bit slow. Can we do better?
Step 2: Let’s Optimize It
When we make a change to a file, we currently have to build an image, deploy new Kubernetes configs, and wait for Kubernetes to schedule the pod.
With Tilt, we can skip all of these steps, and instead live_update the pod in place.
Here’s our new Tiltfile with the following new code:
# Add a live_update rule to our docker_build. docker_build('example-html-image', '.', live_update=[ sync('.', '/app'), run('./report-deployment-time.sh'), run('sed -i "s/Hello cats/Congratulations, you set up live_update/g" index.html'), ])
We’ve added a new parameter to
docker_build() with three
The first step syncs the code from the current directory (
.) into the container at directory
The second step runs our script to report the deployment time.
The third step congratulates you on finishing this guide!
Let’s see what this new configuration looks like in action:
Tilt was able to update the container in less than a second!
You can try the server here:
Once you’re done configuring your project, set up a CI test to ensure
your setup doesn’t break! In the example repo, CircleCI uses
ctlptl to create a single-use Kubernetes
cluster. The test script invokes
tilt ci. The
tilt ci command deploys all
services in a Tiltfile and exits successfully if they’re healthy.
Obviously, our busybox example is very silly. We just wanted to show you how Tilt can work with any language, even a silly one.
Tilt’s first deployment of a service takes a few seconds longer than subsequent ones, due to some behind-the-scenes setup. Measurements in this guide focus on non-initial builds. ↩