Tekton is a Kubernetes-native CI/CD framework that lets you define pipelines as Kubernetes resources. If you're using Tekton to build and deploy .NET applications, the dotnet-publish-image task lets you build and push container images directly using the .NET SDK without writing a Dockerfile.
In this post, we'll walk through setting up a minimal Tekton pipeline that clones a .NET application from Git, builds a container image, and pushes it to quay.io.
How the task works
The dotnet-publish-image Tekton task uses .NET's built-in container publishing support to build and push container images. This means no Dockerfile or separate build tool is required.
The task takes a few key parameters:
SDK_IMAGE: The .NET SDK image to use for building (for example,registry.access.redhat.com/dotnet/sdk:10.0).PROJECT: Path to the.csprojfile in the source workspace.IMAGE_NAME: The target image repository.BASE_IMAGE(optional): The base image for the application container. When the tag is omitted, it is inferred from the project's target framework.
By default, the .NET SDK uses Microsoft's base images. To use Red Hat's .NET container images instead, set BASE_IMAGE to the appropriate image for your application type. For example, for ASP.NET Core applications use registry.access.redhat.com/dotnet/aspnet. For non-web applications use registry.access.redhat.com/dotnet/runtime.
Install the tasks
Our pipeline uses two tasks: git-clone to fetch the source code and dotnet-publish-image to build and push the container image. Install them using the Tekton CLI:
tkn hub install task git-clone
tkn hub install task dotnet-publish-image --type artifact --from redhat-tekton-tasksSet up the image repository
We will push our example application to quay.io using a robot account. First, create a new repository at quay.io (for example, s2i-dotnetcore-ex).
Next, create a robot account and grant it Write permission on the repository.
Once that's in place, create a Kubernetes Secret with the robot account credentials. Note that the username for a robot account is your quay.io username prefixed to the robot name (e.g., myuser+myrobot):
kubectl create secret docker-registry quay-credentials \
--docker-server=quay.io \
--docker-username="<username>+<robot-name>" \
--docker-password="<robot-token>"Finally, link the secret to the pipeline service account so Tekton can provide it to all pipeline tasks:
oc secret link pipeline quay-credentials
# or: kubectl patch serviceaccount pipeline -p '{"secrets": [{"name": "quay-credentials"}]}'Alternatively, instead of linking the secret to the ServiceAccount, you can pass the credentials directly to the dotnet-publish-image task using its optional dockerconfig workspace.
The pipeline
Here's a minimal pipeline that clones the s2i-dotnetcore-ex example application and builds a container image using Red Hat's .NET 10 SDK and ASP.NET Core runtime images:
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: dotnet-build-image
spec:
params:
- name: git-url
type: string
description: Git repository URL.
- name: image-name
type: string
description: Target image repository.
workspaces:
- name: source
tasks:
- name: clone
taskRef:
name: git-clone
params:
- name: url
value: $(params.git-url)
workspaces:
- name: output
workspace: source
- name: build-image
runAfter:
- clone
taskRef:
name: dotnet-publish-image
params:
- name: SDK_IMAGE
value: registry.access.redhat.com/dotnet/sdk:10.0
- name: PROJECT
value: app/app.csproj
- name: IMAGE_NAME
value: $(params.image-name)
- name: BASE_IMAGE
value: registry.access.redhat.com/dotnet/aspnet
workspaces:
- name: source
workspace: sourceThis pipeline has two tasks:
clonefetches the source code from Git using the git-clone task.build-imagebuilds and pushes the container image usingdotnet-publish-image.
Run the pipeline
Create a PipelineRun to execute the pipeline:
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: dotnet-build-image-
spec:
pipelineRef:
name: dotnet-build-image
params:
- name: git-url
value: https://github.com/redhat-developer/s2i-dotnetcore-ex
- name: image-name
value: quay.io/<your-quay-username>/s2i-dotnetcore-ex
workspaces:
- name: source
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1GiNow, start the pipeline run:
kubectl create -f pipelinerun.yamlYou can follow the progress with the Tekton CLI:
tkn pipelinerun logs --last -fOnce complete, the image will be available at quay.io/<your-quay-username>/s2i-dotnetcore-ex.
The PipelineRun uses a volumeClaimTemplate for the source workspace. Tekton automatically creates a PersistentVolumeClaim for each run and cleans it up when the PipelineRun is deleted. To control how many completed runs are retained, you can configure Tekton Pruner with history-based or time-based policies—either globally, per namespace, or scoped to specific pipelines using label selectors.
Trigger from a Git push
With Tekton Triggers, you can run this pipeline automatically whenever code is pushed to your repository. This involves three resource types that work together:
- An
EventListenerexposes an HTTP endpoint that receives webhooks. It uses aTriggerBindingto extract parameters and aTriggerTemplateto create a newPipelineRun. - A
TriggerBindingextracts values from the incoming webhook payload — for example, the repository clone URL from a GitHub push event. - A
TriggerTemplatedefines aPipelineRuntemplate that gets instantiated with the extracted values each time an event is received.
To secure the endpoint, you can add a GitHub interceptor to the EventListener. The interceptor validates the webhook signature against a shared secret, ensuring only genuine GitHub events trigger the pipeline.
Once the EventListener is deployed, Tekton Triggers creates a Service for it. You can expose it with a Route (on OpenShift) or an Ingress, and configure it as a webhook in your GitHub repository settings — selecting the push event. After that, every push to the repository will trigger a new pipeline run that builds and pushes an updated container image.
Conclusion
The dotnet-publish-image task provides a straightforward way to build .NET container images in Tekton pipelines. It uses the .NET SDK's built-in container support, so there's no need to write or maintain Dockerfiles. Combined with Red Hat's .NET container images, this task gives you a minimal, production-ready pipeline for building and publishing .NET application images.
The task supports additional features beyond what we covered here, such as passing MSBuild properties and environment variables. For the full list of parameters and usage details, see the task documentation.