A .Net 8.0 Web Api template that includes containerising the Web Api.
- .Net 8.0
- Docker Desktop
- Visual Studio Code
- Postman
This is intended as a template api but it is not ready for production just yet!
dotnet new webapi -o Template.Api --no-https
cd Template.Api/
code .
with HTTPS
dotnet new web -o Template.Api
cd Template.Api/
code .
dotnet dev-certs https --trust ## I am on macOS
dotnet run --urls="https://localhost:7777"
See https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-8.0.
Install the Health Checks NuGet Package
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks
See https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-8.0.
See https://github.com/serilog/serilog-aspnetcore.
dotnet add package Serilog.AspNetCore
See https://learn.microsoft.com/en-us/azure/azure-app-configuration/quickstart-feature-flag-aspnet-core
dotnet add package Microsoft.FeatureManagement
Create a Dockerfile based on sample here:
https://github.com/dotnet/dotnet-docker/tree/main/samples/aspnetapp
My Docker sample for .Net 5 is here:
Then:
docker build -t template-api:0.0.1 .
docker image ls | grep template-api # to verify image is built
docker run -it --rm -p 8000:8080 template-api:0.0.1
Test using postman when running: http://localhost:8000/
Ctrl-c to exit.
Scan image for vulnerabilities
docker scan template-api:0.0.1
Create the test project
dotnet new xunit -o Template.Api.IntegrationTests
cd Template.Api.IntegrationTests/
dotnet test
Add required packages and reference api project
dotnet add package Microsoft.AspNetCore.Mvc.Testing
dotnet add package FluentAssertions
dotnet add Template.Api.IntegrationTests.csproj reference ../Template.Api/Template.Api.csproj
See https://docs.github.com/en/packages/guides/pushing-and-pulling-docker-images for how you can store and manage Docker images in GitHub Container Registry.
Authenticate to the GitHub Container Registry using a personal access token (PAT). Create a new PAT with the appropriate scopes (read:packages, write:packages, delete:packages)and store the PAT as a repository secret named CR_PAT.
Create a workflow using this https://github.com/docker/build-push-action action.
Integrate with a Kubernetes cluster by creating a kubernetes secret of type docker-registry:
kubectl create secret docker-registry ghcr-secret \
--docker-server=ghcr.io \
--docker-username=$USERNAME \
--docker-password=$GHCR_PAT \
--namespace=$NAMESPACE
Refer to this secret in the imagePullSecrets for the container. It is scoped to the namespace.
Enable a local kubernetes cluster using Docker Desktop. Use the Kubernetes extension in Visual Studio Code to help author the deployment and service yaml.
kubectl config get-contexts # check that the docker desktop is the current context
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get pods
kubectl logs template-api-76f94b7cbc-hw4wc # use pod name from previous command
kubectl apply -f service.yaml
kubectl get services
Test using postman when running: http://localhost:8080/
kubectl delete services template-api
kubectl delete deployment template-api
Let's install the Dahsboard: https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
Accessing the Dashboard UI
kubectl proxy
Dashboard will be available at http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.
Install https://helm.sh/docs/intro/install/.
mkdir charts
cd charts
helm create template-api
Update template-api/values.yaml:
- Change image.repository to template-api:0.0.1 or ghcr.io/fabianmagrini/dotnet-api-template
- Change imagePullSecrets to name: ghcr-secret. See above on creating the secret.
- Change service.type to LoadBalancer
- Change service.port to 8080
- Change spec.template.spec.containers.livenessProbe.httpGet.path to /
- Change spec.template.spec.containers.readinessProbe.httpGet.path to /
Update template-api/Chart.yaml:
- Change appVersion to "0.0.1
helm upgrade --install template-api . --debug
List all pods and services in all namespaces
kubectl get pods --all-namespaces
kubectl get services --all-namespaces
Note the EXTERNAL-IP for the service if there is an EXTERNAL-IP.
Test using postman when running: http://localhost:9000/ or http://EXTERNAL-IP:9000/ if there is an EXTERNAL-IP,
Cleaning up
helm uninstall template-api