Building on a Base Image
When you start adding multiple services to your app, it’s easiest to just copy a new Dockerfile for each service and tweak a few parameters.
Once you have a few services, that duplication can start to feel messy. Sometimes you update one Dockerfile but forget to update the others. Building all the services is slow.
A common pattern is to create a common base image with the dependencies for multiple services.
With Tilt, you can describe when to re-build each image in the dependency graph.
Building a node_modules
Base Image
Let’s look at an example. We want to create a NodeJS server with two Docker images:
-
A Docker image that contains the node_module dependencies.
-
A Docker image that contains the server source code.
First we write a Dockerfile for the base node_modules image. We’ll call this image
local.tilt.dev/nodejs-express-deps
.
# local.tilt.dev/nodejs-express-deps
FROM node:9-alpine
WORKDIR /src
ADD package.json package.json
RUN npm install
Next we’ll create a Dockerfile for the app image. This is just an empty base image to build on.
# local.tilt.dev/nodejs-express-app
FROM local.tilt.dev/nodejs-express-deps
ADD . /src
ENTRYPOINT node server.js
Lastly, we’ll add a Tiltfile that knows how to build both images.
# Configure image build for our external dependencies.
docker_build(
'local.tilt.dev/nodejs-express-deps',
'./package',
dockerfile='deps.dockerfile')
# Configure build to copy our source code.
docker_build(
'local.tilt.dev/nodejs-express-app',
'.', # build context,
dockerfile='app.dockerfile')
# Set up the Kubernetes resources.
k8s_yaml('app.yml')
Notice that the Docker build for nodejs-express-deps
uses the subdirectory ./package
.
Tilt will only rebuild this image when files under ./package
change.
When you run tilt up
, Tilt will build both images, and make sure that the first image
gets injected into the second image.
STEP 1/3 — Building Dockerfile: [local.tilt.dev/nodejs-express-deps]
Building Dockerfile:
# local.tilt.dev/nodejs-express-deps
FROM node:9-alpine
WORKDIR /src
ADD package.json package.json
RUN npm install
...
STEP 2/3 — Building from scratch: [local.tilt.dev/nodejs-express-app]
Building Dockerfile:
FROM local.tilt.dev/nodejs-express-deps:tilt-af085becbf6ef0ef
ADD . /
ENTRYPOINT node server.js
If you make a change to server.js, Tilt knows it can skip the first image build and just do the second.
Try it Yourself
All the source code for this example is on GitHub.
Try running it yourself with Tilt. Make changes to both package.json
and server.js
and see how Tilt rebuilds only what has changed.