Dockerfile doesn't seem to run while debugging in Visual Studio 2019 - visual-studio

The past few weeks i've been working on a project which is built in C# .NET Core in Visual Studio 2019. I enabled Docker support and am using docker-compose to spin up 2 containers (it starts an identityserver4 and webapi). I've created dockerfiles for both projects and created a docker-compose file for starting up the service stack.
The issue i'm running into is that when i run the docker-compose in Visual Studio Debugging mode, it doesnt seem to run my Dockerfile. In the lasts steps in my Dockerfile, I copy some files around and execute a command. These do not get run. However when I use docker build in my commandline, it DOES execute those Dockerfile commands.
Attached my 2 docker files & docker compose.
Web API Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Api/MyApp.Api.Core/MyApp.Api.Core.csproj", "Api/MyApp.Api.Core/"]
COPY ["Api/MyApp.Api.Base/MyApp.Api.Base.csproj", "Api/MyApp.Api.Base/"]
COPY ["Base/MyApp.Base.Contracts/MyApp.Base.Contracts.csproj", "Base/MyApp.Base.Contracts/"]
COPY ["Base/MyApp.Base.Model/MyApp.Base.Model.csproj", "Base/MyApp.Base.Model/"]
COPY ["Data/MyApp.Data.EntityFramework/MyApp.Data.EntityFramework.csproj", "Data/MyApp.Data.EntityFramework/"]
COPY ["ContactpersoonService.cs/MyApp.Services.csproj", "ContactpersoonService.cs/"]
COPY ["Apps/MyApp.Apps.Settings/MyApp.Apps.Settings.csproj", "Apps/MyApp.Apps.Settings/"]
RUN dotnet restore "Api/MyApp.Api.Core/MyApp.Api.Core.csproj"
COPY . .
WORKDIR "/src/Api/MyApp.Api.Core"
RUN dotnet build "MyApp.Api.Core.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "MyApp.Api.Core.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY Api/MyApp.Api.Core/Security/Certificates /app/Security/Certificates
RUN mkdir -p /usr/local/share/ca-certificates/identityserver
RUN chmod -R 777 /usr/local/share/ca-certificates/identityserver
RUN cp /app/Security/Certificates/* /usr/local/share/ca-certificates/identityserver
RUN update-ca-certificates
ENTRYPOINT ["dotnet", "MyApp.Api.Core.dll"]
IdentityServer Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["Api/MyApp.Api.IdentityServer/MyApp.Api.IdentityServer.csproj", "Api/MyApp.Api.IdentityServer/"]
COPY ["Api/MyApp.Api.Base/MyApp.Api.Base.csproj", "Api/MyApp.Api.Base/"]
COPY ["Base/MyApp.Base.Contracts/MyApp.Base.Contracts.csproj", "Base/MyApp.Base.Contracts/"]
COPY ["Base/MyApp.Base.Model/MyApp.Base.Model.csproj", "Base/MyApp.Base.Model/"]
COPY ["Data/MyApp.Data.EntityFramework/MyApp.Data.EntityFramework.csproj", "Data/MyApp.Data.EntityFramework/"]
COPY ["Apps/MyApp.Apps.Settings/MyApp.Apps.Settings.csproj", "Apps/MyApp.Apps.Settings/"]
RUN dotnet restore "Api/MyApp.Api.IdentityServer/MyApp.Api.IdentityServer.csproj"
COPY . .
WORKDIR "/src/Api/MyApp.Api.IdentityServer"
RUN dotnet build "MyApp.Api.IdentityServer.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "MyApp.Api.IdentityServer.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
COPY Api/MyApp.Api.Core/Security/Certificates /app/Security/Certificates
RUN mkdir -p /usr/local/share/ca-certificates/identityserver
RUN chmod -R 777 /usr/local/share/ca-certificates/identityserver
RUN cp /app/Security/Certificates/* /usr/local/share/ca-certificates/identityserver
RUN update-ca-certificates
ENTRYPOINT ["dotnet", "MyApp.Api.IdentityServer.dll"]
docker-compose.yaml:
version: '3.4'
services:
myapp.api.core:
image: ${DOCKER_REGISTRY-}myappapicore
build:
context: .
dockerfile: Api/MyApp.Api.Core/Dockerfile
links:
- myapp.identity.api:identityserver
ports:
- "52008:80"
volumes:
- "C:/Projects/User/MyApp.Api/Api/MyApp.Api.Core/Security/Certificates/ca.crt:/usr/local/share/ca-certificates/identityserver/identityserver.crt:ro"
networks:
app_net:
ipv4_address: 192.168.1.200
myapp.identity.api:
image: ${DOCKER_REGISTRY-}myappapiidentityserver
build:
context: .
dockerfile: Identity/MyApp.Identity.Api/Dockerfile
ports:
- "5000:80"
- "5001:443"
volumes:
- "C:/Projects/User/MyApp.Api/Api/MyApp.Api.IdentityServer/Security/Certificates/ca.crt:/usr/local/share/ca-certificates/identityserver/identityserver.crt:ro"
networks:
app_net:
ipv4_address: 192.168.1.201
networks:
app_net:
external: true
I'm using Visual Studio 2019 (16.3.4)

This is apparently by design as a "Fast mode" optimization in Visual Studio 2019. See the documentation for debugging in containers here.
What it states is that "Fast mode" is the default behavior when debugging containers in VS 2019. In this mode, only the first stage (base) of a multi-stage build is built according to the Dockerfile. VS then handles the rest on the host machine, ignoring the Dockerfile, and shares the output to the container by using volume mounting. This means that any custom steps you add to other stages will be ignored when using the Debug configuration in VS 2019. (The reason given for this non-obvious, and therefore potentially frustrating, optimization is that builds are much slower in a container than on the local machine.) Note that this optimization only happens when using the Debug configuration. The Release configuration will use the entire Dockerfile.
Your options are:
Place your custom steps in the first (base) step of the Dockerfile.
or
Disable this optimization by editing the project file like this:
<PropertyGroup>
<ContainerDevelopmentMode>Regular</ContainerDevelopmentMode>
</PropertyGroup>
Also keep in mind that it will try to reuse a previously built container if possible, so you may need to perform a Clean or Rebuild in order to force the build to create a new version of the container.
Good luck!
** EDIT **
It seems that there is an issue when trying to use the ContainerDevelopmentMode flag after Container Orchestration Support (in this case, Docker Compose) is added. See this issue. It is suggested in the issue discussion that this flag could be used on the docker-compose.dcproj file, but there is a bug (still not fixed) that keeps that approach from working.
A third option, hinted at in my previous answer but not made explicit, would be:
Switch your solution configuration from Debug to Release.
This works, but clearly isn't ideal when you're trying to debug your application.

Related

An issue with resolving directory names when building a docker container for an asp.net core 3.1 web app

Visual Studio 2019 generates a docker file whose COPY statement looks like the following due to the way that the application's folders are structured:
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["MyWebApp/MyWebApp.csproj", "MyWebApp/"]
COPY ["../../core/Logic/Logic.csproj", "../../core/Logic/"]
COPY ["../../core/Models/Models.csproj", "../../core/Models/"]
RUN dotnet restore "MyWebApp/MyWebApp.csproj"
COPY . .
WORKDIR "/src/MyWebApp"
RUN dotnet build "MyWebApp.csproj" -c Release -o /app/build
I keep getting the following error message when running docker compose command:
=> ERROR [build 4/9] COPY [../../core/Logic/Logic.csproj,
../../core/Logic/] 0.0s
=> ERROR [build 5/9] COPY [../../core/Models/Models.csproj, ../../core/Models/]
We cannot restructure the folders in VS 2019 as it has been set up in that way due to some reasons. The docker file resides in MyWebApp project's folder and the docker compose file is in the parent folder of MyWebApp folder where the solution resides. Even I moved the docker file adjacent to the docker compose file but it was not conclusive.
The following code snippet is the docker-compose file:
version: '3.4'
services:
mywebapp:
image: ${DOCKER_REGISTRY-}mywebapp
build:
context: .
dockerfile: MyWebApp/Dockerfile
ports:
- 8080:80
- 8443:443
What is the workaround or solution to address this problem?
If your file structure is:
docker-compose.yml
MyWebApp/MyWebApp.csproj
core/Logic/Logic.csproj
core/Models/Models.csproj
Your Dockerfile should be:
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["MyWebApp/MyWebApp.csproj", "MyWebApp/"]
COPY ["core/Logic/Logic.csproj", "../../core/Logic/"]
COPY ["core/Models/Models.csproj", "../../core/Models/"]
RUN dotnet restore "MyWebApp/MyWebApp.csproj"
COPY . .
WORKDIR "/src/MyWebApp"
RUN dotnet build "MyWebApp.csproj" -c Release -o /app/build
Why?
Because the current working directory is always the context directory. Context can be set using docker-compose's build.context field. In your example, the context is the solution root. So the Dockerfile is executed from that directory, irrespective or where it's placed.
You cannot access files outside the context directory.
Eg. if context resolves to /a/b/c, Dockerfile can't COPY or use files in /a/b/d

Trying to create docker image at command prompt getting docker build error

Created dotnet core mvc application. Tried to create docker image for Windows containers. When I execute docker build command getting below error.
C:\Program Files\dotnet\sdk\3.1.404\NuGet.targets(128,5): error : Unable to load the service index for source https://api.nuget.org/v3/index.json. [C:\src\dockertestwindows\dockertestwindows.csproj]
C:\Program Files\dotnet\sdk\3.1.404\NuGet.targets(128,5): error : No such host is known. [C:\src\dockertestwindows\dockertestwindows.csproj]
The command 'cmd /S /C dotnet restore "dockertestwindows/dockertestwindows.csproj"' returned a non-zero code: 1
My docker file is
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
#For more information, please see https://aka.ms/containercompat
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY ["DockerWindowsCore/DockerWindowsCore.csproj", "DockerWindowsCore/"]
RUN dotnet restore "DockerWindowsCore/DockerWindowsCore.csproj"
COPY . .
WORKDIR "/src/DockerWindowsCore"
RUN dotnet build "DockerWindowsCore.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "DockerWindowsCore.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerWindowsCore.dll"]
After connecting to VPN issue is resolved. I think its firewall issue.

Asp.Net core container isn't ignoring node_modules and won't start because of it existing

I have an asp.net core project I am working on starting and I am getting everything setup for the local docker containers and an Angular app nested inside of the project. The app will launch perfectly fine if there isn't a node_modules folder. After installing my packages for Angular and running the container the app will never launch. I have tried messing with the .dockerignore and I cannot get the folder to get out of my builds.
.dockerignore:
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules*
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
Dockerfile and Compose:
#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 ["FileConverter.Api/FileConverter.Api.csproj", "FileConverter.Api/"]
RUN dotnet restore "FileConverter.Api/FileConverter.Api.csproj"
COPY . .
WORKDIR "/src/FileConverter.Api"
RUN dotnet build "FileConverter.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "FileConverter.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FileConverter.Api.dll"]
version: '3.4'
services:
fileconverter.api:
image: ${DOCKER_REGISTRY-}fileconverterapi
build:
context: .
dockerfile: FileConverter.Api/Dockerfile

Docker COPY fails in Rider when running VS generated dockerfile

I'm running into problems when trying to run a dockerfile that I created in VS2017 in Rider 2019.2. The Dockerfile works fine in VS2017, but since the company I work for also allows developers to use other IDE's we need the Dockerfile to work in Rider (for example) too.
I added a new Docker project wihtin my solution by adding Container Orchestrator Support in VS2017.
My .sln project structure is:
Bram.Website
> Bram.Website // contains the Dockerfile
> docker-compose // contains docker-compose.yml
The generated Dockerfile looks like this:
FROM microsoft/aspnet:4.7.2-windowsservercore-1803
ARG source
WORKDIR /inetpub/wwwrootDock
COPY ${source:-obj/Docker/publish} .
The generated docker-compose.yml is:
version: '3.4'
services:
bram.website:
image: ${DOCKER_REGISTRY-}bramwebsite
build:
context: .\Bram.Website
dockerfile: Dockerfile
I changed my JetBrains build configuration according to the information in this article: https://blog.jetbrains.com/dotnet/2018/07/18/debugging-asp-net-core-apps-local-docker-container/
My config now looks like:
My build command is:
docker build -t <image_tag> . && docker run -p 8000:80 --name bramwebsite <image_tag>
When I try to build this I get the following output:
Deploying 'bram-website Dockerfile: Bram.Website/Dockerfile'...
Building image...
Step 1/4 : FROM microsoft/aspnet:4.7.2-windowsservercore-1803
---> d58c3fe3a54e
Step 2/4 : ARG source
---> Using cache
---> 7be7e1854e6f
Step 3/4 : WORKDIR /inetpub/wwwroot
---> Using cache
---> 6d53dbdcf2cd
Step 4/4 : COPY ${source:-obj/Docker/publish} .
Error: ResponseItem.ErrorDetail[code=<null>,message=COPY failed: CreateFile \\?\C:\ProgramData\Docker\tmp\docker-builder371292226\obj\Docker\publish: The system cannot find the file specified.]
Failed to deploy 'bram-website Dockerfile: Bram.Website/Dockerfile': COPY failed: CreateFile \\?\C:\ProgramData\Docker\tmp\docker-builder371292226\obj\Docker\publish: The system cannot find the file specified.
I'm not sure if this is a problem with my config or if this is an issue in Rider or in the way VS generates the files. The folder at 'C:\ProgramData\Docker\tmp' appears to be empty. My best guess at the moment is that Rider is having difficulties with the 'source' macro that is injected by VS2017? Any help or insight is greatly appreciated.

How to setup a docker project (dcproj) for a dotnet core Web API app in VS2017

I'm using dotnetcore to develop applications and one thing I noticed when creating a aspnetcore (2.1) web api was the option to "Enable Docker" on the project. See below:
This was really great for allowing me to run my web application against my local docker for debugging! :-D I see that I have a new .dcproj file for the docker project, a docker file in my web api and a yml file in the docker project. Everything I needed to run in debug.
Now I'm creating a dotnetcore console application (again core 2.1 is the version I'm using). Unfortunately, I dont have an "Enable Docker Support" option for console apps and would like to run my console app in my local docker instance. Visual studio version I'm running is as follows:
I had a look for and can't seem to find the docker project as a project type template. So I resorted to copying over the docker project from my web app and modifying it to run my console app... needless to say I'm not able to get this running. I get the following error when I try to launch the docker compose:
Failed to launch debug adapter
My docker file is identical to the one from the web project (that works), other than my project and dll names (these are set correctly).
My yml file is the same also, other than the names being changed also. Not sure what I'm doing wrong - has anyone managed to achieve this? I ultimately want to debug my console application when it's running in docker through Visual Studio debug.
Thanks for any pointers in advance!!
For verbosity, here's my Dockerfile:
FROM microsoft/dotnet:2.1.2-runtime-alpine3.7 AS base
WORKDIR /app
EXPOSE 52649
EXPOSE 44331
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY AI.EmitterJob.csproj AI.EmitterJob/
RUN dotnet restore AI.EmitterJob/AI.EmitterJob.csproj
COPY . .
WORKDIR /src/AI.EmitterJob
RUN dotnet build AI.EmitterJob.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish AI.EmitterJob.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "AI.EmitterJob.dll"]
And docker-compose.yml file:
version: '3.4'
services:
ai.emitterjob:
image: ${DOCKER_REGISTRY}ai_emitter
build:
context: .
dockerfile: ../AI.EmitterJob/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_HTTPS_PORT=44331
ports:
- "52649:80"
- "44331:443"
volumes:
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
Note - I know I dont need to expose ports or use volumes here (or set env vars) for the console app, but I wanted to keep changes from the web docker file that works, to a minimum.
Just in case anyone else wants to try this, I finally got it working!
When I copied over the docker file, the only line I changed was from this:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
To this:
FROM microsoft/dotnet:2.1.2-runtime-alpine3.7 AS base
Because I'd used that alpine build before as a base image. Reverting back to the aspnetcore base image made this work fine.
Obviously, this isn't ideal for proper deployments and I need to find a sufficient replacement for the aspnetcore base image that will have the dotnetcore runtime installed.
I'm happy I can debug my console app through docker now! :-D

Resources