Skaffold is a command line tool to develop applications against a Kubernetes cluster (either a local Minikube or a remote cluster). Skaffold handles the build, push and deploy process of the image upon code change. Until today, Skaffold was (IMHO) not well-suited to interpreted languages like Node.js, due the inherent slowness of the process. With version 0.16.0, Skaffold supports an hybrid approach, allowing to take advantage of the usual auto-reload mechanisms used by Node.js developers (e.g.: nodemon
):
nodemon
package.json
), Skaffold does the full rebuild, push and deployThis hybrid approach is perfectly suited to a large class of technology stacks, like Node.js, React, Angular, Python, etc.
Code available in the Skaffold [master](https://github.com/GoogleContainerTools/skaffold/tree/master/integration/examples/nodejs)
branch.
npm
:npm init
package.json
:npm install express nodemon --save
node_modules
locally:rm -rf node_modules
nodemon
run command to the scripts
section in package.json
:
"scripts": {"dev": "nodemon index.js"},
index.js
:Create a Dockerfile
:
Create a Kubernetes pod definition k8s-pod.yaml
:
If you use an editor that writes temporary files (like vim
) you need a .dockerignore
file to make sure that temporary files do not trigger a container build:
skaffold.yaml
:The deploy
section points to the pod definition, while the build
section points to current directory, where the Dockerfile
is located. The sync
clause disables the full rebuild/push/deploy for *.js
file changes and enables the sync process of those files to the container.
skaffold dev
This command starts the Skaffold file watcher, builds the image and deploys it on the cluster; it also shows you the application logs and it handles port forwarding for you. When you see:
...[node] Example app listening on port 3000!
You’re ready to access the application:
$ curl localhost:3000Hello World!
Make some changes to index.js
. You will see that the modified file is synced to the container and nodemon
restarts the application:
Syncing 1 files for gcr.io/k8s-skaffold/node-example:dirty-11d1880Watching for changes every 1s...[node] [nodemon] starting `node index.js`[node] Example app listening on port 3000!
$ curl localhost:3000Hello World - changed!
Fast and easy!
If you change a file that requires rebuilding the container (like adding a dependency in package.json
) the full build/push/deploy mechanism is triggered:
Starting build...Found [minikube] context, using local docker daemon.Building [gcr.io/k8s-skaffold/node-example]...Sending build context to Docker daemon 10.34MBStep 1/5 : FROM node:8.12.0-alpine---> df48b68da02a
...
Build complete in 8.236026621s
...
[node] Example app listening on port 3000!
The time it takes depends on the complexity of your package.json
.
Even if changing package.json
does not happen that often, rebuilding a complex app can be lengthy. A mechanism is needed to make use of npm
cache to speed up the process.
If you want to lean more about local development with Kubernetes, you can watch my talk at the All Day DevOps conference 2018.