Azure DevOps Pipeline: COPY failed: stat /var/lib/docker/…: no such file or directory

Summary

Running a docker build task in an Azure DevOps pipeline causes no such file or directory error.

...
Step 7/26 : COPY ["Hello-Blazor/Hello-Blazor.csproj", "Hello-Blazor/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder890404231/Hello-Blazor/Hello-Blazor.csproj: no such file or directory
##[error]COPY failed: stat /var/lib/docker/tmp/docker-builder890404231/Hello-Blazor/Hello-Blazor.csproj: no such file or directory
##[error]The process '/usr/bin/docker' failed with exit code 1
Finishing: Build an image

The error occurs when the pipeline task build context does not match the build context defined in the Dockerfile. By default it assumes the Dockerfile directory which is not always the case for Visual Studio generated solutions/projects. A buildContext attribute can be added to the pipeline task to explicitly set the build context directory required by the Dockerfile.

... 
buildContext: '$(Build.SourcesDirectory)/Hello-Blazor/'
...

Description

For the detailed cause of this error refer to http://torbenp.com/2020/07/copy-failed-no-such-file-or-directory/
The Azure Pipeline task needs to be explicitly configured to execute the docker build from the parent folder defined by the Dockerfile as it will otherwise assume the Dockerfile folder as the build context. The following shows the default pipeline task without an explicit build context.

...
    - task: Docker@2
      displayName: Build an image
      inputs:
        command: build
        dockerfile: '$(Build.SourcesDirectory)/Hello-Blazor/Hello-Blazor/Dockerfile'
        tags: |
          $(tag)
...

This can create a COPY build failure with the following details:

COPY error from Azure DevOps Pipeline
Azure DevOps Pipeline COPY Error

To make the parent folder of the Dockerfile the build context, add the ‘buildContext’ attribute to the pipeline task configuration.

...
    - task: Docker@2
      displayName: Build an image
      inputs:
        command: build
        dockerfile: '$(Build.SourcesDirectory)/Hello-Blazor/Hello-Blazor/Dockerfile'
        buildContext: '$(Build.SourcesDirectory)/Hello-Blazor/'
        tags: |
          $(tag)
...

COPY failed: stat /var/lib/docker/tmp/docker-builder392878620/Hello-Blazor/Hello-Blazor.csproj: no such file or directory

Summary

Running docker build within the Dockerfile folder causes no such file or directory error.

C:\Hello-Blazor\docker build --force-rm -t helloblazor:latest .
Sending build context to Docker daemon  2.653MB
...
COPY failed: stat /var/lib/docker/tmp/docker-builder392878620/Hello-Blazor/Hello-Blazor.csproj: no such file or directory

Move up one folder (parent folder of Dockerfile) to change the build context and provide path to the Dockerfile.

C:\docker build -f .\Hello-Blazor\Dockerfile --force-rm -t helloblazor:latest .

Description

When building a Docker image from a Visual Studio generated Dockerfile, such as a .NET Core project, the error ‘no such file or directory’ can occur if the right build context is missing. In Visual Studio generated solutions and projects, the Solution file (.sln) is often in a parent folder to the Project files and their individual Dockerfiles. This makes the Visual Studio solution folder the root build context to build all projects and this build context is assumed in the compiler generated Dockerfile for projects.

C:.
+---Hello-Blazor.sln    //Build Context
+---Hello-Blazor
|   +---Hello-Blazor.csproj
|   +---Dockerfile

The autogenerated Dockerfile for multi-staged builds will show the solution folder build context in the COPY and RUN operations.

...
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Hello-Blazor/Hello-Blazor.csproj", "Hello-Blazor/"]
RUN dotnet restore "Hello-Blazor/Hello-Blazor.csproj"
...

To build the Docker image, use the solution folder as the build context (current folder) and use the -f parameter to pass the Dockerfile path instead of building directly from the Dockerfile folder.

C:\docker build -f ./Hello-Blazor/Dockerfile --force-rm -t helloblazor:latest .

Manage Kubernetes with Visual Studio Code

Summary

This is a walkthrough to setup Visual Studio Code (VSCode) to manage an external Kubernetes cluster. In this example, VSCode will be connected to a Kubernetes Cluster running on Raspberry Pi. The VSCode extension provides visual object navigation of the cluster and terminal execution of kubectl to modify cluster objects.

Prerequisites

Description

The following steps will reference a Linux Kubernetes cluster as the source system and a Windows environment as the target system. For these steps there is an assumption that the Kubernetes configuration file (kubeconfig) has been added to the user profile of the master node on the Linux cluster.

pirate – is the Linux user profile (based on the Hypriot distribution)
192.168.0.20 / k8spiblue – is the Linux master node IP / hostname
192.168.0.21 / k8spiblack – is a Linux worker node IP / hostname
192.168.0.22 / k8spiyellow – is a Linux worker node IP / hostname
torben – is the Windows user profile

Steps

From the Windows target system, copy the Kubernetes configuration file (kubeconfig) from the Linux user profile to the Windows user profile.

C:\Users\Torben>scp pirate@192.168.0.20:/home/pirate/.kube/config ./.kube/config

Enter a password for the user (pirate) when prompted and perform a directory listing for verification

Copy kubeconfig

Launch VSCode, click Extensions on the Activity bar and search the Marketplace for ‘Kubernetes’.
Click ‘Install’ and install any dependencies if required, such as Kubectl and Helm.

VSCode Kubernetes

When installation is complete, select ‘Kubernetes’ from the Activity bar to open.

K8s Extension Installed

In the Kubernetes side bar, hover over Clusters and click the ellipses ‘…’ to select ‘Set kubeconfig’.
Select ‘+ Add new kubeconfig’ and navigate to the config file copied previously (%USERPROFILE%\.kube\config).
The Clusters node should now be connected to the remote cluster and the nodes can be expanded to show the cluster hosts.

K8s Cluster Configured

Expand a node to see the pods.

K8s Cluster Nodes

In the Terminal window, execute kubectl get nodes to get listing of the cluster nodes

K8s kubectl nodes

Select Explorer extension on the Activity pane and we can now edit object files and apply them with kubectl directly from Windows.

K8s File Explorer