1
votes

I am totally new in docker/azure DevOps build pipelines. But I have to admit, it is a painful road. This suppose to be easy and it is not:)

What I want to achieve is to only build one project which has one referenced project in the solution. But I don't want to build the whole solution (as I have Xamarin projects which takes a little bit longer to build) As for SLN - I suppose the answer would be easier to find.

I did have this pipeline working when there was only one project without other projects being referenced. But right now, as I referenced one, it breaks.

Just for the records, I am using a build pipeline to create a docker image and deploy it to Azure Container Registry. But that is not important I suppose, because it is failing on building.

My Code structure

  • Solution

    • [Project] BuildChat <-- Referenced project by SignalR
    • [Project] Xamarin.IOS
    • [Project] Xamarin.Android
    • [Project] SignalRChat
      • [File] Docker

My initial file was created through Docker Support addon on VS (proposed here: asp.net core 2.0 - multiple projects solution docker file)

Of course, when I first used it it didn't have referenced projects. So I thought, ok, maybe I will just remove docker file and use Add-->Docker support once again. And it did change the dockerfile to include the referenced project (called BuildChat)

So after the changes my docker file looks following:

#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 ["SignalRChat/SignalRChat.csproj", "SignalRChat/"]
COPY ["BuildChat/BuildChat.csproj", "BuildChat/"]
RUN dotnet restore "SignalRChat/SignalRChat.csproj"
COPY . .
WORKDIR "/src/SignalRChat"
RUN dotnet build "SignalRChat.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "SignalRChat.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "SignalRChat.dll"]

But it is not working. Probably because docker cannot go outside the context. But then again, docker support doesn't know that?:D

I suppose that one option is to move it on SLN level and then to use docker build with -f to specify the file (i saw this as a suggestion) but I don't know how to include it in the azure build pipeline.

Maybe there are some other thoughts on how to achieve this (in this docker "hello world" program, which turns out to be very complicated:D)

My current build pipeline is following:

# Docker
# Build a Docker image 
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:
  dockerRegistryServiceConnection: 'MyProductDockerACR'
  imageRepository: 'mobile/signalr'
  containerRegistry: 'myAcrName.azurecr.io'
  dockerfilePath: '**/Dockerfile'
  tag: '$(Build.BuildNumber)'
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build and push stage
  jobs:  
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push image to container registry
      inputs:
        containerRegistry: $(dockerRegistryServiceConnection)
        repository:  $(imageRepository)
        command: 'buildAndPush'
        Dockerfile: $(dockerfilePath)
        tags: |
          $(tag)

and the error that is produced by the build pipeline is (cut to present the interesting part:) ):

Starting: Build and push image to container registry
==============================================================================
Task         : Docker
Description  : Build or push Docker images, login or logout, or run a Docker command
Version      : 2.166.1
Author       : Microsoft Corporation
Help         : https://aka.ms/azpipes-docker-tsg
==============================================================================
/usr/bin/docker build -f /home/vsts/work/1/s/SignalRChat/Dockerfile --label com.azure.dev.image.system.teamfoundationcollectionuri=https://dev.azure.com/myAzureDevops/ --label com.azure.dev.image.system.teamproject=Mobile --label com.azure.dev.image.build.repository.name=Mobile --label com.azure.dev.image.build.sourceversion=e1fcddf1507478434251b2c12a3f999ef23f7b70 --label com.azure.dev.image.build.repository.uri=https://[email protected]/myAzureDevops/Mobile/_git/Mobile --label com.azure.dev.image.build.sourcebranchname=master --label com.azure.dev.image.build.definitionname=Mobile --label com.azure.dev.image.build.buildnumber=20200423.7 --label com.azure.dev.image.build.builduri=vstfs:///Build/Build/26 -t ***/mobile/signalr:20200423.7 /home/vsts/work/1/s/SignalRChat
Sending build context to Docker daemon  2.509MB

[...]

Status: Downloaded newer image for mcr.microsoft.com/dotnet/core/sdk:3.1-buster
 ---> 4aa6a74611ff
Step 6/27 : WORKDIR /src
 ---> Running in abca9a0a7296
Removing intermediate container abca9a0a7296
 ---> 15699d4bddc2
Step 7/27 : COPY ["SignalRChat/SignalRChat.csproj", "SignalRChat/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder654251088/SignalRChat/SignalRChat.csproj: no such file or directory
##[error]COPY failed: stat /var/lib/docker/tmp/docker-builder654251088/SignalRChat/SignalRChat.csproj: no such file or directory
##[error]The process '/usr/bin/docker' failed with exit code 1

[UPDATE 14:00]

Moving the docker file to the solution level fixes the problem. But the question remains. What if I would want to dockerize yet another project. How to proceed then?

1

1 Answers

2
votes

I think you may have a wrong order here

COPY ["SignalRChat/SignalRChat.csproj", "SignalRChat/"]
COPY ["BuildChat/BuildChat.csproj", "BuildChat/"]

For instance I have two projects

  • SomeLib.csproj - This one is referenced by WeatherService.csproj
  • WeatherService.csproj

For this order:

COPY ["WeatherService/WeatherService.csproj", "WeatherService/"]
COPY ["SomeLib/SomeLib.csproj", "SomeLib/"]

I got this:

enter image description here

But for this order it works

COPY ["SomeLib/SomeLib.csproj", "SomeLib/"]
COPY ["WeatherService/WeatherService.csproj", "WeatherService/"]

enter image description here

Can you try to change COPY order:

COPY ["BuildChat/BuildChat.csproj", "BuildChat/"]
COPY ["SignalRChat/SignalRChat.csproj", "SignalRChat/"]

EDIT:

I tested what I wrote above directly on Azure DevOps and all went fine.

This is my DockerFile:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["SomeLib/SomeLib.csproj", "SomeLib/"]
COPY ["WeatherService/WeatherService.csproj", "WeatherService/"]
RUN dotnet restore "WeatherService/WeatherService.csproj"
COPY . .
WORKDIR "/src/WeatherService"
RUN dotnet build "WeatherService.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "WeatherService.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "WeatherService.dll"]

This is project structure:

Project structure

And YAML file:

- task: Docker@2
  displayName: Build and Push
  inputs:
    repository: $(imageName)
    command: build
    Dockerfile: docker-multiple-apps/Dockerfile
    tags: |
      build-on-agent

All you can find here.

This is log from Azure DevOps

log from Azure DevOps

Can you compare this with your approach? Sorry that I can't point you directly to to root cause but it works on my reference project.

EDIT2:

What is your solution name? Is it SignalRChat? And is this your root folder?

/home/vsts/work/1/s/SignalRChat/Dockerfile

Maybe your Dockerfile path is wrong?