Access Build Variable from Dockerfile on Azure Devops Build pipeline - variables

Is there a way to access a Azure Devops Build variable from a Dockerfile as a part of the build pipeline? Say I have a .NET core application and I have Azure Devops build pipeline where I have the usual build steps like .net restore, .net build. So if I have a step that reads like this dotnet publish -c Release -o $(Build.OutputDirectory), can I reference this $(Build.OutputDirectory) from my Dockerfile?
When build the image locally, I do a dotnet publish -c Release -o ./obj/Docker/publish and my dockerfile looks like so below:
FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "dotnetapp.dll"]
I am assuming that dockerfile for the Build pipeline should look like so below:
FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-**$(Build.OutputDirectory)**} .
ENTRYPOINT ["dotnet", "dotnetapp.dll"]

Related

Dotnet Core build Intermediate Container Removed

Hi Folks I am trying to containerized standard Asp dotnet core application with Dockerfile generated by Visual Studio.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["dotnetcoredokc/dotnetcoredokc.csproj", "dotnetcoredokc/"]
RUN dotnet restore "dotnetcoredokc/dotnetcoredokc.csproj"
COPY . .
WORKDIR "/src/dotnetcoredokc"
RUN dotnet build "dotnetcoredokc.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "dotnetcoredokc.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "dotnetcoredokc.dll"]
After long wait I have received this error.
e4c3d3e4f7b0: Pull complete
101c41d0463b: Pull complete
8275efcd805f: Pull complete
751620502a7a: Pull complete
8e306865fd07: Pull complete
9d2f53e752c2: Pull complete
143a93e01eba: Pull complete
Digest: sha256:bfd6083e9cd36b37b2a4e9f1722cc958b6654fa96cb3d84ef78492ecf00dcd32
Status: Downloaded newer image for mcr.microsoft.com/dotnet/core/sdk:3.1-buster
---> 5fe503d51830
Step 6/17 : WORKDIR /src
---> Running in 2645ba31f404
Removing intermediate container 2645ba31f404
---> ba24bc746a28
Step 7/17 : COPY ["dotnetcoredokc/dotnetcoredokc.csproj", "dotnetcoredokc/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder187253264/dotnetcoredokc/dotnetcoredokc.csproj: no such file or directory

Set Assembly version of net core app using Azure DevOps with a DockerFile

I am using a DockerFile created by visual studio to create my image. I want to build with Azure DevOps and set my assemblies version inside the image the version I have in the Pipeline. I feel that I have to change this line but I dont known how.
RUN dotnet build "ImportBatch.Api.csproj" -c Release -o /app/build
My DockerFile
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["ImportBatch.Api/ImportBatch.Api.csproj", "ImportBatch.Api/"]
COPY ["ImportBach.Dto/ImportBatch.Dto.csproj", "ImportBach.Dto/"]
COPY ["Common/Common.csproj", "Common/"]
COPY ["Common.Dto/Common.Dto.csproj", "Common.Dto/"]
COPY ["Common.Azure.Storage/Common.Azure.Storage.csproj", "Common.Azure.Storage/"]
RUN dotnet restore "ImportBatch.Api/ImportBatch.Api.csproj"
COPY . .
WORKDIR "/src/ImportBatch.Api"
RUN dotnet build "ImportBatch.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ImportBatch.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Cardinal.Software.ImportBatch.Api.dll"]
From pipeline:
- task: Docker#1
displayName: 'Build the image'
inputs:
dockerfile: 'Dockerfile'
imageName: '$(imageRepoName):$(GitVersion.SemVer)'
arguments: '--build-arg version=$(GitVersion.SemVer)'
continueOnError: true
On DockerFile:
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /src
COPY . .
ARG version #define the argument
#use this argument while running build or publish, for example
RUN dotnet publish "./yourProject.csproj" -c Release /p:Version=${version} -o /app/publish --no-restore
For SDK-style projects assembly version attributes are generated automatically, so you can use p:Version=1.2.3.4 right out of the box. Please check example here (at the bottom)
dotnet build -p:Version=1.2.3.4

Deploying AspNet Core to GKE gives connection refused

I am trying to deploy an example Asp.Net Core 3.1 app to GKE, I am building the app in cloud console and it works fine when i am running it from the console with this command "docker run -p 8080:8080 [Image Name]asp-app:v1"
When i deploy it to my Cluster in GKE i cant reach my app althoug i am exposing it with this command: "kubectl expose deployment asp-web --type=LoadBalancer --port 80 --target-port 8080"
I get this error in my webbrowser: "ERR_CONNECTION_REFUSED"
I have managed to deploy another app that where built using Asp.Net Core 2.2 so my settings in GCP should be right.
Does anyone have some experience with this?
Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["asp/asp.csproj", "asp/"]
RUN dotnet restore "asp/asp.csproj"
COPY . .
WORKDIR /src/asp
RUN dotnet build "asp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "asp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:8080
ENTRYPOINT ["dotnet", "asp.dll"]
Figured it out. I had made a new project and added "ENV ASPNETCORE_URLS http://*:8080" to the dockerfile to make it bind to the port while running in the container on GKE.

Docker build for C# core need the internet connection

