Skip to main content

4 posts tagged with "community"

View All Tags

[Community] Continuous Deployment

ยท 2 min read

A typical CI pipeline contains steps such as: clone, build, test, package and push. The final build product may be artifacts pushed to a git repository or a docker container pushed to a container registry.

When these should be deployed on an app server, the pipeline should include a deploy step, which represents the "CD" in CI/CD - the automatic deployment of a pipeline's final product.

There are various ways to accomplish CD with Woodpecker, depending on your project's specific needs.

[Community] Podman image build with sigstore

ยท 3 min read

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:

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 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.

.
โ”œโ”€โ”€ Containerfile
โ”œโ”€โ”€ main.go
โ”œโ”€โ”€ go.mod
โ”œโ”€โ”€ go.sum
โ”œโ”€โ”€ .woodpecker.yml
โ””โ”€โ”€ Makefile

Containerfileโ€‹

The Containerfile refers to the base image that will be verified when pulled.

FROM gcr.io/distroless/static-debian12:nonroot
COPY app /app
CMD ["/app"]

Woodpecker workflowโ€‹

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 <username> --password-stdin registry.gitlab.com
# Build the container image
- podman build --tag registry.gitlab.com/<namespace>/<repository_name>/<image_name>:latest .
# Sign and push the image
- podman push --sign-by-sigstore-private-key ./key.private registry.gitlab.com/<namespace>/<repository_name>/<image_name>:latest

secrets: [sigstore_private_key, registry_login_token]

[Community] Debug pipeline steps

ยท One min read

Sometimes you want to debug a pipeline. Therefore I recently discovered: https://github.com/ekzhang/sshx

A simple step like should allow you to debug:

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.

[Community] Podman-in-Podman image builds

ยท 2 min read

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:

.
โ”œโ”€โ”€ 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

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 <username> --password-stdin registry.gitlab.com
- cd roundcube
- buildah build --tag registry.gitlab.com/<namespace>/<repository_name>/roundcube:latest .
- buildah push registry.gitlab.com/<namespace>/<repository_name>/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.