I am working on a gitlab CI/CD project to build an asp.net core
application into a docker
.
Currently I have 2 possible implementations in mind. The first one have the full logic in the Dockerfile
, but I can't visualize the stages in Gitlab this way (build, test, publish). So I thought about moving the main logic to the gitlab-ci.yml
file. But what bothers me now is that I have to manage the image docker dotnet versions
on 2 places (sdk:3.1, aspnet:3.1.1-alpine3.10). Is it a good idea to deliver the version via build-arg
or is there a more elegant solution?
.gitlab-ci.yml
stages:
- build
- test
- docker
build:
stage: build
image: mcr.microsoft.com/dotnet/core/sdk:3.1
only:
- master
script:
- cd src
- dotnet restore --interactive
- dotnet build --configuration Release
- dotnet publish --configuration Release --output ../publish/
artifacts:
paths:
- ./publish/*.*
expire_in: 1 week
tags:
- docker
test:
stage: test
image: mcr.microsoft.com/dotnet/core/sdk:3.1
only:
- master
script:
- cd src
- dotnet test --test-adapter-path:. --logger:"junit;LogFilePath=../../MyProject.xml"
artifacts:
paths:
- ./MyProject.xml
reports:
junit: ./MyProject.xml
tags:
- docker
docker:
stage: docker
image: docker:stable
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
only:
- master
script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" --build-arg EXECUTABLE=Test.WebApi.dll .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
tags:
- docker
Dockerfile
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.1-alpine3.10
ARG EXECUTABLE
WORKDIR /app
COPY /publish .
ENV ASPNETCORE_URLS "http://*:5000"
ENV ASPNETCORE_ENVIRONMENT "Staging"
CMD ["dotnet", "$EXECUTABLE"]
Here is my solution, I have defined the variables above and replace them in the docker file with sed
My Solution have this two Projects
@ThomasBrüggemann thanks for the Inspiration.
.gitlab-ci.yml
variables:
PROJECT_NAME: "Test.WebApi"
BUILD_IMAGE: "mcr.microsoft.com/dotnet/core/sdk:3.1"
RUNTIME_IMAGE: "mcr.microsoft.com/dotnet/core/aspnet:3.1.1-alpine3.10"
stages:
- build
- test
- docker
build:
stage: build
image: $BUILD_IMAGE
only:
- master
script:
- cd src/$PROJECT_NAME
- dotnet restore --interactive
- dotnet build --configuration Release
- dotnet publish --configuration Release --output ../../publish/
artifacts:
paths:
- ./publish/*
expire_in: 1 week
tags:
- docker
test:
stage: test
image: $BUILD_IMAGE
only:
- master
script:
- cd src/$PROJECT_NAME.UnitTest
- dotnet test --test-adapter-path:. --logger:"junit;LogFilePath=../../UnitTestResult.xml"
artifacts:
paths:
- ./UnitTestResult.xml
reports:
junit: ./UnitTestResult.xml
tags:
- docker
docker:
stage: docker
image: docker:stable
services:
- docker:18.09.7-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
only:
- master
script:
# Prepare Dockerfile
- sed -i "s~\$DOCKERIMAGE~$RUNTIME_IMAGE~g" Dockerfile
- sed -i 's/$ENVIRONMENT/Staging/g' Dockerfile
- sed -i "s/\$ENTRYPOINT/$PROJECT_NAME.dll/g" Dockerfile
# Process Dockerfile
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
tags:
- docker
Dockerfile
FROM $DOCKERIMAGE
WORKDIR /app
COPY /publish .
EXPOSE 5000/tcp
ENV ASPNETCORE_URLS "http://*:5000"
ENV ASPNETCORE_ENVIRONMENT "$ENVIRONMENT"
CMD ["dotnet", "$ENTRYPOINT"]
Here some Version handling when tagging in GitLab-Pipeline:
script:
- COMMIT_DATE=$(git log -1 --format=%cd --date=iso-strict | grep -o '\([0-9]*\)' | tr -d '\n')
- VERSION_PREFIX=$CI_COMMIT_TAG
- VERSION_SUFFIX="${COMMIT_DATE::-6}"
- echo $VERSION_PREFIX-$VERSION_SUFFIX
- sed -i "s:<VersionPrefix>.*</VersionPrefix>:<VersionPrefix>$VERSION_PREFIX</VersionPrefix>:g" [PROJECT].csproj
- dotnet publish --version-suffix $VERSION_SUFFIX -c Release -o ./out
- docker build --tag "$CI_REGISTRY_IMAGE:$VERSION_PREFIX"
only:
- tags
In Project file must
<!-- Version is set by CI-Script do not modify manually -->
<VersionPrefix>0.0.0</VersionPrefix>
<Deterministic>False</Deterministic>
be set
Maybe this is helpful. Something similar can be done when build without tagging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With