I am writing in C# .NET core (VS 2017), using the build for linux containers, using docker-compose.
When I build the image (or publish), there is always reference to the internet, because of nuget usage.
Last error encountered (which I persume of downtime on the nuget, but no matter
- any downtime should not lead to exception in build/publish).
/usr/share/dotnet/sdk/2.1.503/NuGet.targets(114,5): error : Unable to
load the service index for source https://api.nuget.org/v3/index.json. ...
I want to build the image, even the nuget is down, or even there is no interet connection
The yml file look like this:
services:
myProj:
image: my_proj
build:
context: ./all_projects/base_solution/
dockerfile: myProj/Dockerfile
It seems that "dotnet publish..." command call restore from the internet.
If I run publish with --no-restore, the code not compiled, but I want to restore the nuget packages from my own pre-build of my computer.
How can I do it? With no internet connection? Why should I depend on the internet to restore the nuget at each build?
Why cannot I restore nuget package from my own pre-build image, and not always?! get from nuget (actually nuget packages not change occasionally in my code).
May I just copy the folder from the nuget, and not using "COPY" command?
I did the following:
Build an image from a 'common' project, that uses all the nuget package.
Add a reference in the built-image for the new other image, like this:
Create a new common image:
# there is no runtime.
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY TestDock/TestDock.csproj TestDock/
FROM build AS publish
RUN dotnet publish TestDock.csproj -c Release -o /app
And at the original image:
FROM microsoft/dotnet:2.1-runtime AS base
WORKDIR /app
# FROM microsoft/dotnet:2.1-sdk AS build do:
FROM my_common_image AS build
WORKDIR /src
COPY TestDock/TestDock.csproj TestDock/
# Added the following. I tried to copy all, but this doesn't help.
# I persume I can copy part of the common build.
COPY --from=build /app /app
COPY --from=build /src /src
COPY --from=build /usr /usr
FROM build AS publish
RUN dotnet publish TestDock.csproj --no-restore --no-dependecies -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TestDock.dll"]
I have tried to add an intermediate image, with Dockerfile as following:
# This image is base image for all dockers (no need runtime)
# docker build . -f DockerFile_Common -t docker_common
FROM microsoft/dotnet:2.1-sdk AS build
COPY . .
WORKDIR /src/myProj
FROM build AS publish
RUN dotnet publish myProj.csproj -c Release -o /app
RUN dotnet pack /src/myProj.csproj -c Release -o /app
and use it in my image (that I don't want to build using the internet), instead of:
FROM microsoft/dotnet:2.1-sdk AS build
I did:
FROM docker_common AS build
I also tried to add the line: "RUN dotnet publish ..." when setting the workdir as the solution folder, and mark the "Microsoft Visual Studio Offline Packages" (unmark default "nuget.org").
Still, the above doesn't build correctly.
For not using the internet, you can follow the steps.
What is needed is to publish in visual studio, as following:
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-2.2
(Alternative publish in command line).
dotnet publish myProj.csproj -c Release /p:PublishProfile=Properties\PublishProfiles\
<myprofile>.pubxml /p:PublishDir=<proj_folder>\bin\Release\netcoreapp2.1\publish
or put in the Post-build event a line like:
dotnet publish $(ProjectDir)$(ProjectName).csproj -c $(Configuration)
/p:PublishProfile=Properties\PublishProfiles\PublishProfile.pubxml
/p:PublishDir=$(TargetDir)publish --no-build
... and in the Dockerfile I just did with need to do "COPY ..." from the relevant publish directory!
FROM microsoft/dotnet:2.1-runtime
COPY MyProjectFolder/bin/Release/netcoreapp2.1/publish /app
WORKDIR /app
ENTRYPOINT ["dotnet", "myproject.dll"]

Build multi project net core image using Dockerfile

I'm using the reference: https://docs.docker.com/engine/examples/dotnetcore/#prerequisites to create the following Dockerfile:
FROM microsoft/aspnetcore-build:2.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 microsoft/aspnetcore:2.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "aspnetapp.dll"]
However I have the following solution structure:
.sln
Dockerfile
------------WebAPP
------------WebAPP.Domain
I then modified the Dockerfile so I can target my WebAPP csproj etc.
FROM microsoft/aspnetcore-build AS builder
WORKDIR /app
# copy csproj and restore as distinct layers
COPY ./WebAPP/*.csproj ./
RUN dotnet restore
# copy everything else and build
COPY ./WebAPP ./
RUN dotnet publish -c Release -o out
# build runtime image
FROM microsoft/aspnetcore
WORKDIR /app
COPY --from=builder /app/out ./
ENV ASPNETCORE_ENVIRONMENT Production
ENTRYPOINT ["dotnet", "WebAPP.dll"]
However it fails on the dotnet publish step because it's lacking of the Domain project which can make sense. I have also added the RUN dotnet build step to make sure I had all dependencies and dlls and I did get a failure on the penultimate step:
Step 10/12 : COPY --from=builder /app/out ./
COPY failed: stat /var/lib/docker/aufs/mnt/9b7dda771a5bf433365f513a2bfe4cfae4199402b35c95d5f81c57367cdbb788/app/out: no such file or directory
Is there anything I am missing here?
If your WebApp has a reference to WebApp.Domain, you can simplify the DockerFile
FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "WebApp.dll"]