diff --git a/.cspell.json b/.cspell.json index 87d7b64a6..0c9513464 100644 --- a/.cspell.json +++ b/.cspell.json @@ -71,6 +71,7 @@ "gomod", "gonic", "GOPATH", + "handlebargh", "HEALTHCHECK", "healthz", "Hetzner", @@ -161,6 +162,7 @@ "securecookie", "sess", "shellescape", + "sigstore", "Sonatype", "SSHURL", "sslmode", diff --git a/docs/blog/2023-12-12-podman-image-builds/index.md b/docs/blog/2023-12-12-podman-image-builds/index.md new file mode 100644 index 000000000..3e7fe9008 --- /dev/null +++ b/docs/blog/2023-12-12-podman-image-builds/index.md @@ -0,0 +1,58 @@ +--- +title: '[Community] Podman-in-Podman image builds' +description: Build images in Podman with buildah +slug: podman-image-builds +authors: + - name: handlebargh + url: https://github.com/handlebargh + image_url: https://github.com/handlebargh.png +hide_table_of_contents: true +tags: [community, image, podman] +--- + + + +I run Woodpecker CI with podman backend instead of docker and just figured out how to build images with buildah. Since I couldn't find this anywhere documented, I thought I might as well just share it here. + +It's actually pretty straight forward. Here's what my repository structure looks like: + +```bash +. +├── roundcube +│   ├── Containerfile +│   ├── docker-entrypoint.sh +│   └── php.ini +└── .woodpecker + └── .build_roundcube.yml +``` + +As you can see I'm building a roundcube mail image. + +This is the `.woodpecker/.build_roundcube.yaml` + +```yaml +when: + event: [cron, manual] + cron: build_roundcube + +steps: + build-image: + image: quay.io/buildah/stable:latest + pull: true + privileged: true + commands: + - echo $REGISTRY_LOGIN_TOKEN | buildah login -u --password-stdin registry.gitlab.com + - cd roundcube + - buildah build --tag registry.gitlab.com///roundcube:latest . + - buildah push registry.gitlab.com///roundcube:latest + + secrets: [registry_login_token] +``` + +As you can see, I'm using this workflow over at gitlab.com. It should work with GitHub as well, with adjusting the registry login. + +You may have to adjust the `when:` to your needs. Furthermore, you must check the `trusted` checkbox in project settings. Therefore, be sure to run trusted code only in this setup. + +This seems to work fine so far. I wonder if anybody else made this work a different way. + +EDIT: Removed the additional step that would run buildah in a podman container. I didn't know it could be that easy to be honest. diff --git a/docs/blog/2023-12-13-debug-pipeline-steps/index.md b/docs/blog/2023-12-13-debug-pipeline-steps/index.md new file mode 100644 index 000000000..5f5d116c9 --- /dev/null +++ b/docs/blog/2023-12-13-debug-pipeline-steps/index.md @@ -0,0 +1,29 @@ +--- +title: '[Community] Debug pipeline steps' +description: Debug pipeline steps using sshx +slug: debug-pipeline-steps +authors: + - name: anbraten + url: https://github.com/anbraten + image_url: https://github.com/anbraten.png +hide_table_of_contents: true +tags: [community, debug] +--- + + + +Sometimes you want to debug a pipeline. +Therefore I recently discovered: + +A simple step like should allow you to debug: + +```yaml +steps: + - name: debug + image: alpine + commands: + - curl -sSf https://sshx.io/get | sh && sshx + # ^ + # └ This will open a remote terminal session and print the URL. It + # should take under a second. +``` diff --git a/docs/blog/2023-12-15-podman-sigstore/index.md b/docs/blog/2023-12-15-podman-sigstore/index.md new file mode 100644 index 000000000..db3d5b964 --- /dev/null +++ b/docs/blog/2023-12-15-podman-sigstore/index.md @@ -0,0 +1,138 @@ +--- +title: '[Community] Podman image build with sigstore' +description: Build images in Podman with sigstore signature checking and signing +slug: podman-image-build-sigstore +authors: + - name: handlebargh + url: https://github.com/handlebargh + image_url: https://github.com/handlebargh.png +hide_table_of_contents: false +tags: [community, image, podman, sigstore, signature] +--- + + + +This example shows how to build a container image with podman while verifying the base image and signing the resulting image. + +The image being pulled uses a keyless signature, while the image being built will be signed by a pre-generated private key. + +## Prerequisites + +### Generate signing keypair + +You can use cosing or skopeo to generate the keypair. + +Using skopeo: + +```bash +skopeo generate-sigstore-key --output-prefix myKey +``` + +This command will generate a `myKey.private` and a `myKey.pub` keyfile. + +Store the `myKey.private` as secret in Woodpecker. In the example below, the secret is called `sigstore_private_key` + +### Configure hosts pulling the resulting image + +See [here](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/assembly_signing-container-images_building-running-and-managing-containers#proc_verifying-sigstore-image-signatures-using-a-public-key_assembly_signing-container-images) on how to configure the hosts pulling the built and signed image. + +## Repository structure + +Consider the `Makefile` having a `build` target that will be used in the following workflow. +This target yields a Go binary with the filename `app` that will be placed in the root directory. + +```bash +. +├── Containerfile +├── main.go +├── go.mod +├── go.sum +├── .woodpecker.yml +└── Makefile +``` + +### Containerfile + +The Containerfile refers to the base image that will be verified when pulled. + +```dockerfile +FROM gcr.io/distroless/static-debian12:nonroot +COPY app /app +CMD ["/app"] +``` + +### Woodpecker workflow + +```yaml +steps: + build: + image: docker.io/library/golang:1.21 + pull: true + commands: + - make build + + publish: + image: quay.io/podman/stable:latest + # Caution: This image is built daily. It might fill up your image store quickly. + pull: true + # Fill in the trusted checkbox in Woodpecker's settings as well + privileged: true + commands: + # Configure podman to use sigstore attachments for both, the registry you pull from and the registry you push to. + - | + printf "docker: + registry.gitlab.com: + use-sigstore-attachments: true + gcr.io: + use-sigstore-attachments: true" >> /etc/containers/registries.d/default.yaml + + # At pull, check the keyless sigstore signature of the distroless image. + # This is a very strict container policy. It allows pulling from gcr.io/distroless only. Every other registry will be rejected. + # See https://github.com/containers/image/blob/main/docs/containers-policy.json.5.md for more information. + + # fulcio CA crt obtained from https://github.com/sigstore/sigstore/blob/main/pkg/tuf/repository/targets/fulcio_v1.crt.pem + # rekor public key obtained from https://github.com/sigstore/sigstore/blob/main/pkg/tuf/repository/targets/rekor.pub + # crt/key data is base64 encoded. --> echo "$CERT" | base64 + - | + printf '{ + "default": [ + { + "type": "reject" + } + ], + "transports": { + "docker": { + "gcr.io/distroless": [ + { + "type": "sigstoreSigned", + "fulcio": { + "caData": "LS0tLS1CRUdJTiBDR...QVRFLS0tLS0K", + "oidcIssuer": "https://accounts.google.com", + "subjectEmail": "keyless@distroless.iam.gserviceaccount.com" + }, + "rekorPublicKeyData": "LS0tLS1CRUdJTiBQVUJ...lDIEtFWS0tLS0tCg==", + "signedIdentity": { "type": "matchRepository" } + } + ] + }, + "docker-daemon": { + "": [ + { + "type": "reject" + } + ] + } + } + }' > /etc/containers/policy.json + + # Use this key to sign the built image at push. + - echo "$SIGSTORE_PRIVATE_KEY" > key.private + # Login at the registry + - echo $REGISTRY_LOGIN_TOKEN | podman login -u --password-stdin registry.gitlab.com + # Build the container image + - podman build --tag registry.gitlab.com///:latest . + # Sign and push the image + - podman push --sign-by-sigstore-private-key ./key.private registry.gitlab.com///:latest + + secrets: [sigstore_private_key, registry_login_token] +```