Iot Edge: Building a Docker image from multi projects - docker

I can build and run in Visual Studio successfully, but I got an error when I am trying to build a docker image(TestModule) from a visual studio that references 2 projects (Microsoft.Azure.Devices.Edge.Util + ModuleLib). Any idea what wrong with my dockerfile? To build, I right-click on project> build & push IoT edge Modules (I'm using vs extension tool).
projects:
-TestModule
|--Dockerfile
-Microsoft.Azure.Devices.Edge.Util
-ModuleLib
TestModule.csproj
...
<ItemGroup>
<ProjectReference Include="..\Microsoft.Azure.Devices.Edge.Util\Microsoft.Azure.Devices.Edge.Util.csproj" />
<ProjectReference Include="..\ModuleLib\Microsoft.Azure.Devices.Edge.ModuleUtil.csproj" />
</ItemGroup>
...
Build Errors:
Step 4/12 : COPY Microsoft.Azure.Devices.Edge.Util/*.csproj ./Microsoft.Azure.Devices.Edge.Util/
COPY failed: no source files were specified
[ERROR]: COPY failed: no source files were specified
UPDATE:
*
if you try to build this inside DOCKERFILE, using VS Code, the file will not be able to get access because the context of the docker is set to the module folder access. Hence the correct command should be for setting context at root folder.
Run in Powershell in the root folder (replaced myacr.azurecr.io with you container):
docker build --rm -f .\TestModule\Dockerfile.windows-amd64 -t myacr.azurecr.io/testmodule:0.0.7-windows-amd64 .;if ($?) { docker push myacr.azurecr.io/testmodule:0.0.7-windows-amd64 }
Dockerfile in TestModule (Dockerfile.windows-amd64):
FROM microsoft/dotnet:2.1-sdk AS build-env
WORKDIR /app
COPY . .
RUN dotnet restore ./TestModule/TestModule.csproj
COPY . ./
RUN dotnet publish ./TestModule/TestModule.csproj -c Release -o out
FROM microsoft/dotnet:2.1-runtime-nanoserver-1809
WORKDIR /app
COPY --from=build-env /app/TestModule/out ./
ENTRYPOINT ["dotnet", "TestModule.dll"]
I created a DockerBuild.bat batch script in root project folder(replaced myacr.azurecr.io with you container), just enter as parameter a module name (lowercase) + version:
#echo off
Rem Run docker build image and push to Azure Container
IF "%~1"=="" (
ECHO Missing module name parameter lowercase. Ex: DockerBuild.bat modulename
EXIT
)
IF "%~2"=="" (
ECHO Missing version parameter. Ex: DockerBuild.bat modulename version
EXIT
)
set modulename=%~1
set version=%~2
echo Module name: %modulename%
echo Version: %version%
docker build --rm -f .\%modulename%\Dockerfile.windows-amd64 -t myacr.azurecr.io/%modulename%:%version%-windows-amd64 .
docker push myacr.azurecr.io/%modulename%:%version%-windows-amd64
echo The Docker build has completed

Related

cannot run docker build when using docker setup from Visual Studio

I created a web-project named ProjectService and added docker-support for it using Visual Studio 2022. I can build and debug the image pretty well from within VS.
Now I try to build and run the image from the command-line in order to have it within my build-pipeline. So I execute this from the root-directory of my repo:
docker build -t myrep/demo:latest ./ProjectService
However when I do that I get the following error:
#11 ERROR: "/ProjectService/ProjectService.csproj" not found: not found
#12 [build 4/8] COPY [DatabaseManager/DatabaseManager.csproj, DatabaseManager/]
#12 sha256:b881c00e01ebb7ea687c2f8c5d5f585e237bf6151b63cd21110ed1a7bdf74af6
#12 ERROR: "/DatabaseManager/DatabaseManager.csproj" not found: not found
I think this is because within my docker-file paths are relative:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["ProjectService/ProjectService.csproj", "ProjectService/"]
COPY ["DatabaseManager/DatabaseManager.csproj", "DatabaseManager/"]
RUN dotnet restore "ProjectService/ProjectService.csproj"
COPY . .
WORKDIR "/src/ProjectService"
RUN dotnet build "ProjectService.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ProjectService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectService.dll"]
when I execute docker from within the ProjectService-drectory itself, I get the same error, though.
My folder-structure is this:
root
ProjectService
ProjectService.csproj
DockerFile
DatabaseManager
DatabaseManager.csproj
where ProjectService depends on DatabaseManager.
Your Dockerfile looks like it assumes that the build context is the root directory.
So to build it you can either do it from the root directory with
docker build -t myrep/demo:latest -f ProjectService/Dockerfile .
or from the ProjectService directory with
docker build -t myrep/demo:latest ..
A 3rd option is to move the Dockerfile to the root directory. Then your Dockerfile will be in the directory that's assumed to be the build context. That's how most projects are organized. Then you can build with
docker build -t myrep/demo:latest .

Visual Studio generated Dockerfile does not work with manual docker build

I want to dockerize an existing .NET core 5 app and used the container tools to generate a Dockerfile. When I debug with Visual Studio 2022 it works but when I manually run it with the command docker build -t some-name . it generates the following error:
Step 7/21 : COPY ["MechEng.MovableBridges.Api/MechEng.MovableBridges.Api.csproj", "MechEng.MovableBridges.Api/"]
COPY failed: file not found in build context or excluded by .dockerignore: stat MechEng.MovableBridges.Api/MechEng.MovableBridges.Api.csproj: file does not exist
Why doesn't it find the file?
This is my Dockerfile that is inside the MechEng.MovableBridges.Api folder:
#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/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["MechEng.MovableBridges.Api/MechEng.MovableBridges.Api.csproj", "MechEng.MovableBridges.Api/"]
COPY ["MechEng.MovableBridges.Infrastructure/MechEng.MovableBridges.Infrastructure.csproj", "MechEng.MovableBridges.Infrastructure/"]
COPY ["MechEng.MovableBridges.MathCad/MechEng.MovableBridges.Infrastructure.MathCad.csproj", "MechEng.MovableBridges.MathCad/"]
COPY ["MechEng.MovableBridges.Application/MechEng.MovableBridges.Application.csproj", "MechEng.MovableBridges.Application/"]
COPY ["MechEng.MovableBridges.Domain/MechEng.MovableBridges.Domain.csproj", "MechEng.MovableBridges.Domain/"]
RUN dotnet restore "MechEng.MovableBridges.Api/MechEng.MovableBridges.Api.csproj"
COPY . .
WORKDIR "/src/MechEng.MovableBridges.Api"
RUN dotnet build "MechEng.MovableBridges.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MechEng.MovableBridges.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MechEng.MovableBridges.Api.dll"]
Your command fails, because the build context is wrong. Visual studio is using the solution root folder as build context, you are (probably) using the project's dockerfile's location. You can read more about the docker build command here.
Your command should look similar to this:
docker build -f "<path-to-your-dockerfile>" -t some-name "<!!!path-to-your-solution-folder!!!>"
You can see the exact command executed by visual studio in the output window, with "Container Tools" selected from the dropdown box.
In visual studio, you can move the docker file to one back folder.
For example, folder1/folder2/dockerfile move to folder1/dockerfile and build the image.
Docker build -t imageName .
Docker run -p 7778:80 imageName

Error while executing gradle command in docker file

FROM gradle:4.2.1-jdk8-alpine
WORKDIR /app
ADD --chown=gradle:gradle /app/producer /app
RUN ./gradlew build --stacktrace
Project Structure is as follows . It is a muti module project:
<code>
--springbootdocker (Root folder of project) <br>
--producer (Sub module Producer) <br>
-- Dockerfile (for Producer)<br>
--consumer (Sub module Consumer) <br>
-- Dockerfile (for Consumer)<br
</code>
This is the docker file.
While doing docker build: getting this error
failed to build: ADD failed: stat
/var/lib/docker/tmp/docker-builder561553413/app/producer: no such
file or directory
Here you have to fix a couple of things in your Dockerfile.
ADD command
ADD command requires two parameters <src> and <dest>. So, you should provide producer path from the host as src container path as dest. But in such cases recommended to use COPY command.
COPY --chown=gradle:gradle producer /app/producer
RUN ./gradlew
It should be just gradle and it's WORKDIR should be /app/producer. If not it'll fail and you'll get,
Failed to create parent directory '/app/.gradle' when creating directory
'/app/.gradle/4.2.1/fileHashes' error when running gradle command.
Because the WORKDIR /app owns by user root.
Recommend to divide RUN gradle build --stacktrace as ENTRYPOINT and CMD.
Complete Dockerfile
FROM gradle:4.2.1-jdk8-alpine
WORKDIR /app
COPY --chown=gradle:gradle producer /app/producer
WORKDIR /app/producer
ENTRYPOINT ["gradle"]
CMD ["build", "--stacktrace"]
The partial output of docker build
Starting a Gradle Daemon (subsequent builds will be faster)
:buildEnvironment
------------------------------------------------------------
Root project
------------------------------------------------------------
classpath
No dependencies
BUILD SUCCESSFUL in 5s
1 actionable task: 1 executed
This is the dockerfile which is currently working without any error.
FROM gradle:4.10.0-jdk8-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src/producer
WORKDIR /home/gradle/src/producer
RUN gradle bootJar --no-daemon --stacktrace
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=build/libs/*.jar
COPY --from=build /home/gradle/src/producer/build/libs/*.jar producer.jar
ENTRYPOINT ["java","-jar","/producer.jar"]
ADDed files need to be under the directory where the docker build is being run from, so depending on your structure you probably want something like:
ADD myProject /app
Assuming you have a structure like:
Dockerfile
myProject/

.net core docker is working via VS2019, but image build is getting error and not working

"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values",
"httpPort": 52706,
"useSSL": true,
"sslPort": 44344
}
This gives the output when it is run through visual studio
But on build, it throws error
DockerFile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 83
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["testdocker/testdocker.csproj", "testdocker/"]
RUN dotnet restore "testdocker/testdocker.csproj"
COPY . .
WORKDIR "/src/testdocker"
RUN dotnet build "testdocker.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "testdocker.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENV ASPNETCORE_URLS http://+:83
ENTRYPOINT ["dotnet", "testdocker.dll"]
to build the docker image
docker build -t testdock .
but it gives
COPY failed: stat /var/lib/docker/tmp/docker-builder666564019/testdocker/testdocker.csproj,: no such file or directory
Please help to get the dockerfile rewritten so as to complete this build and run the app
If you look at the Container Tools output in Visual Studio, you'll see a line like:
docker build -f "C:\Users\foo\source\MySolution\TestDocker\Dockerfile" -t testdocker:dev --target base --label "com.microsoft.created-by=visual-studio" "C:\Users\foo\source\MySolution"
When building an image for a Linux container on Windows, Docker lifts the contents of the active directory into the MobyLinux VM and all the copy commands and such are run against that path in the MobyLinux VM, not your local filesystem. Because projects very often need access to other projects in the same solution in order to build, the Dockerfiles created by Visual Studio are relative to your solution directory, such that the entire solution directory is lifted in MobyLinux.
Very likely, what you've done is navigate directly into your project directory and run the Dockerfile from there, without passing a directory to use as the "root". As such, Docker simply lifts the current, i.e your project, directory and the resulting paths in the MobyLinux VM no longer match what's in the Dockerfile.
Long and short, if you want to manually do a build of the image, then you need to ensure that the active directory that's lifted is your solution directory, not your project directory. You can achieve that simply by passing that last string of the command above to your own command, which will make it relative to your solution.
The fix for me appeared to be:
docker build -f PROJECT_DIR\Dockerfile .
When ran from the solution directory.
Andrew's sample works for me.
My command:
docker build -f helloworld\dockerfile -t sr-app .
Conceptually COPY takes path as specified in COPY command, just an example
COPY server/nginx/nginx.conf /etc/nginx/conf.d
so its necessary to run docker file from parents of server say path is like this.
xyz-app/server/nginx/nginx.conf
then you need to go to xyz-app directory and then run (And to specify docker file path use -f)
docker build -f server/nginx/Dockerfile -t app.v1.0 .

COPY command failing when running DOCKER BUILD

I'm trying to create a Docker image but it's not working. I'm trying to run this Docker command from the CLI and I'm getting the following error:
(from the <repo root>/src/Services/Accounts/Accounts.Api)
> docker build .
Error message:
Step 7/18 : COPY ["src/Services/Accounts/Accounts.Api/Accounts.Api.csproj", "src/Services/Accounts/Accounts.Api/"]
COPY failed: stat /var/lib/docker/tmp/docker-builder937056687/src/Services/Accounts/Accounts.Api/Accounts.Api.csproj: no such file or directory
and here's my Dockerfile
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
RUN ls -al
COPY ["src/Services/Accounts/Accounts.Api/Accounts.Api.csproj", "src/Services/Accounts/Accounts.Api/"]
COPY ["src/Services/Accounts/Accounts.Api/NuGet.config", "src/Services/Accounts/Accounts.Api/"]
RUN dotnet restore "src/Services/Accounts/Accounts.Api/Accounts.Api.csproj"
COPY . .
WORKDIR "/src/src/Services/Accounts/Accounts.Api"
RUN dotnet build "Accounts.Api.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Accounts.Api.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Hornet.Accounts.Api.dll"]
I've also tried running this from the repo root directory:
> docker build .\src\Services\Accounts\Accounts.Api
Why is it trying to find my files in some /var/lib/docker/tmp/blah folder?
Further info:
Windows 10 OS
Docker CE with Linux Containers
VSCode
I think we can solve this by clarifying how to use the build context and how to specify the location of the Dockerfile.
The Docker build command usage looks like this:
docker build [OPTIONS] PATH
Your build context is the location that you define with PATH, Docker can use the files in the build context for the build. (You cannot use files outside the build context for the build.)
In the Dockerfile in your COPY statements you are specifying the source files' location relative to the root of your repo. This implies that
You should run your build command from the <root of your repo> with PATH . like this:
docker build .
You have not specified the path of your Dockerfile in the question, but it seems to me that it's in a subfolder of your repo. To make your build work issue the docker build command from the <root of your repo> like this:
docker build -f <path to Dockerfile> .
Your Dockerfile must be in the build context.
I think getting the build context and the location of the Dockerfile right will fix your build.
Also remember to use the -t flag to tag your image.
Why is it trying to find my files in some /var/lib/docker/tmp/blah folder?
As you probably know, Docker uses a Linux VM under the hood in the Docker for Windows app to develop Linux based containers. This location simply refers to the location in the VM.

Resources