DEV Community 👩‍💻👨‍💻

jgngo
jgngo

Posted on • Updated on

CI/CD for .NET Core

:WIP

If you have a .NET API that you want to containerize, here are the steps to prepare it.

Explain
-- CI/CD setup for AWS
-- Steps

  1. Create docker image
  2. Push to repository
  3. Setup ECS

Addendum, how to add health check.

Here are two files.

The TLS 1.0 option is needed if your SQL Server database does not support TLS 1.2. The recommended option is to update your database to the secure protocol.

You may also change sdk and aspnet version to 5.0 if you haven't updated to 6.0 yet.

This Dockerfile uses a multi-stage build to get an optimal image size.

Dockerfile

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app

# Enable TLS 1.0
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf

COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "myapp-whatever.dll"]
Enter fullscreen mode Exit fullscreen mode

buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Writing image definitions file...
      - printf '[{"name":"%s","imageUri":"%s"}]' $IMAGE_REPO_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
    files: imagedefinitions.json
Enter fullscreen mode Exit fullscreen mode

If you don't have a health check endpoint, this is important for containers for the orchestrator to know if your container is ready or if needs to be restarted.

Program.cs

builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/api/health");
Enter fullscreen mode Exit fullscreen mode

Startup.cs

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapHealthChecks("/api/health");
            });
Enter fullscreen mode Exit fullscreen mode

Latest comments (1)

Collapse
 
polterguy profile image
Thomas Hansen

Najs one, although I would prefer .Net 6, and a GitHub workflow file ... :)

🌚 Friends don't let friends browse without dark mode.

Just kidding, it's a personal preference. But you can change your theme, font, etc. in your settings.

The more you know. 🌈