dotnet / tye

Tye is a tool that makes developing, testing, and deploying microservices and distributed applications easier. Project Tye includes a local orchestrator to make developing microservices easier and the ability to deploy microservices to Kubernetes with minimal configuration.
MIT License
5.28k stars 520 forks source link

Tye cant find *.csproj on tye build|push|deploy when using custom Dockerimages #1264

Open mercedesyenzzz opened 2 years ago

mercedesyenzzz commented 2 years ago

I came across Tye yesterday and first of all I have to say that I really like it. :thumbsup: :clap:

However, I can't currently publish anything if I'm already using Docker images in my projects. I want Tye to use my Dockerfiles, which it does. The Dockerfiles themselves work, it's just that Tye can't execute some copy commands when creating them. Would it be possible that the internal .dockerignore ignores my .csproj files?

Here is my Dockerfile:

FROM nginx:alpine AS base
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Client.csproj","ClientApp/"]
RUN dotnet restore "ClientApp/Client.csproj" 
COPY . .
RUN dotnet build "Client.csproj"  -c Release -o /app/build

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

FROM base AS final
WORKDIR /usr/share/nginx/html
COPY --from=publish /app/publish/wwwroot .
COPY ["wwwroot/nginx.conf","/etc/nginx/nginx.conf"]

My tye.yaml has nothing special and looks like this:

name: client
services:
- name: client
  project: Client.csproj

The output from tye build -v Debug:

Loading Application Details...
Restoring and evaluating projects
Resolved metadata for service client at /mnt/c/Users/me/source/repos/Client/obj/Debug/net6.0/MicrosoftTye.ProjectMetadata.txt
Restore and project evaluation took: 1524.1305ms
Found application version: 1.0.0
RunCommand=dotnet
RunArguments="/home/administrator/.nuget/packages/microsoft.aspnetcore.components.webassembly.devserver/6.0.1/build/../tools/blazor-devserver.dll" --applicationpath "/mnt/c/Users/me/source/repos/Client/bin/Debug/net6.0/Client.dll"
TargetPath=/mnt/c/Users/me/source/repos/Client/bin/Debug/net6.0/Client.dll
PublishDir=bin/Debug/net6.0/browser-wasm/publish/
AssemblyName=Client
IntermediateOutputPath=obj/Debug/net6.0/
Found target framework: net6.0
Parsed target framework name: net
Parsed target framework version: 6.0
Found shared frameworks: Microsoft.NETCore.App
IsAspNet=False
Evaluation Took: 9.9366ms
Processing Service 'client'...
    Applying container defaults...
    Done Applying container defaults...
    Compiling Services...
    Done Compiling Services...
    Publishing Project...
        Running 'dotnet publish'.
        > dotnet publish "/mnt/c/Users/me/source/repos/Client/Client.csproj" -c Release -o "/tmp/d0widrdx.kuc"
        Done running 'dotnet publish' exit code: 0
        Created Publish Output: '/tmp/d0widrdx.kuc'
    Done Publishing Project...
    Building Docker Image...
        Using existing Dockerfile '/mnt/c/Users/me/source/repos/Client/Dockerfile'.
        Running 'docker build'.
        > docker build "/tmp/d0widrdx.kuc" -t client:1.0.0 -f "/tmp/d0widrdx.kuc/Dockerfile"
            #1 [internal] load build definition from Dockerfile
            #1 sha256:9b6f74df23f5e806672e8a1420c9216a219684590aea6204d2806ebbb6fef2be
            #1 transferring dockerfile: 539B done
            #1 DONE 0.0s

            #2 [internal] load .dockerignore
            #2 sha256:61fa7acfc863fbfbbb12777b157ea03fd01abf7d803d1ec36d05827e95ff3a8f
            #2 transferring context: 2B done
            #2 DONE 0.0s

            #4 [internal] load metadata for docker.io/library/nginx:alpine
            #4 sha256:b001d263a254f0e4960d52c837d5764774ef80ad3878c61304052afb6e0e9af2
            #4 ...

            #3 [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0
            #3 sha256:9eb4f6c3944cfcbfe18b9f1a753c769fc35341309a8d4a21f8937f47e94c712b
            #3 DONE 0.0s

            #4 [internal] load metadata for docker.io/library/nginx:alpine
            #4 sha256:b001d263a254f0e4960d52c837d5764774ef80ad3878c61304052afb6e0e9af2
            #4 DONE 6.3s

            #5 [base 1/1] FROM docker.io/library/nginx:alpine@sha256:eb05700fe7baa6890b74278e39b66b2ed1326831f9ec3ed4bdc6361a4ac2f333
            #5 sha256:aafadb73b65a89c3f6e3b20b806cb50252525cc4a32f8b6adee5d8514d661c14
            #5 DONE 0.0s

            #7 [build 1/6] FROM mcr.microsoft.com/dotnet/sdk:6.0
            #7 sha256:7ecb41e81f15ad01ec9dfe74e314966dca2b7e75c8209ba0f5971e2896aeacb1
            #7 DONE 0.0s

            #8 [build 2/6] WORKDIR /src
            #8 sha256:5ab03db9c756d494d26f6f951935e98641cd0ac874530e7c026c9e03c0da1894
            #8 CACHED

            #9 [internal] load build context
            #9 sha256:3b050e0756165a296dab472ea84724e71c07fb2d3dbd944b0cf6851e9892b96c
            #9 transferring context: 16.57MB 0.1s done
            #9 DONE 0.1s

            #10 [build 3/6] COPY [Client.csproj,ClientApp/]
            #10 sha256:01e444170df97756e8dc281d91e15f6e0b7f9b126a68561aef923acc812704b9
            #10 ERROR: "/Client.csproj" not found: not found
            ------
             > [build 3/6] COPY [Client.csproj,ClientApp/]:
            ------
            failed to compute cache key: "/Client.csproj" not found: not found
        Done running 'docker build' exit code: 1
