I'm looking at this tutorial:
https://learn.microsoft.com/en-us/learn/modules/implement-docker-multi-stage-builds/3-examine-multi-stage-dockerfiles
And this part confuses me:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["WebApplication1.csproj", ""]
RUN dotnet restore "./WebApplication1.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "WebApplication1.csproj" -c Release -o /app/build
Why would you use WORKDIR twice here? Aren't we already in the src?
Does the dot at the end (/src/.) has any additional meaning?
Adding twice WORKDIR is for clarity. As best practise adding WORKDIR with absolute path is recommended for readability and maintenance purpose.
Working directory can also be verify as below
docker run -it imageName pwd
replace imageName -with actual Image Name
pwd with cd (windows current directory command)
Link for Docker best practises, refer WORKDIR section.
Related
Let's take an example of dotnet application code
I have an application code present at
D:\eshop\DotneteShopOnWeb\src\Web\Application.sln
and I have multiple projects in the "Application.sln" like Web, API, Test
every project is having its own Dockerfile like
D:\eshop\DotneteShopOnWeb\src\Web>Dockerfile
The Dockerfile is as below
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS build
WORKDIR /app
COPY *.sln .
COPY . .
WORKDIR /app/src/Web
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./
ENV ASPNETCORE_ENVIRONMENT Development
ENTRYPOINT ["dotnet", "Web.dll"]
I am executing the docker build command Dockerfile location.
I have also tried docker build -t dotnetcore-eshop-mvc-manual -f src/Web/Dockerfile . from D:\eshop\DotneteShopOnWeb>
I am getting errors in RUN dotnet restore as the sln file is not getting copied into the work directory.
Please let me know what modification I need in COPY to copy content from the previous directory.
you are changing the working directory before restoring. I mean that your .sln files are in the path /app but your restoring is executed inside /app/src/Web location. you should do something like this to copy .sln files.
COPY *.sln .
COPY . .
WORKDIR /app/src/Web
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/sdk:5.0-focal AS runtime
WORKDIR /app
COPY --from=build /app/src/Web/out ./
ENV ASPNETCORE_ENVIRONMENT Development
ENTRYPOINT ["dotnet", "Web.dll"]
I have .sln file and Dockerfile at a different location on my local hard drive.
Till now I work on a source code where .sln file and Dockerfile are present at the same location.
I am facing difficulty to configure it correctly.
I have .sln file at the location CompanyCarsDocker\CompanyCarsDocker\CompanyCarsDocker.sln
And My Dockerfile is present inside CompanyCarsDocker\CompanyCarsDocker\CarApi\Dockerfile
-
Below is my Dockerfile
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 54411
FROM microsoft/aspnetcore-build:2.0 AS builder
WORKDIR /src
COPY . ./*.sln ./
ADD ./site /inetpub/wwwroot
COPY ./CarApi.csproj CarApi/
RUN dotnet restore
COPY . .
WORKDIR /src/CarApi
RUN dotnet build -c Release -o /app
FROM builder AS publish
RUN dotnet publish -c Release -o /app
FROM base AS production
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "CarApi.dll"]
I have added ADD ./site /inetpub/wwwroot for testing purpose. I am getting
ADD failed: CreateFile \\?\C:\ProgramData\Docker\tmp\docker-builder782713904\site: The system cannot find the file specified.
Same error I am also Getting at COPY ./CarApi.csproj CarApi/
Please let me know if I configured something wrong in the Dockerfile.
You can use the -f flag of docker build to specify the path to the Dockerfile
Make sure you’re current working directory is the one which has the sln file and rest of the project. Run the command docker build -f <path to Dockerfile> .
your .sln file is two directories up so you should use
COPY ../../*.sln ./
instead of
COPY . ./*.sln ./
I'm trying to move ASP.NET Core project to docker linux container, however I cannot build up a proper image. When I create default dockerfile (through VisualStudio Add -> DockerSupport) it's setting up paths for COPY to all of the projects. However when I run docker build -t . it pop's out error "no such file or directory". I've tried to stick with official docker documentation with moving asp.net core to docker containers and here is the code I ended with:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ./ ./
RUN dotnet restore "myproject.csproj"
COPY . .
WORKDIR "/src/myproject"
RUN dotnet build "myproject.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "myproject.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "myproject.dll"]
This is the command im using to build up an image:
docker build -t myapp -f myproject/Dockerfile .
I'm building it from the parent directory, because when I was using current working directory it wasn't finding all the .csproj files. When I run this image it doesn't work - I know there are wrong paths, however I have no idea where is the error in logic. Current error is "Program does not contain a static 'Main' method suitable for an entry point" and "A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/app/'. Failed to run as a self-contained app. If this should be a framework-dependent app, specify the appropriate framework in /app/myproject.runtimeconfig.json"
Try the following based off this documentation replace myproject with project name
FROM microsoft/dotnet:sdk 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/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", “myproject.dll"]
Then build and run with the following commands:
docker build -t myproject .
docker run -d -p 8080:80 --name myapp myproject
You should not specify RUN dotnet build "myproject.csproj" -c Release -o /app with -o /app which will output in the same folder with build layer.
Try
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["myproject/*.csproj", "myproject/"]
RUN dotnet restore "myproject/myproject.csproj"
COPY . .
WORKDIR /src/myproject
RUN dotnet build "myproject.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "myproject.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "myproject.dll"]
I just started a new solution with a .NET Core Project (2.1) using visual studio 15.8.8. It can run and debug it by setting the docker compose file as a startup project. It works!
Logically, I should be able to build the docker image with a simple commandline statement. However, it complains that the csproj cannot be found. This is strange. The file exist and as I told, I can run it from visual studio. I tried it from one directory up and the directory that has the dockerfile. Same problem.
How can I solve this? The only thing I want is simply build my image and then run it by just using docker commands.
Dockerfile
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["TryNewDocker2/TryNewDocker2.csproj", "TryNewDocker2/"]
RUN dotnet restore "TryNewDocker2/TryNewDocker2.csproj"
COPY . .
WORKDIR "/src/TryNewDocker2"
RUN dotnet build "TryNewDocker2.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TryNewDocker2.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TryNewDocker2.dll"]
Het is the compose file:
version: '3.4'
services:
trynewdocker2:
image: ${DOCKER_REGISTRY}trynewdocker2
build:
context: .
dockerfile: TryNewDocker2/Dockerfile
Logically, I want "docker-compose up" to keep working when fixing this problem.
This is caused by the wrong root folder for the file path in dockerfile.
For launching from Docker, its root folder is C:\Users\...\repos\TryNewDocker2, but while running from command, its root fodler is C:\Users\...\repos\TryNewDocker2\TryNewDocker2, so the path for TryNewDocker2.csproj has changed from TryNewDocker2/TryNewDocker2.csproj to TryNewDocker2.csproj
Try dockerfile below:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 59162
EXPOSE 44342
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["TryNewDocker2.csproj", "TryNewDocker2/"]
RUN dotnet restore "TryNewDocker2/TryNewDocker2.csproj"
COPY . ./TryNewDocker2/
WORKDIR "/src/TryNewDocker2"
RUN dotnet build "TryNewDocker2.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TryNewDocker2.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TryNewDocker2.dll"]
Update
For working in both Docker and command, do not change your dockerfile, and from path below to run your command with specifying the dockerfile path.
C:\Users\...\repos\TryNewDocker2>docker build -t gogo -f TryNewDocker2/Dockerfile .
For those of you who end up here years later like I did, I'll share my experience.
My problem was caused by the auto-generated Dockerfile that came from Visual Studio's "add > Docker Support..." was on the same level as my .csproj file.
The specific line causing me trouble was COPY ["MyApp/MyApp.csproj", "MyApp/"] which should have been just COPY ["MyApp.csproj", "MyApp/"]. Removing the extra MyApp/ in front of the .csproj got the build working fine.
Special thanks to Edward in the answer above for pointing me in the right direction.
I am trying to make use of this Docker construct:
Optionally a name can be given to a new build stage by adding AS name
to the FROM instruction. The name can be used in subsequent FROM and
COPY --from= instructions to refer to the image built in
this stage.
But I get this message:
COPY failed: stat /var/lib/docker/tmp/docker-builder869050639/-–from=build-env:
no such file or directory
Is copying files from a previous stage supported on Docker for Windows 17.09.0-ce-win33 (13620)? This is the Dockerfile:
FROM microsoft/dotnet:2.0-sdk AS build-env
WORKDIR /app
COPY ./ ./
RUN dotnet build ProviderApi.csproj
RUN dotnet publish ProviderApi.csproj -c Release -r linux-x64 -o out
FROM microsoft/dotnet:2.0-runtime-deps
WORKDIR /app
COPY -–from=build-env /app/out/ ./
EXPOSE 80
ENTRYPOINT ["./ProviderApi"]
The problem was that the destination directory was not present in the docker image of the final build stage. Here is the working Dockerfile for future reference.
FROM microsoft/aspnetcore-build:2.0.3-stretch AS build-env
WORKDIR /app
COPY . ./
RUN dotnet build ProviderApi.csproj
RUN dotnet publish ProviderApi.csproj -c Release -r linux-x64 -o out
FROM microsoft/aspnetcore:2.0.3-stretch
RUN mkdir /app
COPY --from=build-env /app/out /app
ENV ASPNETCORE_URLS=http://+:5001
EXPOSE 5001
ENTRYPOINT ["/app/ProviderApi"]
have you tried with lowercase "as"? (seems like a long-shot, I see examples of both around)
FROM microsoft/dotnet:2.0-sdk as build-env
or the more basic
FROM microsoft/dotnet:2.0-sdk
COPY -–from=0 /app/out/ ./