diff --git a/Makefile b/Makefile index 37ff24fd0..72a1ce79a 100644 --- a/Makefile +++ b/Makefile @@ -170,22 +170,8 @@ tools-tidy: cd tools; go mod tidy .PHONY: prepare-for-pr -prepare-for-pr: check-links test tools-tidy katacoda +prepare-for-pr: check-links test tools-tidy @echo "========" @echo "It looks good! :)" @echo "Make sure to commit all changes!" @echo "========" - -.PHONY: katacoda -katacoda: - @echo "========" - @echo "Generating Katacoda docs..." - @go run katacoda/main.go - @echo "All done!" - @echo "========" - -.PHONY: check-katacoda -check-katacoda: katacoda - @echo "Checking if Katacoda docs are up-to-date..." - @git diff --quiet HEAD -- katacoda/scenarios || ( echo "Katacoda docs are not up-to-date! Please run 'make katacoda' and commit the katacoda/scenarios folder" && exit 1) - @echo "All katacoda docs are up-to-date" diff --git a/content/docs/app-developer-guide/_index.md b/content/docs/app-developer-guide/_index.md index 58a8fa60c..4e8e9e44b 100644 --- a/content/docs/app-developer-guide/_index.md +++ b/content/docs/app-developer-guide/_index.md @@ -5,8 +5,6 @@ include_summaries=true expand=true +++ -{{< katacoda-button href="https://katacoda.com/buildpacks/scenarios/app-developer-guide" color="green" >}} Learn on Katacoda {{}} - ## Prerequisites A lot of the examples used within this guide will require the following: diff --git a/content/docs/app-developer-guide/build-an-app.md b/content/docs/app-developer-guide/build-an-app.md index 1bac2ef93..33e28270d 100644 --- a/content/docs/app-developer-guide/build-an-app.md +++ b/content/docs/app-developer-guide/build-an-app.md @@ -62,12 +62,6 @@ docker run --rm -p 8080:8080 sample-app The app should now be running and accessible via [localhost:8080](http://localhost:8080). - - ## What about ARM apps? Linux ARM image builds are now supported! diff --git a/content/docs/app-journey.md b/content/docs/app-journey.md index 2084db32b..78e79225b 100644 --- a/content/docs/app-journey.md +++ b/content/docs/app-journey.md @@ -7,15 +7,13 @@ getting-started=true ## Pack for the journey In this tutorial, we'll explain how to use `pack` and **buildpacks** to create a runnable app image from source code. - -{{< katacoda-button href="https://katacoda.com/buildpacks/scenarios/app-journey" color="green" >}} Learn on Katacoda {{}} In order to run the build process in an isolated fashion, `pack` uses **Docker**. That means you'll need to make sure you have both `docker` and `pack` installed: {{< download-button href="https://store.docker.com/search?type=edition&offering=community" color="blue" >}} Install Docker {{}} {{< download-button href="/docs/install-pack" color="pink" >}} Install pack {{}} - + > **NOTE:** `pack` is only one implementation of the [Cloud Native Buildpacks Platform Specification][cnb-platform-spec]. Additionally, not all Cloud Native Buildpacks Platforms require Docker. [cnb-platform-spec]: https://github.com/buildpacks/spec/blob/main/platform.md @@ -86,14 +84,8 @@ To test out your new app image locally, you can run it with Docker: docker run --rm -p 8080:8080 myapp ``` - Now hit [`localhost:8080`](http://localhost:8080) in your favorite browser and take a minute to enjoy the view. - - ### Take your image to the skies @@ -107,9 +99,7 @@ deploying your new image to your favorite cloud! Windows image builds are now supported! - Windows build guide - [builder]: /docs/concepts/components/builder/ [buildpack]: /docs/concepts/components/buildpack/ diff --git a/katacoda.yaml b/katacoda.yaml deleted file mode 100644 index 200412a3e..000000000 --- a/katacoda.yaml +++ /dev/null @@ -1 +0,0 @@ -scenario_root : katacoda/scenarios \ No newline at end of file diff --git a/katacoda/files.txt b/katacoda/files.txt deleted file mode 100644 index 4f3a50744..000000000 --- a/katacoda/files.txt +++ /dev/null @@ -1,17 +0,0 @@ -content/docs/app-journey.md,katacoda/scenarios/app-journey/step1.md -content/docs/app-developer-guide/build-an-app.md,katacoda/scenarios/app-developer-guide/build-an-app.md -content/docs/app-developer-guide/using-cache-image.md,katacoda/scenarios/app-developer-guide/using-cache-image.md -content/docs/app-developer-guide/environment-variables.md,katacoda/scenarios/app-developer-guide/environment-variables.md -content/docs/app-developer-guide/mounting-volumes.md,katacoda/scenarios/app-developer-guide/mounting-volumes.md -content/docs/app-developer-guide/run-an-app.md,katacoda/scenarios/app-developer-guide/run-an-app.md -content/docs/app-developer-guide/specify-buildpacks.md,katacoda/scenarios/app-developer-guide/specify-buildpacks.md -content/docs/buildpack-author-guide/create-buildpack/_index.md,katacoda/scenarios/buildpack-author-guide/intro.md -content/docs/buildpack-author-guide/create-buildpack/adding-bill-of-materials.md,katacoda/scenarios/buildpack-author-guide/adding-bill-of-materials.md -content/docs/buildpack-author-guide/create-buildpack/build-app.md,katacoda/scenarios/buildpack-author-guide/build-app.md -content/docs/buildpack-author-guide/create-buildpack/building-blocks-cnb.md,katacoda/scenarios/buildpack-author-guide/building-blocks-cnb.md -content/docs/buildpack-author-guide/create-buildpack/caching.md,katacoda/scenarios/buildpack-author-guide/caching.md -content/docs/buildpack-author-guide/create-buildpack/detection.md,katacoda/scenarios/buildpack-author-guide/detection.md -content/docs/buildpack-author-guide/create-buildpack/make-app-runnable.md,katacoda/scenarios/buildpack-author-guide/make-app-runnable.md -content/docs/buildpack-author-guide/create-buildpack/make-buildpack-configurable.md,katacoda/scenarios/buildpack-author-guide/make-buildpack-configurable.md -content/docs/buildpack-author-guide/create-buildpack/setup-local-environment.md,katacoda/scenarios/buildpack-author-guide/setup-local-environment.md -content/docs/buildpack-author-guide/create-buildpack/specify-multiple-process-types.md,katacoda/scenarios/buildpack-author-guide/specify-multiple-process-types.md \ No newline at end of file diff --git a/katacoda/main.go b/katacoda/main.go deleted file mode 100644 index b8014b18a..000000000 --- a/katacoda/main.go +++ /dev/null @@ -1,169 +0,0 @@ -package main - -import ( - "encoding/csv" - "log" - "os" - "path/filepath" - "regexp" - "strings" - "text/template" -) - -var ( - commentType = regexp.MustCompile(`file=(?P[\w-/\.]*)`) - replacements = map[string]string{ - `[localhost:8080](http://localhost:8080)`: `[here](https://[[HOST_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com)`, - } -) - -// A very syntactic approach to preprocessing text -// The "better" approach would be to parst the markdwn into some AST and -// manipulate the AST. However the addition of katacoda -// annotations do not lend themselves to any of the existing parsers. Given the -// input -// -// -//```bash -//pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -//``` -// -// -// the `pandoc` AST is -// -// ,RawBlock (Format "html") "" -// ,Para [Code ("",[],[]) "bash pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack",RawInline (Format "html") ""] -// -// and neither the gomarkdown or goldmark AST correctly capture this extended -// markdown format. Neither golang parsers support Pandoc's -// `fenced_code_attributes` which could be used to work around this issue. -func preprocessText(input []byte) []byte { - text := string(input) - lines := strings.Split(text, "\n") - output := preprocessor(lines) - return []byte(strings.Join(output, "\n")) -} - -func openCodeBlock(prv string, line string) (string, bool) { - matches := commentType.FindStringSubmatch(prv) - filename := commentType.SubexpIndex("filename") - if len(matches) != 0 && filename != -1 { - if strings.Contains(prv, "data-target=append") { - return `
`, true
-		}
-		return `
`, true
-	}
-
-	return line, false
-}
-
-// Defines a micro-sytax for fenced code blocks and frontmatter
-//
-// A fenced code block is $``` (where $ is the beginning of a line) followed by
-// an optional language definition.  If the fenced code block is to replace or
-// append to a katacoda file, then the line prior to the fence must contain
-//   file=the/file/name
-// an optional
-//   data-target=append
-// marks the fenced code block as appending to the named file rather than the
-// default which is to replace it.
-//
-// Replace a file
-//   
-//   ```bash
-//   #!/usr/bin/env bash
-//   ```
-// Append to a file
-//   
-//   ```bash
-//   #!/usr/bin/env bash
-//   ```
-// This works well with the existing test framework, eg: Test a file and mark it
-// for replacement
-//   
-//   ```bash
-//   #!/usr/bin/env bash
-//   ````
-func preprocessor(lines []string) []string {
-	var (
-		buf           []string
-		closePreFlag  = false
-		inFrontMatter = false
-	)
-	for _, s := range lines {
-
-		// Perform any globally required replacments
-		for key, value := range replacements {
-			s = strings.ReplaceAll(s, key, value)
-		}
-
-		// Open code block
-		if strings.HasPrefix(s, "```") && !closePreFlag {
-			prv := buf[len(buf)-1]
-			var codeblock string
-			codeblock, closePreFlag = openCodeBlock(prv, s)
-			buf = append(buf, codeblock)
-			// Close code block
-		} else if strings.HasPrefix(s, "```") && closePreFlag {
-			buf = append(buf, "
"+s[3:]) - closePreFlag = false - } else if strings.HasPrefix(s, "+++") && !inFrontMatter { - inFrontMatter = true - } else if strings.HasPrefix(s, "+++") && inFrontMatter { - inFrontMatter = false - } else if inFrontMatter { - fmatter := strings.Split(s, "=") - if "title" == fmatter[0] { - buf = append(buf, "# "+strings.Trim(fmatter[1], `"`)) - } - } else { - buf = append(buf, s) - } - } - return buf -} - -func getMappings() ([][]string, error) { - file, err := os.Open("katacoda/files.txt") - defer file.Close() - if err != nil { - return nil, err - } - return csv.NewReader(file).ReadAll() -} - -func main() { - files, err := getMappings() - if err != nil { - parseError := err.(*csv.ParseError) - log.Fatalf("unable to read input files, %s on line %d: %w", parseError.Err, parseError.Line, err) - } - docsLinks := regexp.MustCompile(`\(/docs/`) // Links start with LPAREN eg: (foo)[/docs/...] - docsFootnote := regexp.MustCompile(`: /docs/`) // References in footnotes eg: [foo]: /docs/... - for _, mapping := range files { - i := mapping[0] - o := mapping[1] - out, err := os.ReadFile(i) - out = preprocessText(out) - out = docsLinks.ReplaceAll(out, []byte("(https://buildpacks.io/docs/")) - out = docsFootnote.ReplaceAll(out, []byte(": https://buildpacks.io/docs/")) - if err != nil { - log.Fatalf("unable to read input file %s: %s", i, err) - } - t, err := template.New("example").Delims("").Parse(strings.TrimSpace(string(out))) - if err != nil { - log.Fatalf("unable to parse file %s: %s", i, err) - } - d := filepath.Dir(o) - if err := os.MkdirAll(d, 0755); err != nil { - log.Fatalf("unable to create output directory: %s", err) - } - f, err := os.Create(o) - if err != nil { - log.Fatalf("create file: ", err) - } - if err := t.Execute(f, []string{}); err != nil { - log.Fatalf("unable to execute template: %s", err) - } - } -} diff --git a/katacoda/scenarios/app-developer-guide/background.sh b/katacoda/scenarios/app-developer-guide/background.sh deleted file mode 100644 index 0f0f8bcd6..000000000 --- a/katacoda/scenarios/app-developer-guide/background.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -(curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.24.0/pack-v0.24.0-linux.tgz" | sudo tar -C /usr/local/bin/ --no-same-owner -xzv pack) -git clone https://github.com/buildpacks/samples -sudo touch /opt/setup-done -docker pull cnbs/sample-builder:bionic -docker pull buildpacksio/lifecycle diff --git a/katacoda/scenarios/app-developer-guide/build-an-app.md b/katacoda/scenarios/app-developer-guide/build-an-app.md deleted file mode 100644 index 70797a377..000000000 --- a/katacoda/scenarios/app-developer-guide/build-an-app.md +++ /dev/null @@ -1,71 +0,0 @@ -# Build an app -# Build an app - - -Building an app using Cloud Native Buildpacks is as easy as `1`, `2`, `3`... - -### 1. Select a builder - -To [build][build] an app you must first decide which [builder][builder] you're going to use. A builder -includes the [buildpacks][buildpack] that will be used as well as the environment for building your -app. - -When using `pack`, you can run `pack builder suggest` for a list of suggested builders. - -``` -pack builder suggest -```{{execute}} - -For this guide we're actually going to use a sample builder, `cnbs/sample-builder:jammy`, which is not listed -as a suggested builder for good reason. It's a sample. - -### 2. Build your app - -Now that you've decided on what builder to use, we can build our app. For this example we'll use our [samples][samples] -repo for simplicity. - -1. Check that the samples repo exists and if not - we clone it -``` -ls samples || git clone https://github.com/buildpacks/samples -```{{execute}} - -2. Build the app -``` -pack build sample-app --path samples/apps/java-maven --builder cnbs/sample-builder:jammy -```{{execute}} - -> **TIP:** If you don't want to keep specifying a builder every time you build, you can set it as your default -> builder by running `pack config default-builder ` for example `pack config default-builder cnbs/sample-builder:jammy`{{execute}} - -### 3. Run it - -``` -docker run --rm -p 8080:8080 sample-app -```{{execute}} - -**Congratulations!** - - -Now open your favorite browser and point it to port "8080" of your host and take a minute to enjoy the view. - -On Katacoda you can do this by [clicking here](https://[[HOST_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com) - - -## What about ARM apps? - -Linux ARM image builds are now supported! - - -Check out the [Linux ARM build guide](https://buildpacks.io//docs/app-developer-guide/build-an-arm-app). - -## What about Windows apps? - -Windows image builds are now supported! - -Check out the [Windows build guide](https://buildpacks.io/docs/app-developer-guide/build-a-windows-app/). - - -[build]: https://buildpacks.io/docs/concepts/operations/build -[builder]: https://buildpacks.io/docs/concepts/components/builder -[buildpack]: https://buildpacks.io/docs/concepts/components/buildpack -[samples]: https://github.com/buildpacks/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/cache-image-bg.sh b/katacoda/scenarios/app-developer-guide/cache-image-bg.sh deleted file mode 100644 index 6f33d0d34..000000000 --- a/katacoda/scenarios/app-developer-guide/cache-image-bg.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -docker run -e REGISTRY_STORAGE_DELETE_ENABLED=true -d -p 5000:5000 --restart=always --name registry registry:2 diff --git a/katacoda/scenarios/app-developer-guide/environment-variables.md b/katacoda/scenarios/app-developer-guide/environment-variables.md deleted file mode 100644 index 08c23278c..000000000 --- a/katacoda/scenarios/app-developer-guide/environment-variables.md +++ /dev/null @@ -1,136 +0,0 @@ -# Environment variables -# Environment variables - -Environment variables are a common way to configure various buildpacks at build-time. - -Below are a few ways you can do so. All of them will use our [samples][samples] repo for simplicity. - -### Using CLI arguments (`--env`) - -The `--env` parameter must be one of the following: - -- `VARIABLE=VALUE` -- `VARIABLE`, where the value of `VARIABLE` will be taken from the local environment - -##### Example: - -1. Set an environment variable -``` -export FOO=BAR -```{{execute}} - -2. Build the app -``` -pack build sample-app \ - --env "HELLO=WORLD" \ - --env "FOO" \ - --builder cnbs/sample-builder:jammy \ - --buildpack samples/buildpacks/hello-world/ \ - --buildpack samples/apps/bash-script/bash-script-buildpack/ \ - --path samples/apps/bash-script/ -```{{execute}} - -3. Run the app -``` -docker run sample-app -```{{execute}} - -The following environment variables were set and available to buildpacks at build-time: - -| Name | Value | _Source_ | -|---------|---------|----------------------------| -| `HELLO` | `WORLD` | _hard-coded inline value_ | -| `FOO` | `BAR` | _current environment_ | - - -### Using env files (`--env-file`) - -The `--env-file` parameter must be a path to a file where each line is one of the following: - -- `VARIABLE=VALUE` -- `VARIABLE`, where the value of `VARIABLE` will be taken from the current environment - -##### Example: - -1. Set an environment variable -``` -export FOO=BAR -```{{execute}} - -2. Create an env file -``` -echo -en "HELLO=WORLD\nFOO" > ./envfile -```{{execute}} - -3. Build the app -``` -pack build sample-app \ - --env-file ./envfile \ - --builder cnbs/sample-builder:jammy \ - --buildpack samples/buildpacks/hello-world/ \ - --buildpack samples/apps/bash-script/bash-script-buildpack/ \ - --path samples/apps/bash-script/ -```{{execute}} - -4. Run the app -``` -docker run sample-app -```{{execute}} - -The following environment variables were set and available to buildpacks at build-time: - -| Name | Value | _Source_ | -|---------|---------|----------------------------| -| `HELLO` | `WORLD` | _hard-coded value in file_ | -| `FOO` | `BAR` | _current environment_ | - - - -> **NOTE:** Variables defined using `--env` take precedence over variables defined in `--env-file`. - -### Using Project Descriptor -The `--descriptor` parameter must be a path to a file which follows the project.toml [schema][descriptor-schema]. -Without the `--descriptor` flag, `pack build` will use the `project.toml` file in the application directory if it exists. -You can define environment variables in an `env` table in the file, and pass those into the application. - -##### Example: - -1. Add an environment variable to the project.toml - -``` -cat >> samples/apps/bash-script/project.toml < **NOTE:** Variables defined using `--env` or `--env-file` take precedence over variables defined in the `project.toml`. - -> **NOTE:** `project.toml` can't detect environment variables (so, for instance, if one ran `export FOO=BAR` and added ->`name=FOO` to the `project.toml`, it wouldn't detect any value set for `FOO`). - -[descriptor-schema]: https://buildpacks.io/docs/reference/project-descriptor/ -[samples]: https://github.com/buildpacks/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/foreground.sh b/katacoda/scenarios/app-developer-guide/foreground.sh deleted file mode 100644 index c1f23794b..000000000 --- a/katacoda/scenarios/app-developer-guide/foreground.sh +++ /dev/null @@ -1 +0,0 @@ -echo "Waiting for environment to be set up"; while [ ! -f /opt/setup-done ] ; do sleep 1; done; echo "Done" \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/index.json b/katacoda/scenarios/app-developer-guide/index.json deleted file mode 100644 index 923a005c9..000000000 --- a/katacoda/scenarios/app-developer-guide/index.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "title": "App Developer’s Guide", - "description": "Learn how to build and customize your application image using Cloud Native Buildpacks", - "difficulty": "Beginner", - "time": "30", - "details": { - "steps": [ - { - "title": "Build an App", - "text": "build-an-app.md" - }, - { - "title": "Environment Variables", - "text": "environment-variables.md" - }, - { - "title": "Cache Images", - "text": "using-cache-image.md", - "courseData": "cache-image-bg.sh" - }, - { - "title": "Mounting Volumes", - "text": "mounting-volumes.md" - }, - { - "title": "Specifying Buildpacks", - "text": "specify-buildpacks.md" - }, - { - "title": "Specify launch process", - "text": "run-an-app.md" - } - ], - "intro": { - "courseData": "background.sh", - "code": "foreground.sh", - "text": "intro.md" - } - }, - "environment": { - "uilayout": "terminal" - }, - "backend": { - "imageid": "ubuntu:2004" - } -} \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/intro.md b/katacoda/scenarios/app-developer-guide/intro.md deleted file mode 100644 index ce57923c0..000000000 --- a/katacoda/scenarios/app-developer-guide/intro.md +++ /dev/null @@ -1 +0,0 @@ -In this scenario you will learn how to create a container image from your application source code using [`pack`](https://buildpacks.io/docs/app-developer-guide/build-an-app/) and `Cloud native buildpacks`. \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/mounting-volumes.md b/katacoda/scenarios/app-developer-guide/mounting-volumes.md deleted file mode 100644 index bca29e92b..000000000 --- a/katacoda/scenarios/app-developer-guide/mounting-volumes.md +++ /dev/null @@ -1,101 +0,0 @@ -# Mounting Volumes - -# Mounting Volumes - -Volumes are a mechanism for both supplying and persisting data generated by build containers. - - -## Mounting Volumes (`--volume`) - -The `--volume` parameter must be one of the following: - - - A volume mount. - - A comma separated list of volume mounts. - -Each volume mount has the following format: -``` -:[:] -``` - -##### `` -This is the name of the volume, it is unique on a given host machine. - -##### `` -The path where the file or directory is available in the container. - -##### `[:]` -An optional comma separated list of mount options. If no options are provided, the read-only option will be used. -A mount option must be one of the following: - - `ro`, volume contents are read-only. - - `rw`, volume contents are readable and writeable. - - `volume-opt=key=value`, can be specified more than once, takes a key-value pair consisting of the option name and its value. - - -### Examples -For the following examples we will use our [samples][samples] repo for simplicity. - -Here we bind mount a local folder into our container and display its contents during -a `pack build`. - -#### Linux container example - - - - - - - - - -We'll create a new docker volume: - - -```bash -docker volume create test-volume -```{{execute}} - -Next, we'll create a text file on the volume: - - -```bash -docker run --rm \ - --volume test-volume:/tmp/volume:rw \ - bash \ - bash -c 'echo "Hello from a volume!" > /tmp/volume/volume_contents.txt' -```{{execute}} - -Now, we can mount this volume during `pack build`: - - -```bash -ls -al -pack build volume-example \ - --builder cnbs/sample-builder:jammy \ - --buildpack samples/buildpacks/hello-world \ - --path samples/apps/bash-script \ - --volume test-volume:/platform/volume:ro -```{{execute}} - -The above `pack build ...` command will mount the `test-volume` volume in the `/platform` directory of the container. - -Since we are using the `samples/hello-world` buildpack, we should see the `/platform` directory files listed: - -```text -[builder] platform_dir files: -... -[builder] /platform/volume: -[builder] total 12 -[builder] drwxr-xr-x 2 root root 4096 Sep 17 20:17 . -[builder] drwxr-xr-x 1 root root 4096 Sep 17 20:18 .. -[builder] -rw-r--r-- 1 root root 21 Sep 17 20:18 volume_contents.txt -``` - -[samples]: https://github.com/buildpack/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/run-an-app.md b/katacoda/scenarios/app-developer-guide/run-an-app.md deleted file mode 100644 index 300081d31..000000000 --- a/katacoda/scenarios/app-developer-guide/run-an-app.md +++ /dev/null @@ -1,147 +0,0 @@ -# Specify launch process -# Specify launch process - -Learn how to specify the launch process for an app. - - -### Build a multi-process app - -For this example we will use the `hello-processes` buildpack from our [samples][samples] repo so make sure you have it cloned locally. - -Let's build the app. -``` -pack build multi-process-app \ - --builder cnbs/sample-builder:alpine \ - --buildpack samples/java-maven \ - --buildpack samples/buildpacks/hello-processes/ \ - --path samples/apps/java-maven/ -```{{execute}} - -If you inspect the app image with `pack`, you will see multiple process types defined: - -``` -pack inspect-image multi-process-app -```{{execute}} - -The output should look similar to the below: - -``` -Inspecting image: multi-process-app - -REMOTE: -(not present) - -LOCAL: - -Stack: io.buildpacks.samples.stacks.alpine - -Base Image: - Reference: f5898fb2b30c2b66f5a69a424bae6473259fa48b387df35335f04332af7f1091 - Top Layer: sha256:700c764e7c5d5c75e6a0fc7d272b7e1c70ab327c03fbdf4abd9313e5ec3217f7 - -Run Images: - cnbs/sample-base-run:alpine - -Rebasable: true - -Buildpacks: - ID VERSION HOMEPAGE - samples/java-maven 0.0.1 https://github.com/buildpacks/samples/tree/main/buildpacks/java-maven - samples/hello-processes 0.0.1 https://github.com/buildpacks/samples/tree/main/buildpacks/hello-process - -Processes: - TYPE SHELL COMMAND ARGS - web (default) bash java -jar target/sample-0.0.1-SNAPSHOT.jar - sys-info bash /layers/samples_hello-processes/sys-info/sys-info.sh -``` - -Notice that the default process type is `web`. This is because `pack` will always attempt to set the default process type to `web` unless the `--default-process` flag is passed. -If we had run the `pack build` command above with `--default-process sys-info`, `sys-info` would be the default process for the app image! - -### Run a multi-process app - -Buildpacks are designed to give you much flexibility in how you run your app. The lifecycle includes a binary called the `launcher` which is present in the final app image and is responsible for starting your app. -By default, the `launcher` will start processes with `bash` (these are referred to as `non-direct` processes). Processes that are started without `bash` are referred to as `direct` processes. -The `launcher` will source any profile scripts (for `non-direct` processes) and set buildpack-provided environment variables in the app's execution environment before starting the app process. - -#### Default process type - -If you would like to run the default process, you can simply run the app image without any additional arguments: - -``` -docker run --rm -p 8080:8080 multi-process-app -```{{execute}} - -#### Default process type with additional arguments - -If you would like to pass additional arguments to the default process, you can run the app image with the arguments specified in the command: - -``` -docker run --rm -p 8080:8080 multi-process-app --spring.profiles.active=mysql -```{{execute interrupt}} - -#### Non-default process-type - -To run a non-default process type, set the process type as the entrypoint for the run container: - -``` -docker run --rm --entrypoint sys-info multi-process-app -```{{execute interrupt}} - -#### Non-default process-type with additional arguments - -You can pass additional arguments to a non-default process type: - -``` -docker run --rm --entrypoint sys-info multi-process-app --spring.profiles.active=mysql -```{{execute interrupt}} - -#### User-provided shell process - -You can even override the buildpack-defined process types: - -``` -docker run --rm --entrypoint launcher -it multi-process-app bash -```{{execute interrupt}} - -Now let's exit this shell and run an alternative entrypoint - -``` -exit -```{{execute interrupt}} -``` -docker run --rm --entrypoint launcher -it multi-process-app echo hello "$WORLD" # $WORLD is evaluated on the host machine -```{{execute interrupt}} -``` -docker run --rm --entrypoint launcher -it multi-process-app echo hello '$WORLD' # $WORLD is evaluated in the container after profile scripts are sourced -```{{execute interrupt}} - -#### User-provided shell process with bash script - -An entire script may be provided as a single argument: - -``` -docker run --rm --entrypoint launcher -it multi-process-app 'for opt in $JAVA_OPTS; do echo $opt; done' -```{{execute interrupt}} - -#### User-provided direct process - -By passing `--` before the command, we instruct the `launcher` to start the provided process without `bash`. -Note that while buildpack-provided environment variables will be set in the execution environment, no profile scripts will be sourced (as these require `bash`): - -``` -docker run --rm --entrypoint launcher multi-process-app -- env # output will include buildpack-provided env vars -docker run --rm --entrypoint launcher multi-process-app -- echo hello "$WORLD" # $WORLD is evaluated on the host machine -docker run --rm --entrypoint launcher multi-process-app -- echo hello '$WORLD' # $WORLD is not evaluated, output will include string literal `$WORLD` -``` - -#### No launcher - -You can bypass the launcher entirely by setting a new entrypoint for the run container: - -``` -docker run --rm --entrypoint bash -it multi-process-app # profile scripts have NOT been sourced and buildpack-provided env vars are NOT set in this shell -```{{execute interrupt}} - -To learn more about the launcher, see the [platform spec](https://github.com/buildpacks/spec/blob/main/platform.md#launcher). - -[samples]: https://github.com/buildpacks/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/specify-buildpacks.md b/katacoda/scenarios/app-developer-guide/specify-buildpacks.md deleted file mode 100644 index 078297893..000000000 --- a/katacoda/scenarios/app-developer-guide/specify-buildpacks.md +++ /dev/null @@ -1,102 +0,0 @@ -# Specify buildpacks -# Specify buildpacks - - -You may specify exactly what buildpacks are used during the build process by referencing them with a URI in any of the following formats. - -| Type | Format | -|----- |------- | -| Relative | `` | -| Filesystem | `file://[]/` | -| URL | `http[s]:///` | -| Docker | `docker://[]/[:⏐@]` | -| CNB Builder Resource | `urn:cnb:builder[:[@]]` | -| CNB Registry Resource | `urn:cnb:registry[:[@]]` | - -##### Fallback Behavior - -When a string does not include a scheme prefix (ex. `docker://`) and also does not match a path on the filesystem, a platform may attempt to resolve it to a URI in the following order: -- If it matches a buildpack ID in the builder, it will be treated as a `urn:cnb:builder` URI -- If it looks like a Docker ref, it will be treated as a `docker://` URI -- If it looks like a Buildpack Registry ID, it will be treated as a `urn:cnb:registry` URI - -If you need to disambiguate a particular reference, use a fully qualified URI. - -## Using the Pack CLI - -The `--buildpack` parameter accepts a URI in any of the formats described above. - -##### Example: - -For this example we will use a few buildpacks from our [samples][samples] repo. - -``` -pack build sample-java-maven-app \ - --builder cnbs/sample-builder:alpine \ - --buildpack samples/java-maven \ - --buildpack samples/buildpacks/hello-processes/ \ - --buildpack docker://cnbs/sample-package:hello-universe \ - --path samples/apps/java-maven/ -```{{execute}} - -> Multiple buildpacks can be specified, in order, by supplying: -> -> - `--buildpack` multiple times, or -> - a comma-separated list to `--buildpack` (without spaces) - - - -## Using a Project Descriptor - -The [`project.toml`][project-toml] format allows for Buildpack URIs to be specified in the `[[build.buildpacks]]` table with the `uri` key. - -##### Example: - -```toml -[project] -id = "sample-java-maven-app" -name = "Sample Java App" -version = "1.0.0" - -[[build.buildpacks]] -uri = "samples/java-maven" - -[[build.buildpacks]] -uri = "samples/buildpacks/hello-processes/" - -[[build.buildpacks]] -uri = "docker://cnbs/sample-package:hello-univers" -``` - -## URI Examples - -A path to a directory, `tar` file, or `tgz` file - -- `./my/buildpack/` -- `./my/buildpack.tgz` -- `/home/user/my/buildpack.tgz` -- `file:///my/buildpack.tgz` -- `file:///home/user/my/buildpack.tgz` - -A URL to a `tar` or `tgz` file containing a buildpackage -- `http://example.com/my/buildpack.tgz` -- `https://example.com/my/buildpack.tgz` - -A Docker image containing a buildpackage -- `docker://gcr.io/distroless/nodejs` -- `docker:///ubuntu:latest` -- `docker:///ubuntu@sha256:45b23dee08...` - -A buildpack located in a CNB Builder -- `urn:cnb:builder:bp.id` -- `urn:cnb:builder:bp.id@bp.version` - -A buildpack located in a CNB Registry -- `urn:cnb:registry:bp-id` -- `urn:cnb:registry:bp-id@bp.version` - - Directory buildpacks are not currently supported on Windows.
- Version may be omited if there is only one buildpack in the builder matching the `id`. - -[project-toml]: https://buildpacks.io/docs/app-developer-guide/using-project-descriptor/ -[samples]: https://github.com/buildpacks/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-developer-guide/using-cache-image.md b/katacoda/scenarios/app-developer-guide/using-cache-image.md deleted file mode 100644 index 2d4415a8d..000000000 --- a/katacoda/scenarios/app-developer-guide/using-cache-image.md +++ /dev/null @@ -1,78 +0,0 @@ -# Cache Images -# Cache Images - - -Cache Images are a way to preserve build optimizing layers across different host machines. -These images can improve performance when using `pack` in ephemeral environments such as CI/CD pipelines. - - -## Using Cache Images (`--cache-image`) - -The `--cache-image` parameter must be in the following format - -``` ---cache-image -``` - -The `--cache-image` flag must be specified in conjunction with the `--publish` flag. - -### Examples -For the following examples we will use: - - A local [Docker v2 registry running on port `5000`](https://docs.docker.com/registry/deploying/#run-a-local-registry) - - Our [samples][samples] repo - -> **NOTE:** If we wish to publish to an external registry like `Dockerhub` we will first need to authenticate with `docker` to allow us to push images. We can do this via `docker login` - - -Next we trust the `cnbs/sample-builder:jammy` builder in order to allow access to docker credentials when publishing. - -``` -pack config trusted-builders add cnbs/sample-builder:jammy -```{{execute}} - -To build the `localhost:5000/buildpack-examples/cache-image-example` application image - and the `localhost:5000/buildpack-examples/maven-cache-image:latest` cache image - we may run the following - -``` -pack build localhost:5000/buildpack-examples/cache-image-example \ - --builder cnbs/sample-builder:jammy \ - --buildpack samples/java-maven \ - --path samples/apps/java-maven \ - --cache-image localhost:5000/buildpack-examples/maven-cache-image:latest \ - --network host \ - --publish -```{{execute}} - -> **NOTE:** Please omit `--network host` if you are using a remote registry like Dockerhub or on Windows. - -Now we may inspect both the application image, and the cache image by pulling them - - -Let's inspect the application image first - - -``` -docker pull localhost:5000/buildpack-examples/cache-image-example -docker inspect localhost:5000/buildpack-examples/cache-image-example -```{{execute}} - -Now let's take a look at the cache image - -``` -docker pull localhost:5000/buildpack-examples/maven-cache-image:latest -docker inspect localhost:5000/buildpack-examples/maven-cache-image:latest -```{{execute}} - -The cache image we produced may now be used by builds on other machines. Note these -builds may also update the specified `cache-image`. - -The following command will restore data for the `samples/java-maven:maven_m2` layer from the cache image. -``` -pack build localhost:5000/buildpack-examples/second-cache-image-example \ - --builder cnbs/sample-builder:jammy \ - --buildpack samples/java-maven \ - --path samples/apps/java-maven \ - --cache-image localhost:5000/buildpack-examples/maven-cache-image:latest \ - --network host \ - --publish -```{{execute}} - -[samples]: https://github.com/buildpack/samples \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/background.sh b/katacoda/scenarios/app-journey/background.sh deleted file mode 100644 index 6082d992d..000000000 --- a/katacoda/scenarios/app-journey/background.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -(curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.24.0/pack-v0.24.0-linux.tgz" | sudo tar -C /usr/local/bin/ --no-same-owner -xzv pack) -docker pull cnbs/sample-builder:bionic -docker pull buildpacksio/lifecycle -pack config trusted-builders add cnbs/sample-builder:bionic \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/finish.md b/katacoda/scenarios/app-journey/finish.md deleted file mode 100644 index d978ad22a..000000000 --- a/katacoda/scenarios/app-journey/finish.md +++ /dev/null @@ -1,17 +0,0 @@ -## All done - -Congratulations! You have successfully created your first app using buildpacks! - -### Take your image to the skies - -`pack` uses **buildpacks** to help you easily create OCI images that you can run just about anywhere. Try -deploying your new image to your favorite cloud! - -> In case you need it, `pack build` has a handy flag called `--publish` that will build your image directly onto a Docker -> registry. You can learn more about `pack` features in the [documentation][pack-docs]. - - -[builder]: https://buildpacks.io/docs/concepts/components/builder/ -[buildpack]: https://buildpacks.io/docs/concepts/components/buildpack/ -[samples-java-maven]: https://github.com/buildpacks/samples/tree/main/apps/java-maven -[pack-docs]: https://buildpacks.io/docs/tools/pack/ \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/foreground.sh b/katacoda/scenarios/app-journey/foreground.sh deleted file mode 100644 index 6c26f67b8..000000000 --- a/katacoda/scenarios/app-journey/foreground.sh +++ /dev/null @@ -1 +0,0 @@ -echo "Waiting for environment to be set up"; while [ ! -f /usr/local/bin/pack ] ; do sleep 1; done; echo "Done" \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/index.json b/katacoda/scenarios/app-journey/index.json deleted file mode 100644 index 5d83dd01f..000000000 --- a/katacoda/scenarios/app-journey/index.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "title": "An App’s Brief Journey from Source to Image", - "description": "Create an application container image using Cloud Native Buildpacks", - "difficulty": "Beginner", - "time": "10", - "details": { - "steps": [ - { - "title": "Step 1", - "text": "step1.md" - } - ], - "intro": { - "courseData": "background.sh", - "code": "foreground.sh", - "text": "intro.md" - }, - "finish": { - "text": "finish.md" - } - }, - "environment": { - "uilayout": "terminal" - }, - "backend": { - "imageid": "ubuntu:2004" - } -} \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/intro.md b/katacoda/scenarios/app-journey/intro.md deleted file mode 100644 index ce57923c0..000000000 --- a/katacoda/scenarios/app-journey/intro.md +++ /dev/null @@ -1 +0,0 @@ -In this scenario you will learn how to create a container image from your application source code using [`pack`](https://buildpacks.io/docs/app-developer-guide/build-an-app/) and `Cloud native buildpacks`. \ No newline at end of file diff --git a/katacoda/scenarios/app-journey/step1.md b/katacoda/scenarios/app-journey/step1.md deleted file mode 100644 index ce3811665..000000000 --- a/katacoda/scenarios/app-journey/step1.md +++ /dev/null @@ -1,94 +0,0 @@ -# An App's Brief Journey from Source to Image - -## Pack for the journey - -In this tutorial, we'll explain how to use `pack` and **buildpacks** to create a runnable app image from source code. - -> **NOTE:** `pack` is only one implementation of the [Cloud Native Buildpacks Platform Specification][cnb-platform-spec]. Additionally, not all Cloud Native Buildpacks Platforms require Docker. - -[cnb-platform-spec]: https://github.com/buildpacks/spec/blob/main/platform.md - -## Buildpack base camp - -Before we set out, you'll need to know the basics of **buildpacks** and how they work. - -### What is a [buildpack][buildpack]? - -A buildpack is something you've probably leveraged without knowing, as they're currently -being used in many cloud platforms. A buildpack's job is to gather everything your app needs to build and run, -and it often does this job quickly and quietly. - -That said, while buildpacks are often a behind-the-scenes detail, they are at the heart of transforming your source -code into a runnable app image. - -##### Auto-detection - -What enables buildpacks to go unnoticed is auto-detection. This happens when a platform sequentially -tests groups of buildpacks against your app's source code. The first group that deems itself fit for your source code -will become the selected set of buildpacks for your app. Detection criteria is specific to each buildpack -- for -instance, an **NPM buildpack** might look for a `package.json`, and a **Go buildpack** might look for Go source files. - -### What is a [builder][builder]? - -A builder is an image that contains all the components necessary to execute a build. A builder image is created by taking a build image and adding a lifecycle, buildpacks, and files that configure aspects of the build including the buildpack detection order and the location(s) of the run image. - -## Next stop, the end - -Let's see all this in action using `pack build`. - -Run the following commands in a shell to clone and build this [simple Java app][samples-java-maven]. - -1. Clone the samples repo. -``` -git clone https://github.com/buildpacks/samples -```{{execute}} - -2. Go to the Java apps sub-directory -``` -cd samples/apps/java-maven -```{{execute}} - -3. Build the app using [`pack`][pack-docs] -``` -pack build myapp --builder cnbs/sample-builder:jammy -```{{execute}} - - -> **NOTE:** This is your first time running `pack build` for `myapp`, so you'll notice that -> **the build might take longer than usual.** Subsequent builds will take advantage of various forms of caching. -> If you're curious, try running `pack build myapp` a second time to see the difference in build time. - -**That's it!** You've now got a runnable app image called `myapp` available on your local Docker daemon. -We did say this was a *brief* journey after all. Take note that your app was built without needing to install -a JDK, run Maven, or otherwise configure a build environment. `pack` and **buildpacks** took care of that for you. - - -## Beyond the journey - -To test out your new app image locally, you can run it with Docker: - -```bash -docker run --rm -p 8080:8080 myapp -```{{execute}} - -Now open your favorite browser and point it to port "8080" of your host and take a minute to enjoy the view. - -On Katacoda you can do this by [clicking here](https://[[HOST_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com) - - -### Take your image to the skies - -`pack` uses **buildpacks** to help you easily create OCI images that you can run just about anywhere. Try -deploying your new image to your favorite cloud! - -> In case you need it, `pack build` has a handy flag called `--publish` that will build your image directly onto a Docker -> registry. You can learn more about `pack` features in the [documentation][pack-docs]. - -## What about Windows apps? - -Windows image builds are now supported! - -[builder]: https://buildpacks.io/docs/concepts/components/builder/ -[buildpack]: https://buildpacks.io/docs/concepts/components/buildpack/ -[samples-java-maven]: https://github.com/buildpacks/samples/tree/main/apps/java-maven -[pack-docs]: https://buildpacks.io/docs/tools/pack/ \ No newline at end of file diff --git a/katacoda/scenarios/assets/avatar.png b/katacoda/scenarios/assets/avatar.png deleted file mode 100644 index 26d2c553b..000000000 Binary files a/katacoda/scenarios/assets/avatar.png and /dev/null differ diff --git a/katacoda/scenarios/buildpack-author-guide/adding-bill-of-materials.md b/katacoda/scenarios/buildpack-author-guide/adding-bill-of-materials.md deleted file mode 100644 index 63bad20fd..000000000 --- a/katacoda/scenarios/buildpack-author-guide/adding-bill-of-materials.md +++ /dev/null @@ -1,263 +0,0 @@ -# Adding Bill-of-Materials - - - -One of the benefits of buildpacks is they can also populate the app image with metadata from the build process, allowing you to audit the app image for information like: - -* The process types that are available and the commands associated with them -* The run-image the app image was based on -* The buildpacks were used to create the app image -* And more...! - -You can find some of this information using `pack` via its `inspect-image` command. The bill-of-materials information will be available using `pack sbom download`. - - -```bash -pack inspect-image test-ruby-app -```{{execute}} -You should see the following: - - -```text -Run Images: - cnbs/sample-base-run:jammy -... - -Buildpacks: - ID VERSION HOMEPAGE - examples/ruby 0.0.1 - - -Processes: - TYPE SHELL COMMAND ARGS WORK DIR - web (default) bash bundle exec ruby app.rb /workspace - worker bash bundle exec ruby worker.rb /workspace -``` - -Apart from the above standard metadata, buildpacks can also populate information about the dependencies they have provided in form of a `Bill-of-Materials`. Let's see how we can use this to populate information about the version of `ruby` that was installed in the output app image. - -To add the `ruby` version to the output of `pack download sbom`, we will have to provide a [Software `Bill-of-Materials`](https://en.wikipedia.org/wiki/Software_bill_of_materials) (`SBOM`) containing this information. There are three "standard" ways to report SBOM data. You'll need to choose to use on of [CycloneDX](https://cyclonedx.org/), [SPDX](https://spdx.dev/) or [Syft](https://github.com/anchore/syft) update the `ruby.sbom.` (where `` is the extension appropriate for your SBOM standard, one of `cdx.json`, `spdx.json` or `syft.json`) at the end of your `build` script. Discussion of which SBOM format to choose is outside the scope of this tutorial, but we will note that the SBOM format you choose to use is likely to be the output format of any SBOM scanner (eg: [`syft cli`](https://github.com/anchore/syft)) you might choose to use. In this example we will use the CycloneDX json format. - -First, annotate the `buildpack.toml` to specify that it emits CycloneDX: - - -
-# Buildpack API version
-api = "0.8"
-
-# Buildpack ID and metadata
-[buildpack]
-  id = "examples/ruby"
-  version = "0.0.1"
-  sbom-formats = [ "application/vnd.cyclonedx+json" ]
-
-# Targets the buildpack will work with
-[[targets]]
-os = "linux"
-
-# Stacks (deprecated) the buildpack will work with
-[[stacks]]
-  id = "io.buildpacks.samples.stacks.jammy"
-
- -Then, in our buildpack implementation we will generate the necessary SBOM metadata: - -```bash -# ... - -# Append a Bill-of-Materials containing metadata about the provided ruby version -cat >> "$layersdir/ruby.sbom.cdx.json" << EOL -{ - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "version": 1, - "components": [ - { - "type": "library", - "name": "ruby", - "version": "$ruby_version" - } - ] -} -EOL -``` - -We can also add an SBOM entry for each dependency listed in `Gemfile.lock`. Here we use `jq` to add a new record to the `components` array in `bundler.sbom.cdx.json`: - -```bash -crubybom="${layersdir}/ruby.sbom.cdx.json" -cat >> ${rubybom} << EOL -{ - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "version": 1, - "components": [ - { - "type": "library", - "name": "ruby", - "version": "$ruby_version" - } - ] -} -EOL -if [[ -f Gemfile.lock ]] ; then - for gem in $(gem dep -q | grep ^Gem | sed 's/^Gem //') - do - version=${gem##*-} - name=${gem%-${version}} - DEP=$(jq --arg name "${name}" --arg version "${version}" \ - '.components[.components| length] |= . + {"type": "library", "name": $name, "version": $version}' \ - "${rubybom}") - echo ${DEP} > "${rubybom}" - done -fi -``` - -Your `ruby-buildpack/bin/build`{{open}} script should look like the following: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-plan=$3
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-ruby_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "ruby") | .metadata.version')
-echo "---> Downloading and extracting Ruby $ruby_version"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-$ruby_version.tgz
-wget -q -O - "$ruby_url" | tar -xJf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# 6. INSTALL GEMS
-# Compares previous Gemfile.lock checksum to the current Gemfile.lock
-bundlerlayer="$layersdir/bundler"
-local_bundler_checksum=$((sha256sum Gemfile.lock || echo 'DOES_NOT_EXIST') | cut -d ' ' -f 1)
-remote_bundler_checksum=$(cat "$layersdir/bundler.toml" | yj -t | jq -r .metadata.checksum 2>/dev/null || echo 'DOES_NOT_EXIST')
-# Always set the types table so that we re-use the appropriate layers
-echo -e '[types]\ncache = true\nlaunch = true' >> "$layersdir/bundler.toml"
-
-if [[ -f Gemfile.lock && $local_bundler_checksum == $remote_bundler_checksum ]] ; then
-    # Determine if no gem dependencies have changed, so it can reuse existing gems without running bundle install
-    echo "---> Reusing gems"
-    bundle config --local path "$bundlerlayer" >/dev/null
-    bundle config --local bin "$bundlerlayer/bin" >/dev/null
-else
-    # Determine if there has been a gem dependency change and install new gems to the bundler layer; re-using existing and un-changed gems
-    echo "---> Installing gems"
-    mkdir -p "$bundlerlayer"
-    cat >> "$layersdir/bundler.toml" << EOL
-[metadata]
-checksum = "$local_bundler_checksum"
-EOL
-    bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin"
-
-fi
-
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-# our web process
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-
-# our worker process
-[[processes]]
-type = "worker"
-command = "bundle exec ruby worker.rb"
-EOL
-
-# ========== ADDED ===========
-# 8. ADD A SBOM
-rubybom="${layersdir}/ruby.sbom.cdx.json"
-cat >> ${rubybom} << EOL
-{
-  "bomFormat": "CycloneDX",
-  "specVersion": "1.4",
-  "version": 1,
-  "components": [
-    {
-      "type": "library",
-      "name": "ruby",
-      "version": "$ruby_version"
-    }
-  ]
-}
-EOL
-if [[ -f Gemfile.lock ]] ; then
-  for gem in $(gem dep -q | grep ^Gem | sed 's/^Gem //')
-  do
-    version=${gem##*-}
-    name=${gem%-${version}}
-    DEP=$(jq --arg name "${name}" --arg version "${version}" \
-      '.components[.components| length] |= . + {"type": "library", "name": $name, "version": $version}' \
-      "${rubybom}")
-    echo ${DEP} > "${rubybom}"
-  done
-fi
-
- -Then rebuild your app using the updated buildpack: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -Viewing your bill-of-materials requires extracting (or `download`ing) the bill-of-materials from your local image. This command can take some time to return. - - -```bash -pack sbom download test-ruby-app -```{{execute}} - -The SBOM information is now downloaded to the local file system: - - -```bash -cat layers/sbom/launch/examples_ruby/ruby/sbom.cdx.json | jq -M -``` - -You should find that the included `ruby` version is `2.5.0` as expected. - - -```text -{ - "bomFormat": "CycloneDX", - "specVersion": "1.4", - "version": 1, - "components": [ - { - "type": "library", - "name": "ruby", - "version": "3.1.0" - }, -... - ] -} -``` - -Congratulations! You’ve created your first configurable Cloud Native Buildpack that uses detection, image layers, and caching to create an introspectable and runnable OCI image. - -## Going further - -Now that you've finished your buildpack, how about extending it? Try: - -- Caching the downloaded Ruby version -- [Packaging your buildpack for distribution][package-a-buildpack] - -[package-a-buildpack]: https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/ \ No newline at end of file diff --git a/katacoda/scenarios/buildpack-author-guide/background.sh b/katacoda/scenarios/buildpack-author-guide/background.sh deleted file mode 100644 index 5f3037972..000000000 --- a/katacoda/scenarios/buildpack-author-guide/background.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -(curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.24.0/pack-v0.24.0-linux.tgz" | sudo tar -C /usr/local/bin/ --no-same-owner -xzv pack) -docker pull cnbs/sample-builder:bionic -docker pull buildpacksio/lifecycle -pack config trusted-builders add cnbs/sample-builder:bionic diff --git a/katacoda/scenarios/buildpack-author-guide/build-app.md b/katacoda/scenarios/buildpack-author-guide/build-app.md deleted file mode 100644 index 97a1b6e20..000000000 --- a/katacoda/scenarios/buildpack-author-guide/build-app.md +++ /dev/null @@ -1,136 +0,0 @@ -# Building your application - - - -Now we'll change the build step you created to install application dependencies. This will require updates to the `build` script such that it performs the following steps: - -1. Creates a layer for the Ruby runtime -1. Downloads the Ruby runtime and installs it to the layer -1. Installs Bundler (the Ruby dependency manager) -1. Uses Bundler to install dependencies - -By doing this, you'll learn how to create arbitrary layers with your buildpack, and how to read the contents of the app in order to perform actions like downloading dependencies. - -Let's begin by changing the `ruby-buildpack/bin/build`{{open}} so that it creates a layer for Ruby. - -### Creating a Layer - -A Buildpack layer is represented by a directory inside the [layers directory][layers-dir] provided to our buildpack by the Buildpack execution environment. To create a new layer directory representing the Ruby runtime, change the `build` script to look like this: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-layersdir=$1
-
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
- -The `rubylayer` directory is a sub-directory of the directory provided as the first positional argument to the build script (the [layers directory][layers-dir]), and this is where we'll store the Ruby runtime. - -Next, we'll download the Ruby runtime and install it into the layer directory. Add the following code to the end of the `build` script: - - -
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
- -This code uses the `wget` tool to download the Ruby binaries from the given URL, and extracts it to the `rubylayer` directory. - -The last step in creating a layer is writing a TOML file that contains metadata about the layer. The TOML file's name must match the name of the layer (in this example it's `ruby.toml`). Without this file, the Buildpack lifecycle will ignore the layer directory. For the Ruby layer, we need to ensure it is available in the launch image by setting the `launch` key to `true`. Add the following code to the build script: - - -
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
- -### Installing Dependencies - -Next, we'll use the Ruby runtime you installed to download the application's dependencies. First, we need to make the Ruby executables available to our script by putting it on the Path. Add the following code to the end of the `build` script: - - -
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
- -Now we can install Bundler, a dependency manager for Ruby, and run the `bundle install` command. Append the following code to the script: - - -
-echo "---> Installing gems"
-bundle install
-
- -Now the Buildpack is ready to test. - -### Running the Build - -Your complete `ruby-buildpack/bin/build`{{open}} script should look like this: - - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# 6. INSTALL GEMS
-echo "---> Installing gems"
-bundle install
-
- -Build your app again: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You will see the following output: - -``` -===> DETECTING -... -===> RESTORING -===> BUILDING ----> Ruby Buildpack ----> Downloading and extracting Ruby ----> Installing gems -... -===> EXPORTING -... -Successfully built image 'test-ruby-app' -``` - -A new image named `test-ruby-app` was created in your Docker daemon with a layer containing the Ruby runtime. However, your app image is not yet runnable. We'll make the app image runnable in the next section. - - - -[layers-dir]: https://buildpacks.io/docs/reference/spec/buildpack-api/#layers \ No newline at end of file diff --git a/katacoda/scenarios/buildpack-author-guide/building-blocks-cnb.md b/katacoda/scenarios/buildpack-author-guide/building-blocks-cnb.md deleted file mode 100644 index 6f5c3d474..000000000 --- a/katacoda/scenarios/buildpack-author-guide/building-blocks-cnb.md +++ /dev/null @@ -1,121 +0,0 @@ -# Building blocks of a Cloud Native Buildpack - - - -Now we will set up the buildpack scaffolding. - -Let's create the directory where your buildpack will live: - -## Using the Pack CLI - -The `buildpack new ` command will create a directory named for the buildpack ID. - -Example: - -```bash -pack buildpack new examples/ruby \ - --api 0.8 \ - --path ruby-buildpack \ - --version 0.0.1 \ - --stacks io.buildpacks.samples.stacks.jammy -```{{execute}} -This command will create `ruby-buildpack` directory which contains `buildpack.toml`, `bin/build`, `bin/detect` files. - -### Additional Parameters -- `-a, --api` Buildpack API compatibility of the generated buildpack -- `-h, --help` Help for 'new' -- `--path` the location on the filesystem to generate the artifacts. -- `--stacks` Stack(s) this buildpack will be compatible with. Repeat for each stack in order, or supply once by comma-separated list -- `-V, --version` the version of the buildpack in buildpack.toml - - - -### buildpack.toml - -You will have `ruby-buildpack/buildpack.toml`{{open}} in your buildpack directory to describe our buildpack. - - -
-# Buildpack API version
-api = "0.8"
-
-# Buildpack ID and metadata
-[buildpack]
-  id = "examples/ruby"
-  version = "0.0.1"
-
-# Stacks that the buildpack will work with
-[[stacks]]
-  id = "io.buildpacks.samples.stacks.jammy"
-
-
- -You will notice two specific fields in the file: `buildpack.id` and `stack.id`. The buildpack ID is the way you will reference the buildpack when you create buildpack groups, builders, etc. The stack ID is the root file system in which the buildpack will be run. This example can be run on one of two different stacks, both based upon Ubuntu Bionic. - -### `detect` and `build` - -Next, we will cover the `detect` and `build` scripts. These files are created in `bin` directory in your buildpack directory. - - -Now update your `ruby-buildpack/bin/detect`{{open}} file and copy in the following contents: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-exit 1
-
- -Also update your `ruby-buildpack/bin/build`{{open}} file and copy in the following contents: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-exit 1
-
- -These two files are executable `detect` and `build` scripts. You are now able to use this buildpack. - -### Using your buildpack with `pack` - -In order to test your buildpack, you will need to run the buildpack against your sample Ruby app using the `pack` CLI. - -Set your default [builder][builder] by running the following: - - -```bash -pack config default-builder cnbs/sample-builder:jammy -```{{execute}} - -Tell pack to trust our default builder: - - -```bash -pack config trusted-builders add cnbs/sample-builder:jammy -```{{execute}} - -Then run the following `pack` command: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -The `pack build` command takes in your Ruby sample app as the `--path` argument and your buildpack as the `--buildpack` argument. - -After running the command, you should see that it failed to detect, as the `detect` script is currently written to simply error out. - - -``` -===> DETECTING -... -err: examples/ruby@0.0.1 (1) -... -ERROR: No buildpack groups passed detection. -ERROR: failed to detect: buildpack(s) failed with err -``` - diff --git a/katacoda/scenarios/buildpack-author-guide/caching.md b/katacoda/scenarios/buildpack-author-guide/caching.md deleted file mode 100644 index 44724e6ed..000000000 --- a/katacoda/scenarios/buildpack-author-guide/caching.md +++ /dev/null @@ -1,279 +0,0 @@ -# Improving performance with caching - - - -We can improve performance by caching dependencies between builds, only re-downloading when necessary. To begin, let's create a cacheable `bundler` layer. - -## Creating the `bundler` layer - -To do this, replace the following lines in the `build` script: - -```bash -echo "---> Installing gems" -bundle install -``` - -with the following: - -```bash -echo "---> Installing gems" -bundlerlayer="$layersdir/bundler" -mkdir -p "$bundlerlayer" -echo -e '[types]\ncache = true\nlaunch = true' > "$layersdir/bundler.toml" -bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin" - -``` - -Your full `ruby-buildpack/bin/build`{{open}} script should now look like the following: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# ======= MODIFIED =======
-# 6. INSTALL GEMS
-echo "---> Installing gems"
-bundlerlayer="$layersdir/bundler"
-mkdir -p "$bundlerlayer"
-echo -e '[types]\ncache = true\nlaunch = true' > "$layersdir/bundler.toml"
-bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin"
-
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-# our web process
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-
-# our worker process
-[[processes]]
-type = "worker"
-command = "bundle exec ruby worker.rb"
-EOL
-
- -Now when we run: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You will see something similar to the following during the `EXPORTING` phase: - - -```text -Adding layer 'examples/ruby:bundler' -``` - -## Caching dependencies - -Now, let's implement the caching logic. We'll first need to create a `ruby-sample-app/Gemfile.lock`{{open}} file with the contents given below: - -> Typically you would run `bundle install` locally to generate this file, but for the sake -> of simplicity we'll create `ruby-sample-app/Gemfile.lock` manually. - - -
-GEM
-  remote: https://rubygems.org/
-  specs:
-    mustermann (1.0.3)
-    rack (2.0.7)
-    rack-protection (2.0.7)
-      rack
-    sinatra (2.0.7)
-      mustermann (~> 1.0)
-      rack (~> 2.0)
-      rack-protection (= 2.0.7)
-      tilt (~> 2.0)
-    tilt (2.0.9)
-
-PLATFORMS
-  ruby
-
-DEPENDENCIES
-  sinatra
-
-BUNDLED WITH
-   2.0.2
-
- -Replace the gem installation logic from the previous step: - -```bash -# ... - -echo "---> Installing gems" -bundlerlayer="$layersdir/bundler" -mkdir -p "$bundlerlayer" -echo -e '[types]\ncache = true\nlaunch = true' > "$layersdir/bundler.toml" -bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin" - - -# ... -``` - -with the new logic below that checks to see if any gems have been changed. This simply creates a checksum for the previous `Gemfile.lock` and compares it to the checksum of the current `Gemfile.lock`. If they are the same, the gems are reused. If they are not, the new gems are installed. - -We'll now write additional metadata to our `bundler.toml` of the form `cache = true` and `launch = true`. This directs the lifecycle to cache our gems and provide them when launching our application. With `cache = true` the lifecycle can keep existing gems around so that build times are fast, even with minor `Gemfile.lock` changes. - -Note that there may be times when you would want to clean the cached layer from the previous build, in which case you should always ensure to remove the contents of the layer before proceeding with the build. In the case below this can be done using a simple `rm -rf "$bundlerlayer"/*` after the `mkdir -p "$bundlerlayer"` command. - -```bash -# Compares previous Gemfile.lock checksum to the current Gemfile.lock -bundlerlayer="$layersdir/bundler" -local_bundler_checksum=$((sha256sum Gemfile.lock || echo 'DOES_NOT_EXIST') | cut -d ' ' -f 1) -remote_bundler_checksum=$(cat "$layersdir/bundler.toml" | yj -t | jq -r .metadata.checksum 2>/dev/null || echo 'DOES_NOT_EXIST') - -# Always set the types table so that we re-use the appropriate layers -echo -e '[types]\ncache = true\nlaunch = true' >> "$layersdir/bundler.toml" - -if [[ -f Gemfile.lock && $local_bundler_checksum == $remote_bundler_checksum ]] ; then - # Determine if no gem dependencies have changed, so it can reuse existing gems without running bundle install - echo "---> Reusing gems" - bundle config --local path "$bundlerlayer" >/dev/null - bundle config --local bin "$bundlerlayer/bin" >/dev/null -else - # Determine if there has been a gem dependency change and install new gems to the bundler layer; re-using existing and un-changed gems - echo "---> Installing gems" - mkdir -p "$bundlerlayer" - cat >> "$layersdir/bundler.toml" << EOL -[metadata] -checksum = "$local_bundler_checksum" -EOL - bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin" - -fi -``` - -Your full `ruby-buildpack/bin/build`{{open}} script will now look like this: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# ======= MODIFIED =======
-# 6. INSTALL GEMS
-# Compares previous Gemfile.lock checksum to the current Gemfile.lock
-bundlerlayer="$layersdir/bundler"
-local_bundler_checksum=$((sha256sum Gemfile.lock || echo 'DOES_NOT_EXIST') | cut -d ' ' -f 1)
-remote_bundler_checksum=$(cat "$layersdir/bundler.toml" | yj -t | jq -r .metadata.checksum 2>/dev/null || echo 'DOES_NOT_EXIST')
-# Always set the types table so that we re-use the appropriate layers
-echo -e '[types]\ncache = true\nlaunch = true' >> "$layersdir/bundler.toml"
-
-if [[ -f Gemfile.lock && $local_bundler_checksum == $remote_bundler_checksum ]] ; then
-    # Determine if no gem dependencies have changed, so it can reuse existing gems without running bundle install
-    echo "---> Reusing gems"
-    bundle config --local path "$bundlerlayer" >/dev/null
-    bundle config --local bin "$bundlerlayer/bin" >/dev/null
-else
-    # Determine if there has been a gem dependency change and install new gems to the bundler layer; re-using existing and un-changed gems
-    echo "---> Installing gems"
-    mkdir -p "$bundlerlayer"
-    cat >> "$layersdir/bundler.toml" << EOL
-[metadata]
-checksum = "$local_bundler_checksum"
-EOL
-    bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin"
-
-fi
-
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-# our web process
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-
-# our worker process
-[[processes]]
-type = "worker"
-command = "bundle exec ruby worker.rb"
-EOL
-
- -Now when you build your app: - - -```text -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -it will download the gems: - - -```text -===> BUILDING -... ----> Ruby Buildpack ----> Downloading and extracting Ruby ----> Installing gems -``` - -If you build the app again: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -you will see the new caching logic at work during the `BUILDING` phase: - - -```text -===> BUILDING -... ----> Ruby Buildpack ----> Downloading and extracting Ruby ----> Reusing gems -``` - -Next, let's see how buildpack users may be able to provide configuration to the buildpack. - diff --git a/katacoda/scenarios/buildpack-author-guide/detection.md b/katacoda/scenarios/buildpack-author-guide/detection.md deleted file mode 100644 index 8e152e1c8..000000000 --- a/katacoda/scenarios/buildpack-author-guide/detection.md +++ /dev/null @@ -1,50 +0,0 @@ -# Detecting your application - - - -Next, you will want to actually detect that the app you are building is a Ruby app. In order to do this, you will need to check for a `Gemfile`. - -Replace `exit 1` in the `detect` script with the following check: - -```bash -if [[ ! -f Gemfile ]]; then - exit 100 -fi -``` - -Your `ruby-buildpack/bin/detect`{{open}} script should look like this: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-if [[ ! -f Gemfile ]]; then
-   exit 100
-fi
-
- -Next, rebuild your app with the updated buildpack: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You should see the following output: - -``` -Previous image with name "test-ruby-app" not found -===> DETECTING -examples/ruby 0.0.1 -===> RESTORING -===> BUILDING ----> Ruby Buildpack -ERROR: failed to build: exit status 1 -ERROR: failed to build: executing lifecycle: failed with status code: 51 -``` - -Notice that `detect` now passes because there is a valid `Gemfile` in the Ruby app at `ruby-sample-app`, but now `build` fails because it is currently written to error out. - -You will also notice that `RESTORING` now appears in the build output. This step is part of the buildpack lifecycle that looks to see if any previous image builds have layers that the buildpack can re-use. We will get into this topic in more detail later. - diff --git a/katacoda/scenarios/buildpack-author-guide/foreground.sh b/katacoda/scenarios/buildpack-author-guide/foreground.sh deleted file mode 100644 index 6c26f67b8..000000000 --- a/katacoda/scenarios/buildpack-author-guide/foreground.sh +++ /dev/null @@ -1 +0,0 @@ -echo "Waiting for environment to be set up"; while [ ! -f /usr/local/bin/pack ] ; do sleep 1; done; echo "Done" \ No newline at end of file diff --git a/katacoda/scenarios/buildpack-author-guide/index.json b/katacoda/scenarios/buildpack-author-guide/index.json deleted file mode 100644 index 5f90252f3..000000000 --- a/katacoda/scenarios/buildpack-author-guide/index.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "title": "Buildpack Author's Guide", - "description": "A step-by-step tutorial for creating a Cloud Native Buildpack using simple bash scripts.", - "difficulty": "Intermediate", - "time": "30", - "details": { - "steps": [ - { - "title": "Setup your Environment", - "text": "setup-local-environment.md" - }, - { - "title": "Building blocks of a Cloud Native Buildpack", - "text": "building-blocks-cnb.md" - }, - { - "title": "Detecting your application", - "text": "detection.md" - }, - { - "title": "Building your application", - "text": "build-app.md" - }, - { - "title": "Making your application runnable", - "text": "make-app-runnable.md" - }, - { - "title": "Specfiying multiple process types", - "text": "specify-multiple-process-types.md" - }, - { - "title": "Improving performance with caching", - "text": "caching.md" - }, - { - "title": "Making your buildpack configurable", - "text": "make-buildpack-configurable.md" - }, - { - "title": "Adding a Bill-of-Materials", - "text": "adding-bill-of-materials.md" - } - ], - "intro": { - "courseData": "background.sh", - "code": "foreground.sh", - "text": "intro.md" - } - }, - "environment": { - "uilayout": "vscode-terminal-split" - }, - "backend": { - "imageid": "ubuntu:2004" - } -} \ No newline at end of file diff --git a/katacoda/scenarios/buildpack-author-guide/intro.md b/katacoda/scenarios/buildpack-author-guide/intro.md deleted file mode 100644 index 2565b0e40..000000000 --- a/katacoda/scenarios/buildpack-author-guide/intro.md +++ /dev/null @@ -1,16 +0,0 @@ -# Create a buildpack - - - -This is a step-by-step tutorial for creating a Ruby Cloud Native Buildpack. - -- [Set up your local environment](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/setup-local-environment) -- [Building blocks of a Cloud Native Buildpack](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/building-blocks-cnb) -- [Detecting your application](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/detection) -- [Building your application](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/build-app) -- [Making your application runnable](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/make-app-runnable) -- [Specifying multiple process types](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/specify-multiple-process-types) -- [Improving performance with caching](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/caching) -- [Making your buildpack configurable](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/make-buildpack-configurable) -- [Adding a Bill-of-Materials](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/adding-bill-of-materials) - diff --git a/katacoda/scenarios/buildpack-author-guide/make-app-runnable.md b/katacoda/scenarios/buildpack-author-guide/make-app-runnable.md deleted file mode 100644 index ca8c8745a..000000000 --- a/katacoda/scenarios/buildpack-author-guide/make-app-runnable.md +++ /dev/null @@ -1,89 +0,0 @@ -# Make your application runnable - - - -To make your app runnable, a default start command must be set. You'll need to add the following to the end of your `build` script: - - -
-# ...
-
-# Set default start command
-cat > "$layersdir/launch.toml" << EOL
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-EOL
-
-# ...
-
- -Your full `ruby-buildpack/bin/build`{{open}} script should now look like the following: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# 6. INSTALL GEMS
-echo "---> Installing gems"
-bundle install
-
-# ========== ADDED ===========
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-EOL
-
- -Then rebuild your app using the updated buildpack: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You should then be able to run your new Ruby app: - -```bash -docker run --rm -p 8080:8080 test-ruby-app -```{{execute}} - -and see the server log output: - -```text -[2019-04-02 18:04:48] INFO WEBrick 1.4.2 -[2019-04-02 18:04:48] INFO ruby 2.5.1 (2018-03-29) [x86_64-linux] -== Sinatra (v2.0.5) has taken the stage on 8080 for development with backup from WEBrick -[2019-04-02 18:04:48] INFO WEBrick::HTTPServer#start: pid=1 port=8080 -``` - -Test it out by navigating to [here](https://[[HOST_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com) in your favorite browser! - -We can add multiple process types to a single app. We'll do that in the next section. - diff --git a/katacoda/scenarios/buildpack-author-guide/make-buildpack-configurable.md b/katacoda/scenarios/buildpack-author-guide/make-buildpack-configurable.md deleted file mode 100644 index 20f9cc784..000000000 --- a/katacoda/scenarios/buildpack-author-guide/make-buildpack-configurable.md +++ /dev/null @@ -1,134 +0,0 @@ -# Making your buildpack configurable - - - -It's likely that not all Ruby apps will want to use the same version of Ruby. Let's make the Ruby version configurable. - -## Select Ruby version - -We'll allow buildpack users to define the desired Ruby version via a `.ruby-version` file in their app. We'll first update the `detect` script to check for this file. We will then record the dependency we can `provide` (Ruby), as well as the specific dependency the application will `require`, in the `Build Plan`, a document the lifecycle uses to determine if the buildpack will provide everything the application needs. - -Update `ruby-buildpack/bin/detect` to look like this: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-if [[ ! -f Gemfile ]]; then
-   exit 100
-fi
-
-# ======= ADDED =======
-plan=$2
-version=3.1.3
-
-if [[ -f .ruby-version ]]; then
-    version=$(cat .ruby-version | tr -d '[:space:]')
-fi
-
-echo "provides = [{ name = \"ruby\" }]" > "$plan"
-echo "requires = [{ name = \"ruby\", metadata = { version = \"$version\" } }]" >> "$plan"
-# ======= /ADDED =======
-
- -Then you will need to update your `build` script to look for the recorded Ruby version in the build plan: - -Your `ruby-buildpack/bin/build` script should look like the following: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# ======= MODIFIED =======
-# 1. GET ARGS
-layersdir=$1
-plan=$3
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# ======= MODIFIED =======
-# 3. DOWNLOAD RUBY
-ruby_version=$(cat "$plan" | yj -t | jq -r '.entries[] | select(.name == "ruby") | .metadata.version')
-echo "---> Downloading and extracting Ruby $ruby_version"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-$ruby_version.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# 6. INSTALL GEMS
-# Compares previous Gemfile.lock checksum to the current Gemfile.lock
-bundlerlayer="$layersdir/bundler"
-local_bundler_checksum=$((sha256sum Gemfile.lock || echo 'DOES_NOT_EXIST') | cut -d ' ' -f 1)
-remote_bundler_checksum=$(cat "$layersdir/bundler.toml" | yj -t | jq -r .metadata.checksum 2>/dev/null || echo 'DOES_NOT_EXIST')
-# Always set the types table so that we re-use the appropriate layers
-echo -e '[types]\ncache = true\nlaunch = true' >> "$layersdir/bundler.toml"
-
-if [[ -f Gemfile.lock && $local_bundler_checksum == $remote_bundler_checksum ]] ; then
-    # Determine if no gem dependencies have changed, so it can reuse existing gems without running bundle install
-    echo "---> Reusing gems"
-    bundle config --local path "$bundlerlayer" >/dev/null
-    bundle config --local bin "$bundlerlayer/bin" >/dev/null
-else
-    # Determine if there has been a gem dependency change and install new gems to the bundler layer; re-using existing and un-changed gems
-    echo "---> Installing gems"
-    mkdir -p "$bundlerlayer"
-    cat >> "$layersdir/bundler.toml" << EOL
-[metadata]
-checksum = "$local_bundler_checksum"
-EOL
-    bundle config set --local path "$bundlerlayer" && bundle install && bundle binstubs --all --path "$bundlerlayer/bin"
-
-fi
-
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-# our web process
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-
-# our worker process
-[[processes]]
-type = "worker"
-command = "bundle exec ruby worker.rb"
-EOL
-
- -Finally, create a file `ruby-sample-app/.ruby-version` with the following contents: - - -
-3.1.0
-
- -Now when you run: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You will notice that version of Ruby specified in the app's `.ruby-version` file is downloaded. - - -```text -===> BUILDING -... ----> Ruby Buildpack ----> Downloading and extracting Ruby 3.1.0 -``` - -Next, let's see how buildpacks can store information about the dependencies provided in the output app image for introspection. - diff --git a/katacoda/scenarios/buildpack-author-guide/setup-local-environment.md b/katacoda/scenarios/buildpack-author-guide/setup-local-environment.md deleted file mode 100644 index 55dc34259..000000000 --- a/katacoda/scenarios/buildpack-author-guide/setup-local-environment.md +++ /dev/null @@ -1,82 +0,0 @@ -# Set up your local environment - - - - - - - - - -First, we'll create a sample Ruby app that you can use when developing your buildpack: - - -```bash -mkdir ruby-sample-app -```{{execute}} - -Create a file in the current directory called `ruby-sample-app/app.rb`{{open}} with the following contents: - - -
-require 'sinatra'
-
-set :bind, '0.0.0.0'
-set :port, 8080
-
-get '/' do
-  'Hello World!'
-end
-
- -Then, create a file called `ruby-sample-app/Gemfile`{{open}} with the following contents: - - -
-source "https://rubygems.org"
-
-git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
-
-gem "sinatra"
-
- -Finally, make sure your local Docker daemon is running by executing: - - -```bash -docker version -```{{execute}} - -If you see output similar to the following, you're good to go! Otherwise, start Docker and check again. - -``` -Client: Docker Engine - Community - Version: 20.10.9 - API version: 1.41 - Go version: go1.16.8 - Git commit: c2ea9bc - Built: Mon Oct 4 16:08:29 2021 - OS/Arch: linux/amd64 - Context: default - Experimental: true - -Server: Docker Engine - Community - Engine: - Version: 20.10.9 - API version: 1.41 (minimum version 1.12) - Go version: go1.16.8 - Git commit: 79ea9d3 - Built: Mon Oct 4 16:06:34 2021 - OS/Arch: linux/amd64 - Experimental: false -``` - diff --git a/katacoda/scenarios/buildpack-author-guide/specify-multiple-process-types.md b/katacoda/scenarios/buildpack-author-guide/specify-multiple-process-types.md deleted file mode 100644 index 0a73080d6..000000000 --- a/katacoda/scenarios/buildpack-author-guide/specify-multiple-process-types.md +++ /dev/null @@ -1,114 +0,0 @@ -# Specify multiple process types - - - -One of the benefits of buildpacks is that they are multi-process - an image can have multiple entrypoints for each operational mode. Let's see how this works. We will extend our app to have a worker process. - -Let's create a worker file, `ruby-sample-app/worker.rb`{{open}}, with the following contents: - - -
-for i in 0..5
-    puts "Running a worker task..."
-end
-
- -After building our app, we could run the resulting image with the `web` process (currently the default) or our new worker process. - -To enable running the worker process, we'll need to have our buildpack define a "process type" for the worker. Modify the section where processes are defined to: - -```bash -# ... - -cat > "$layersdir/launch.toml" << EOL -# our web process -[[processes]] -type = "web" -command = "bundle exec ruby app.rb" -default = true - -# our worker process -[[processes]] -type = "worker" -command = "bundle exec ruby worker.rb" -EOL - -# ... -``` - -Your full `ruby-buildpack/bin/build`{{open}} script should now look like the following: - - -
-#!/usr/bin/env bash
-set -eo pipefail
-
-echo "---> Ruby Buildpack"
-
-# 1. GET ARGS
-layersdir=$1
-
-# 2. CREATE THE LAYER DIRECTORY
-rubylayer="$layersdir"/ruby
-mkdir -p "$rubylayer"
-
-# 3. DOWNLOAD RUBY
-echo "---> Downloading and extracting Ruby"
-ruby_url=https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-22/ruby-3.1.3.tgz
-wget -q -O - "$ruby_url" | tar -xzf - -C "$rubylayer"
-
-# 4. MAKE RUBY AVAILABLE DURING LAUNCH
-echo -e '[types]\nlaunch = true' > "$layersdir/ruby.toml"
-
-# 5. MAKE RUBY AVAILABLE TO THIS SCRIPT
-export PATH="$rubylayer"/bin:$PATH
-export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}"$rubylayer/lib"
-
-# 6. INSTALL GEMS
-echo "---> Installing gems"
-bundle install
-
-# ========== MODIFIED ===========
-# 7. SET DEFAULT START COMMAND
-cat > "$layersdir/launch.toml" << EOL
-# our web process
-[[processes]]
-type = "web"
-command = "bundle exec ruby app.rb"
-default = true
-
-# our worker process
-[[processes]]
-type = "worker"
-command = "bundle exec ruby worker.rb"
-EOL
-
- -Now if you rebuild your app using the updated buildpack: - - -```bash -pack build test-ruby-app --path ./ruby-sample-app --buildpack ./ruby-buildpack -```{{execute}} - -You should then be able to run your new Ruby worker process: - - -```bash -docker run --rm --entrypoint worker test-ruby-app -```{{execute}} - -and see the worker log output: - - -```text -Running a worker task... -Running a worker task... -Running a worker task... -Running a worker task... -Running a worker task... -Running a worker task... -``` - -Next, we'll look at how to improve our buildpack by leveraging cache. - diff --git a/themes/buildpacks/layouts/shortcodes/katacoda-button.html b/themes/buildpacks/layouts/shortcodes/katacoda-button.html deleted file mode 100644 index 9c38953fc..000000000 --- a/themes/buildpacks/layouts/shortcodes/katacoda-button.html +++ /dev/null @@ -1,3 +0,0 @@ -{{ if $.Site.Params.featureKatacoda }} -{{- .Inner -}}
-{{ end }} \ No newline at end of file