Drats! 'build' failed:
        'docker build' failed.

I tried this with version 0.10.0-alpha.21420.1+7cec0655cc474aee8d3c3a3d180678985209d439 & 0.11.0-alpha.22057.1+388bd9bbe56ad83b6eeb5104a91ec7eab6af400f.

My guess is that an entry in the internal .dockerignore prevents this copy operation. I did not specify a .dockerignore, but still one is loaded(as you can see in the logs...). Would there be any way for me to change the internal .dockerignore or has anyone encountered this bug already?

Any kind of help is very much appreciated :pray:

philliphoff commented 2 years ago

@mercedesyenzzz If you have existing Dockerfile files for your projects, I would suggest explicitly pointing Tye to those via the tye.yaml, as well as explicitly setting their Dockerfile contexts. It may be that your existing Dockerfile files assume a different context than what Tye sets by default.

If that doesn't work, then perhaps you can strip down your workspace into a minimal repro in order to do some investigation?

mercedesyenzzz commented 2 years ago

According to the documentation, setting a Dockerfile is only supported for tye run. However, this does not seem to work for me. For example, when I run tye run --docker, tye doesn't seem to use my own Docker image, even if I specify it and the context in tye.yaml.

In this repository I created there is an AspNetWebApp with a standard Docker image from Microsoft and a standalone Blazorwasm app with a custom Docker image. docker-compose up works as expected. tye run works as expected too and already gives me a benefit (--watch & --debug options are very nice). If there are any further questions please let me know.

mercedesyenzzz commented 2 years ago

I thought the repository I created for this issue was sufficient for further investigation, but here are the steps to reproduce the issue:

dotnet new webapp -n WebApp
cd WebApp
cat > Dockerfile <<EOL
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 WebApp.csproj ./
RUN dotnet restore "WebApp.csproj"
COPY . .
RUN dotnet build "WebApp.csproj" -c Release -o /app/build

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

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

To prove that the Dockerimage is working as expected:

docker build -t webapp .
tye init

or with dockerFile and dockerFileContext properties (doesn't make any difference for me):

cat > tye.yaml <<EOL
name: webapp
services:
- name: webapp
  project: WebApp.csproj
  dockerFile: Dockerfile
  dockerFileContext: .
EOL

I am using Windows 10 (Version 1909 (OS Build 18363.1916), Docker Desktop 4.3.2 (72729) and Docker Engine v20.10.11. I tried this from Windows 10 directly and WSL2 (Ubuntu 20.04) with Tye version 0.10.0-alpha.21420.1+7cec0655cc474aee8d3c3a3d180678985209d439 & 0.11.0-alpha.22057.1+388bd9bbe56ad83b6eeb5104a91ec7eab6af400f.

tye run works like expected but tye run --docker does not seem to use my Dockerimage. All other commands (tye build, tye push, tye deploy) give me the error failed to compute cache key: "/WebApp.csproj" not found: not found i mentioned earlier.

Would be great if someone could take a look at this and tell me if the issue can be reproduced or not, because I would really like to use the deploy functionality of tye.

fntawiniga commented 2 years ago

I had the same issue with failed to compute cache key: ... .csproj not found and I removed all the Dockerfile and everything was successfully built. You may try to remove all the Dockerfile generated from Visual Studio as a workaround

mercedesyenzzz commented 2 years ago

@fntawiniga this workaround is known to me, but unfortunately it does not work for Blazor Web Assembly Standalone. But good to know that I am not the only one who has this issue!

philliphoff commented 2 years ago

It looks like tye build publishes the project locally, and then copies the contents of the publish output into the Docker image. The Dockerfile context, therefore, is fixed to the publish output directory. (That's why the .csproj file is not found; as it's not part of the context.) If you want to use a custom Dockerfile, it would need to be written with that assumption, which is a very different assumption from other Docker tooling which typically expects the publication to be done in the container, as part of the image creation.

mercedesyenzzz commented 2 years ago

Ahh okay that makes sense, thanks for the explanation. I think for me the effort is less to just manually build, push and deploy my images instead of customizing all my Dockerfiles to tye... Would be very cool if in the future an update will allow me to use custom docker images. 🤞🏾

philliphoff commented 2 years ago

Not being the original developer/maintainer, I can only speculate as to why build/deploy relies on a local publish when using a custom Dockerfile. I don't see why Tye couldn't just rely on a custom Dockerfile to generate a "complete" image, especially as that would allow the same Dockerfile to be used across run/build/deploy.

philliphoff commented 2 years ago

Note that this issue is related to (if not a duplicate of) #998.

271943794 commented 2 years ago

same issues. tye run --watch is success but tye deploy is failed