Skip to content

Instantly share code, notes, and snippets.

@dmikusa
Last active January 10, 2020 04:09
Show Gist options
  • Save dmikusa/67eb684ea3d3606cee6db5995ba4c4e3 to your computer and use it in GitHub Desktop.
Save dmikusa/67eb684ea3d3606cee6db5995ba4c4e3 to your computer and use it in GitHub Desktop.

Notes for Cloud Natvie Buildpacks Talk

https://gist.github.com/dmikusa-pivotal/67eb684ea3d3606cee6db5995ba4c4e3

Running internal Registry

To start:

docker run -d -p 5000:5000 --restart=always -e REGISTRY_STORAGE_DELETE_ENABLED=true -v registry-volume:/var/lib/registry --name registry registry:2

To stop:

docker stop registry

To start again:

docker start registry

If the continaer is deleted, run the original command again. Just don't delete the registry-volume volume or you will need to docker push to the registry again.

Seeding the Registry

Run:

docker pull cloudfoundry/run:full-cnb  # pull latest run image
docker pull cloudfoundry/run:0.0.13-full-cnb # pull latest run image
docker pull cloudfoundry/run:0.0.12-full-cnb # pull previous run image
docker pull cloudfoundry/run:0.0.11-full-cnb # pull previous run image
docker pull cloudfoundry/cnb:cflinuxfs3   # pull latest builder

docker tag cloudfoundry/run:full-cnb localhost:5000/cloudfoundry/run:full-cnb  # tag
docker tag cloudfoundry/run:0.0.13-full-cnb localhost:5000/cloudfoundry/run:0.0.13-full-cnb
docker tag cloudfoundry/run:0.0.12-full-cnb localhost:5000/cloudfoundry/run:0.0.12-full-cnb
docker tag cloudfoundry/run:0.0.11-full-cnb localhost:5000/cloudfoundry/run:0.0.11-full-cnb
docker tag cloudfoundry/cnb:cflinuxfs3 localhost:5000/cloudfoundry/cnb:cflinuxfs3

docker push localhost:5000/cloudfoundry/run:full-cnb  # push images to local repo
docker push localhost:5000/cloudfoundry/run:0.0.13-full-cnb
docker push localhost:5000/cloudfoundry/run:0.0.12-full-cnb
docker push localhost:5000/cloudfoundry/run:0.0.11-full-cnb
docker push localhost:5000/cloudfoundry/cnb:cflinuxfs3

# delete them from the local docker so they are only in the registry (optional)
docker rmi cloudfoundry/cnb:cflinuxfs3 cloudfoundry/run:full-cnb cloudfoundry/run:0.0.13-full-cnb cloudfoundry/run:0.0.12-full-cnb cloudfoundry/run:0.0.11-full-cnb

Fetch the Demo app

git clone https://github.com/cloudfoundry/httpd-cnb
cd httpd-cnb/integration/fixtures/simple_app

Using pack

CLI Usage

  1. pack --help

  2. Introspect usage: pack suggest-builders and pack suggest-stacks. Then pack inspect-builder cloudfoundry/cnb:cflinuxfs3.

Basic Local Usage

To build an app:

pack build --builder cloudfoundry/cnb:cflinuxfs3 tests/httpd-app

You can then introspect your image:

pack build inspect-image tests/httpd-app

You can then run your app with:

docker run -e PORT=8080 -p 8080:8080 tests/httpd-app

The PORT env variable is a convention used by most buildpacks. It allows you to change the listening port easily. The -p flag should match the PORT env variable so that Docker is exposing the same port on which we told the app to listen.

Create a Builder

In some cases, you want to make your own builders. Good thing it's easy :)

pack create-builder localhost:5000/httpd-builder -b httpd-builder.toml --publish

where httpd-builder.toml looks like:

description = "Small demo builder with Apache Web Server"

[[buildpacks]]
id = "org.cloudfoundry.httpd"
uri = "https://github.com/cloudfoundry/httpd-cnb/releases/download/v0.0.73/httpd-cnb-0.0.73.tgz"

[lifecycle]
version = "0.5.0"

[stack]
build-image = "cloudfoundry/build:full-cnb"
id = "org.cloudfoundry.stacks.cflinuxfs3"
run-image = "cloudfoundry/run:full-cnb"

[[order]]
[[order.group]]
id = "org.cloudfoundry.httpd"

Usage w/a Registry

To pull images from a local registry instead of Docker Hub:

pack build --builder localhost:5000/httpd-builder --run-image localhost:5000/cloudfoundry/run:full-cnb tests/httpd-app

This tells pack where to find the builder and run images, and directs to the local registry.

To build and immediately publish the image to your registry (i.e. nothing local).

$ pack build --builder localhost:5000/httpd-builder --run-image localhost:5000/cloudfoundry/run:full-cnb --publish localhost:5000/tests/httpd-app
...
$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/cloudfoundry/cnb   cflinuxfs3          8a325acb4969        2 weeks ago         1.58GB
localhost:5000/cloudfoundry/run   full-cnb            38ca9e9b59d6        2 weeks ago         1.05GB

Note how tests/httpd-app doesn't exist locally. It's just in our registry.

Doing a docker run will first pull down the image.

