Skip to content

Commit f11ce5b

Browse files
Merge pull request #3598 from benjaminguttmann-avtq/2667-add-custom-buildpack-documentation
2 parents e18fc2c + 46c1351 commit f11ce5b

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

docs/custom-buildpacks.md

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
# Buildpacks
2+
Korifi utilizes [kpack](https://github.com/buildpacks-community/kpack) to build Container Images combining [Cloud Native Buildpacks (CNB)](https://buildpacks.io) with application source code.
3+
4+
## Default Buildpacks
5+
6+
If you choose Helm to deploy Korifi some default buildpacks are pre-configured for you.
7+
You can see the available buildpacks via the CF CLI using the command
8+
9+
```bash
10+
cf buildpacks
11+
Getting buildpacks as cf-admin...
12+
13+
position name stack enabled locked filename
14+
1 paketo-buildpacks/java io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
15+
2 paketo-buildpacks/go io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
16+
3 paketo-buildpacks/nodejs io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
17+
4 paketo-buildpacks/ruby io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
18+
5 paketo-buildpacks/procfile io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
19+
```
20+
21+
Those default buildpacks are configured within the `ClusterStore` and `ClusterBuilder` of the Helm Chart, which can be found [here](../helm/korifi/kpack-image-builder/cluster-builder.yaml)
22+
23+
## Custom Buildpacks
24+
25+
If you want to make more buildpacks than the default ones available, you have two possibilities. You can either adjust the `ClusterStore` and `ClusterBuilder` within your cluster to include further buildpacks or you provide your own `ClusterBuilder` and use it instead.
26+
27+
### Adjust the existing ClusterBuilder/ ClusterStore
28+
29+
As an example we will add the [paketo/web-servers](https://github.com/paketo-buildpacks/web-servers) buildpack to Korifi and deploy an app with it.
30+
31+
#### Adjusting ClusterStore
32+
33+
First we get the current `ClusterStore` applied on the cluster. The default name is `cf-default-buildpacks`.
34+
35+
```yaml
36+
kubectl get ClusterStore cf-default-buildpacks -o yaml
37+
38+
apiVersion: kpack.io/v1alpha2
39+
kind: ClusterStore
40+
metadata:
41+
annotations:
42+
meta.helm.sh/release-name: korifi
43+
meta.helm.sh/release-namespace: korifi
44+
creationTimestamp: "2024-11-04T12:58:59Z"
45+
generation: 2
46+
labels:
47+
app.kubernetes.io/managed-by: Helm
48+
name: cf-default-buildpacks
49+
resourceVersion: "4105"
50+
uid: 374265ba-9dd8-4769-8363-76ab2b94d56e
51+
spec:
52+
sources:
53+
- image: gcr.io/paketo-buildpacks/java
54+
- image: gcr.io/paketo-buildpacks/nodejs
55+
- image: gcr.io/paketo-buildpacks/ruby
56+
- image: gcr.io/paketo-buildpacks/procfile
57+
- image: gcr.io/paketo-buildpacks/go
58+
...
59+
```
60+
We now need to add the image for the new buildpack `web-servers` we want to use under `.spec.sources`. For that we use the patch command below:
61+
62+
```yaml
63+
kubectl patch ClusterStore/cf-default-buildpacks --type json -p '[{"op": "add", "path": "/spec/sources/-","value": {"image": "gcr.io/paketo-buildpacks/web-servers"}}]'
64+
```
65+
66+
Afterwards we can see that sources now includes web-servers as well
67+
68+
```yaml
69+
kubectl get ClusterStore cf-default-buildpacks -o jsonpath={".spec.sources"} | jq
70+
[
71+
{
72+
"image": "gcr.io/paketo-buildpacks/java"
73+
},
74+
{
75+
"image": "gcr.io/paketo-buildpacks/nodejs"
76+
},
77+
{
78+
"image": "gcr.io/paketo-buildpacks/ruby"
79+
},
80+
{
81+
"image": "gcr.io/paketo-buildpacks/procfile"
82+
},
83+
{
84+
"image": "gcr.io/paketo-buildpacks/go"
85+
},
86+
{
87+
"image": "gcr.io/paketo-buildpacks/web-servers"
88+
}
89+
]
90+
```
91+
92+
#### Adjusting ClusterBuilder
93+
94+
The next step to make the buildpacks available to CF is to adjust the `ClusterBuilder`.
95+
An example of the `ClusterBuilder` looks like this. The default name is `cf-kpack-cluster-builder`.
96+
97+
```yaml
98+
kubectl get ClusterBuilder cf-kpack-cluster-builder -o yaml
99+
apiVersion: kpack.io/v1alpha2
100+
kind: ClusterBuilder
101+
metadata:
102+
annotations:
103+
meta.helm.sh/release-name: korifi
104+
meta.helm.sh/release-namespace: korifi
105+
creationTimestamp: "2024-11-04T14:37:37Z"
106+
generation: 1
107+
labels:
108+
app.kubernetes.io/managed-by: Helm
109+
name: cf-kpack-cluster-builder
110+
resourceVersion: "5138"
111+
uid: ff1ab7ea-4482-4e25-a959-4587d33314d2
112+
spec:
113+
order:
114+
- group:
115+
- id: paketo-buildpacks/java
116+
- group:
117+
- id: paketo-buildpacks/go
118+
- group:
119+
- id: paketo-buildpacks/nodejs
120+
- group:
121+
- id: paketo-buildpacks/ruby
122+
- group:
123+
- id: paketo-buildpacks/procfile
124+
serviceAccountRef:
125+
name: kpack-service-account
126+
namespace: cf
127+
stack:
128+
kind: ClusterStack
129+
name: cf-default-stack
130+
store:
131+
kind: ClusterStore
132+
name: cf-default-buildpacks
133+
tag: localregistry-docker-registry.default.svc.cluster.local:30050/kpack-builder
134+
...
135+
```
136+
We will now add the `web-server` buildpack as a new element to `.spec.order` which makes it appear for the CF CLI.
137+
138+
```yaml
139+
kubectl patch ClusterBuilder/cf-kpack-cluster-builder --type json -p '[{"op":"add", "path":"/spec/order/-","value": {"group": [{"id": "paketo-buildpacks/web-servers"}]}}]'
140+
```
141+
142+
After that you can see the buildpack using the CF CLI.
143+
144+
```yaml
145+
cf buildpacks
146+
Getting buildpacks as cf-admin...
147+
148+
position name stack enabled locked filename
149+
1 paketo-buildpacks/java io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
150+
2 paketo-buildpacks/go io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
151+
3 paketo-buildpacks/nodejs io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
152+
4 paketo-buildpacks/ruby io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
153+
5 paketo-buildpacks/procfile io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
154+
6 paketo-buildpacks/web-servers io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
155+
```
156+
157+
### Provide your own ClusterBuilder/ ClusterStore
158+
159+
Instead on relying on the kpack `ClusterBuilder`/ `ClusterStore` provided by the Helm Chart you can deploy your own set of `ClusterBuilder`, `ClusterStore` and `ClusterStack` and make the Helm Chart use this one.
160+
161+
The following steps will only provide very basic manifests to add a new buildpack, for more details on the matter we recommend the [kpack documentation](https://github.com/buildpacks-community/kpack/blob/main/docs/build.md) or for this specific case the [kpack Tutorial](https://github.com/buildpacks-community/kpack/blob/main/docs/tutorial.md) to ensure all pre-requisits are met to perform the steps below.
162+
163+
Lets start with the `ClusterStore`.
164+
For that copy the manifest down below into a file called `store.yaml` and run `kubectl apply -f store.yaml`.
165+
166+
```yaml
167+
apiVersion: kpack.io/v1alpha2
168+
kind: ClusterStore
169+
metadata:
170+
name: custom-cluster-store
171+
spec:
172+
sources:
173+
- image: gcr.io/paketo-buildpacks/web-servers
174+
```
175+
176+
Please check that the `ClusterStore` was succesfully created
177+
178+
```yaml
179+
kubectl get ClusterStore
180+
NAME READY
181+
custom-cluster-store True
182+
```
183+
184+
Next we need a `ClusterStack` where we specify which stack should be used building the application image. For that please store the manifest below into a file called `stack.yaml` and run `kubectl apply -f stack.yaml`.
185+
186+
```yaml
187+
apiVersion: kpack.io/v1alpha2
188+
kind: ClusterStack
189+
metadata:
190+
name: custom-cluster-stack
191+
spec:
192+
id: "io.buildpacks.stacks.jammy"
193+
buildImage:
194+
image: "paketobuildpacks/build-jammy-base"
195+
runImage:
196+
image: "paketobuildpacks/run-jammy-base"
197+
```
198+
199+
Verify that the `ClusterStack` has been created successfully.
200+
201+
```yaml
202+
kubectl get ClusterStack
203+
NAME READY
204+
custom-cluster-stack True
205+
```
206+
207+
Now we only need a `ClusterBuilder` to have everything in place.
208+
For that please save the manifest below into a file called `builder.yaml` and apply it `kubectl apply -f builder.yaml`.
209+
210+
```yaml
211+
apiVersion: kpack.io/v1alpha2
212+
kind: ClusterBuilder
213+
metadata:
214+
name: custom-cluster-builder
215+
namespace: default
216+
spec:
217+
serviceAccountRef:
218+
name: <ServiceAccount> # e.g. kpack-service-account
219+
namespace: <ServiceAccountNamespace> # e.g. cf
220+
tag: <CLUSTER-BUILDER-IMAGE-TAG> # e.g. localregistry-docker-registry.default.svc.cluster.local:30050/kpack-builder
221+
stack:
222+
name: custom-cluster-stack
223+
kind: ClusterStack
224+
store:
225+
name: custom-cluster-store
226+
kind: ClusterStore
227+
order:
228+
- group:
229+
- id: paketo-buildpacks/web-servers
230+
```
231+
232+
Verify that the `ClusterBuilder` was created successfully.
233+
234+
```yaml
235+
kubectl get ClusterBuilder
236+
NAME LATESTIMAGE READY UPTODATE
237+
custom-cluster-builder localregistry-docker-registry.default.svc.cluster.local:30050/kpack-builder:clusterbuilder-custom-cluster-builder@sha256:4e273a309e6679e071ab93c754617869b486fcd0bf420ddde2babf32bd1dc491 True True
238+
```
239+
240+
Now we only need to tell Helm that it should use our own custom `ClusterBuilder` to build images by setting the value `--set=kpackImageBuilder.clusterBuilderName="custom-cluster-builder"` during the Helm install command.
241+
242+
Afterwards we can see all buildpacks we have configured in CF.
243+
244+
```yaml
245+
cf buildpacks
246+
Getting buildpacks as cf-admin...
247+
248+
position name stack enabled locked filename
249+
1 paketo-buildpacks/web-servers io.buildpacks.stacks.jammy true false paketo-buildpacks/[email protected]
250+
```
251+
252+
### Verify your buildpack is working
253+
254+
To verify that your newly added buildpack is working you can deploy one of the (sample apps for cloud native buildpacks)[https://github.com/paketo-buildpacks/samples].
255+
256+
In our case we use the [web-servers/nginx-sample](https://github.com/paketo-buildpacks/samples/tree/main/web-servers/nginx-sample)
257+
258+
```yaml
259+
cd web-servers/nginx-sample
260+
cf push nginx-sample -b paketo-buildpacks/web-servers
261+
```
262+
263+
and after a short waiting time we can see our app is successfully deployed
264+
265+
```yaml
266+
cf apps
267+
Getting apps in org test-org / space test-space as cf-admin...
268+
269+
name requested state processes routes
270+
nginx-sample started web:1/1 nginx-sample.apps-127-0-0-1.nip.io
271+
```
272+
273+
and we can as well access it via curl (or browser if you want to).
274+
275+
```yaml
276+
curl -k https://nginx-sample.apps-127-0-0-1.nip.io
277+
<!DOCTYPE html>
278+
<html>
279+
<head>
280+
<title>Powered By Paketo Buildpacks</title>
281+
</head>
282+
<body>
283+
<img style="display: block; margin-left: auto; margin-right: auto; width: 50%;" src="https://paketo.io/images/paketo-logo-full-color.png"></img>
284+
</body>
285+
</html>`
286+
```

0 commit comments

Comments
 (0)