diff --git a/codelab/03_buildpacks-runimage-override/README.md b/codelab/03_buildpacks-runimage-override/README.md new file mode 100644 index 00000000000..e62bb2bd2c8 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/README.md @@ -0,0 +1,5 @@ +### Example: buildpacks with custom run image (Go) + +This is an example demonstrating how to build a single Go file app with [Cloud Native Buildpacks](https://buildpacks.io/) using a custom [Run Image](https://buildpacks.io/docs/concepts/components/stack/) + +[![Open in Cloud Shell](https://gstatic.com/cloudssh/images/open-btn.png)](https://ssh.cloud.google.com/cloudshell/open?cloudshell_git_repo=https://github.com/GoogleContainerTools/skaffold&cloudshell_working_dir=codelab/03_buildpacks-runimage-override&cloudshell_workspace=codelab/03_buildpacks-runimage-override&cloudshell_tutorial=tutorial.md) diff --git a/codelab/03_buildpacks-runimage-override/app/go.mod b/codelab/03_buildpacks-runimage-override/app/go.mod new file mode 100644 index 00000000000..36638d39c7c --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/app/go.mod @@ -0,0 +1,3 @@ +module github.com/GoogleContainerTools/skaffold/examples/buildpacks + +go 1.13 diff --git a/codelab/03_buildpacks-runimage-override/app/main.go b/codelab/03_buildpacks-runimage-override/app/main.go new file mode 100644 index 00000000000..5dc6ed052c0 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/app/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" +) + +func main() { + http.HandleFunc("/", hello) + + log.Println("Listening on port 8080") + http.ListenAndServe(":8080", nil) +} + +func hello(w http.ResponseWriter, _ *http.Request) { + data, err := ioutil.ReadFile("/hello.txt") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + fmt.Fprintf(w, string(data)) +} diff --git a/codelab/03_buildpacks-runimage-override/base/Dockerfile b/codelab/03_buildpacks-runimage-override/base/Dockerfile new file mode 100644 index 00000000000..1d4a09d05b1 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/base/Dockerfile @@ -0,0 +1,7 @@ +FROM gcr.io/gcp-runtimes/ubuntu_18_0_4 +LABEL "io.buildpacks.stack.id"="google" +ENV CNB_STACK_ID io.buildpacks.stacks.bionic +ENV CNB_USER_ID=1000 +ENV CNB_GROUP_ID=1000 + +COPY hello.txt / \ No newline at end of file diff --git a/codelab/03_buildpacks-runimage-override/base/hello.txt b/codelab/03_buildpacks-runimage-override/base/hello.txt new file mode 100644 index 00000000000..b45ef6fec89 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/base/hello.txt @@ -0,0 +1 @@ +Hello, World! \ No newline at end of file diff --git a/codelab/03_buildpacks-runimage-override/k8s/web.yaml b/codelab/03_buildpacks-runimage-override/k8s/web.yaml new file mode 100644 index 00000000000..38cb3662df9 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/k8s/web.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Service +metadata: + name: web +spec: + ports: + - port: 8080 + name: http + type: LoadBalancer + selector: + app: web +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web +spec: + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + containers: + - name: web + image: app + ports: + - containerPort: 8080 diff --git a/codelab/03_buildpacks-runimage-override/skaffold.yaml b/codelab/03_buildpacks-runimage-override/skaffold.yaml new file mode 100644 index 00000000000..14e02d2df12 --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/skaffold.yaml @@ -0,0 +1,15 @@ +apiVersion: skaffold/v2beta9 +kind: Config +build: + artifacts: + - image: base + context: base + - image: app + context: app + buildpacks: + builder: "gcr.io/buildpacks/builder:v1" + runImage: base + env: + - GOPROXY={{.GOPROXY}} + requires: + - image: base diff --git a/codelab/03_buildpacks-runimage-override/tutorial.md b/codelab/03_buildpacks-runimage-override/tutorial.md new file mode 100644 index 00000000000..0fafa33df1d --- /dev/null +++ b/codelab/03_buildpacks-runimage-override/tutorial.md @@ -0,0 +1,85 @@ +# Using custom run image for CNB builder + +## Introduction + +### What is CNB? +[Cloud Native Buildpacks](https://buildpacks.io/) (CNB) enable building +a container image from source code without the need for a Dockerfile. +Skaffold supports building with CNB, requiring only +a local Docker daemon. + +CNB uses two images when building an application image: + - A _run image_ serves as the base image for the resulting application image. + - A _build image_ acts as the host for performing the build. + +### What you'll learn + +- how to annotate an arbitrary image and use it as a CNB +[run image](https://buildpacks.io/docs/concepts/components/stack/). +- how to integrate the custom run image with a sample Buildpacks application using Skaffold's *artifact dependencies* feature. + +___ + +**Time to complete**: + +Click the **Start** button to move to the next step. + +## First steps + +### Start a Minikube cluster + +We'll use `minikube` as our local kubernetes cluster of choice. + +Run: +```bash +minikube start +``` + +## Write a custom CNB run image + +CNB run and build images require some additional metadata to identify the _Stack ID_ and user/group accounts to be used. A [_stack_](https://buildpacks.io/docs/concepts/components/stack/) is a specification or contract. For example, the `io.buildpacks.stacks.bionic` stack defines that it provides the same packages as installed on Ubuntu 18.04. + +We add a base artifact with a single Dockerfile that defines the required metadata, and reference this as an artifact called `base` in our `skaffold.yaml`. + +Next we'll use this artifact as the run image for a sample Buildpacks app. + + + We will use the `gcr.io/buildpacks/builder:v1` builder image which supports the Stack ID `google`. So that's what we added to the Dockerfile. + + +## Use it in a sample Buildpacks app + +We use a simple Go application and reference it as an artifact called `app` in our `skaffold.yaml`. + +To use the `base` artifact as the custom run image we: +- add an artifact dependency for `app` artifact on the `base` artifact. +- set the runImage property of the `app` artifact to be the `base` artifact. + +## Run it! + +Run this command and Skaffold should take care of building the artifacts in order and deploying the provided manifest. + +```bash +skaffold dev --port-forward +``` + +Once the image has been built and deployed click on the icon and select `Preview on port 8080`. This should redirect to the running service and show the output: + +``` +Hello, World! +``` + +The Go app reads hello.txt that's provided by the base artifact. Lets change the text from Hello, World! to `Hello, Buildpacks!`. This should trigger a rebuild of the `base` artifact which in turn triggers a rebuild and redeploy for the `app` artifact. Once that completes click on the icon again and select `Preview on port 8080`. This should redirect to the running service and show the output: + +``` +Hello, Buildpacks! +``` + +## Congratulations + + + +All done! + +You now know how to use Buildpacks with custom run images and use Skaffold to tie the loop together. +