$ docker run -e PORT=8080 -p 8080:8080 localhost:5000/tests/httpd-app
Unable to find image 'localhost:5000/tests/httpd-app:latest' locally
latest: Pulling from tests/httpd-app
1e41f30fb26c: Already exists
4aeb1954bc58: Pull complete
f34e57b56b3e: Pull complete
4f4a3cf382ca: Pull complete
6236630d0e15: Pull complete
Digest: sha256:756d210d7f680c4682ef6fc4f94181e277d42841aacb319e8131ed9298ca5e38
Status: Downloaded newer image for localhost:5000/tests/httpd-app:latest
[Tue Dec 31 16:41:56.618475 2019] [mpm_event:notice] [pid 1:tid 140673498269568] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
[Tue Dec 31 16:41:56.618806 2019] [mpm_event:info] [pid 1:tid 140673498269568] AH00490: Server built: Aug 15 2019 01:29:02
[Tue Dec 31 16:41:56.618823 2019] [core:notice] [pid 1:tid 140673498269568] AH00094: Command line: 'httpd -f /workspace/httpd.conf -D FOREGROUND'

Updating App Code

Updating app code is quick and easy. Let's make a change to our fixture. Edit htdocs/index.hml and change it to say "Hello CodeMash!".

Now, simply run pack build again. The same command as before.

pack build --builder localhost:5000/httpd-builder --run-image localhost:5000/cloudfoundry/run:full-cnb tests/httpd-app
...
docker run -e PORT=8080 -p 8080:8080 tests/httpd-app

Check the output and you should see "Hello CodeMash!" instead of "Hello World!"

Update the Run Image via Rebase

To rebase, you first need an image built based on an older run image. We can do that by running pack build with the --run-image argument and providing an older image. Then we can pack rebase and use the latest run image.

Build the initial image & confirm it's using the older run image:

$ pack build --builder localhost:5000/httpd-builder --run-image localhost:5000/cloudfoundry/run:0.0.11-full-cnb tests/httpd-app
...
Successfully built image tests/httpd-app

Now we look at the Metadata. Run pack inspect-image tests/httpd-app and check out the Base Image -> Reference. You can see similar with docker inspect.

$ docker inspect -f '{{json .Config.Labels}}' tests/httpd-app  | jq -r '.["io.buildpacks.lifecycle.metadata"]' | sed 's|\"|"|g' | jq -r '.runImage.reference'
cloudfoundry/run@sha256:b5f98e92a78673ed49feb818fa45ed2d9bde9cacdc32376dc9fb89738e7937d1

This should compare to the following value, which is the repo digest extracted from the actual run image:

$ docker inspect cloudfoundry/run:0.0.11-full-cnb | jq -r '.[].Id'
cloudfoundry/run@sha256:b5f98e92a78673ed49feb818fa45ed2d9bde9cacdc32376dc9fb89738e7937d1

Now we can Rebase

To rebase, we just run pack rebase. This switches out the underlying run image for the latest one. It does not rebuild.

$ pack rebase tests/httpd-app --run-image cloudfoundry/run:0.0.12-full-cnb
Rebasing tests/httpd-app on run image cloudfoundry/run:0.0.12-full-cnb
*** Images (sha256:a7d29fb02e5c5b3dbc102a86ebcbe6b84b9aba964c58447f2d6344bfd80a8b78):
      tests/httpd-app
Rebased Image: tests/httpd-app@sha256:a7d29fb02e5c5b3dbc102a86ebcbe6b84b9aba964c58447f2d6344bfd80a8b78
Successfully rebased image tests/httpd-app

Look at the metadata for the container, pack inspect-image tests/httpd-app.

This should now match for the image we rebased to:

$ docker inspect cloudfoundry/run:0.0.12-full-cnb | jq -r '.[].Id'
cloudfoundry/run@sha256:b5f98e92a78673ed49feb818fa45ed2d9bde9cacdc32376dc9fb89738e7937d1

The demo is set up so you can rebase one more time to 0.0.13. Feel free to run that now. It's OK if you rebase even when you're on the same image. It doesn't create any problems. In fact your image, just stays the same. Try it and try docker pull after. It should indicate nothing has changed. It's also OK to rebase backwards, like if you need to roll back your images for some reason.

Updates to CNBs

Create Old Builder

Go to httpd-cnb, update buildpack.toml to have old Apache HTTPD version.

[metadata]
  include_files = ["bin/build", "bin/detect", "buildpack.toml"]
  pre_package = "./scripts/build.sh"

  [[metadata.dependencies]]
    id = "httpd"
    name = "Apache HTTP Server"
    sha256 = "a6ad42b88561c78777360cc19d0d8c2e6ae516fad3928adcb4a6fd750a7141e9"
    source = "http://archive.apache.org/dist/httpd/httpd-2.4.39.tar.bz2"
    source_sha256 = "b4ca9d05773aa59b54d66cd8f4744b945289f084d3be17d7981d1783a5decfa2"
    stacks = ["org.cloudfoundry.stacks.cflinuxfs3"]
    uri = "https://buildpacks.cloudfoundry.org/dependencies/httpd/httpd-2.4.39-linux-x64-cflinuxfs3-a6ad42b8.tgz"
    version = "2.4.39"

Run ./scripts/package.sh -v 0.0.71 (it's part of the httpd-cnb project, and every CNB). Get the output directory. Then update httpd-builder-old.toml to point to the output directory.

Execute this to create the builder:

pack create-builder httpd-0.0.71-builder -b httpd-builder-old.toml

Test this out

To see how CNB updates work, we'll first build with an old builder. The old builder has an older HTTPD CNB version on it.

pack build --builder httpd-0.0.71-builder --run-image cloudfoundry/run:full-cnb tests/httpd-app

You can docker run it, but that's not really important here.

Next we'll rebuild using the new CNB.

pack build --builder localhost:5000/httpd-builder --run-image cloudfoundry/run:full-cnb tests/httpd-app

You should see the buildpack run again on the second time and install the newer version of Apache HTTPD.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment