Dockerfile weird paths generated by Visual Studio - dockerfile

I'm using Jason Taylor's Clean Architecture template and I wonder why his WebUI Dockerfile is generated by Visual Studio just like below.
It sets WORKDIR to /src and then copies each project from /src/ProjectDir/Project.csproj. What's the point of WORKDIR in that case? Look at WORKDIR "/src/src/WebUI". Why /src/src? There is only one src directory.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
ENV ASPNETCORE_URLS=https://+:5001;http://+:5000
WORKDIR /app
EXPOSE 5000
EXPOSE 5001
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt install -y nodejs
WORKDIR /src
COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"]
COPY ["src/Application/Application.csproj", "src/Application/"]
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/WebUI/WebUI.csproj"
COPY . .
WORKDIR "/src/src/WebUI"
RUN dotnet build "WebUI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]

I suspect this is because WORKDIR /src will create a directory called /src AND change directories into it. After changing into it, it will copy files from the host's relative src folder and into another subdirectory called src (on the container). So the full absolute path becomes /src/src. You can confirm this by adding RUN pwd && ls before the WORKDIR and after the first COPY.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
ENV ASPNETCORE_URLS=https://+:5001;http://+:5000
WORKDIR /app
EXPOSE 5000
EXPOSE 5001
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt install -y nodejs
RUN pwd && ls /
WORKDIR /src
COPY ["src/WebUI/WebUI.csproj", "src/WebUI/"]
RUN pwd && ls
COPY ["src/Application/Application.csproj", "src/Application/"]
COPY ["src/Domain/Domain.csproj", "src/Domain/"]
COPY ["src/Infrastructure/Infrastructure.csproj", "src/Infrastructure/"]
RUN dotnet restore "src/WebUI/WebUI.csproj"
COPY . .
WORKDIR "/src/src/WebUI"
RUN dotnet build "WebUI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]

Related

Docker file build error while upgrading to .net core 6 in AWS lambda app

I am working on upgrading the existing containerized lambda application from .NET Core 5 to .NET Core 6. I am getting this error in the Azure pipeline (on run build script):
Step 13/14 : WORKDIR ${LAMBDA_TASK_ROOT} cannot normalize nothing.
The same code is working without any issue when targetting .NET Core 5.
.NET Core 5:
FROM public.ecr.aws/lambda/dotnet:5.0 AS base
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim as build
WORKDIR /workspace
COPY . /workspace
RUN ls
RUN dotnet build -c Release MyAPI.sln -o ./publish
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim as test
WORKDIR /workspace
COPY . /workspace
RUN ls
RUN dotnet test -c Release MyAPI.sln -o ./publish
FROM base as final
WORKDIR ${LAMBDA_TASK_ROOT}
COPY --from=build /workspace/publish
.NET Core 6:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS base
FROM base as build
WORKDIR /workspace
COPY . /workspace
RUN ls
RUN dotnet build -c Release MyAPI.sln -o ./publish
FROM base as test
WORKDIR /workspace
COPY . /workspace
RUN ls
RUN dotnet test -c Release MyAPI.sln -o ./publish
FROM base as final
WORKDIR ${LAMBDA_TASK_ROOT}
COPY --from=build /workspace/publish

Provide dependent file in a multi-stage build

I need to read in my application from a file "cert.pem" whose path is a) provided as an argument or b) it is retrieved from the directory of the main application file main.py.
I have created the following dockerfile, but after building and running my application using the image the "cert.pem" file cannot be accessed. Is there a way to read from this file?
FROM golang:1.17-alpine AS builder
RUN apk add --no-cache git
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o ./bin .
#final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/bin /app/bin
EXPOSE 3000
CMD ["/app/bin"]
The instruction to load the file is the following:
....
var (
cert_file = flag.String("cert", "./cert.pem", "File name of x509 certificate")
)
...
func main() {
...
_, err := ioutil.ReadFile(*cert_file)
...
you just have to copy your cert.pem file to the location of the binary in the final stage in docker. Assuming you have the cert file in your docker build context, you run a copy command.
FROM golang:1.17-alpine AS builder
RUN apk add --no-cache git
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o ./bin .
#final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/bin /app/bin
COPY cert.pem /app/
EXPOSE 3000
CMD ["/app/bin"]
Make sure you set the cert.pem location in your go program as ./cert.pem
The solution is to define an ENTRYPOINT instead CMD and add a WORKDIR instruction:
#build stage
FROM golang:1.17-alpine AS builder
RUN apk add --no-cache git
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o ./bin .
#final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/bin /app/bin
COPY --from=builder /app/cert.pem /app/cert.pem
EXPOSE 3000
WORKDIR /app
ENTRYPOINT ["/app/bin"]

Apache Druid Nano Container Service Error

I want to spin up a low configuration containerized service for which I created a Dockerfile as below:
docker build -t apache/druid_nano:0.20.2 -f Dockerfile .
FROM ubuntu:16.04
Install Java JDK 8
RUN apt-get update
&& apt-get install -y openjdk-8-jdk
RUN mkdir /app
WORKDIR /app
COPY apache-druid-0.20.2-bin.tar.gz /app
RUN tar xvzf apache-druid-0.20.2-bin.tar.gz
WORKDIR /app/apache-druid-0.20.2
EXPOSE <PORT_NUMBERS>
ENTRYPOINT ["/bin/start/start-nano-quickstart"]
When I start the container using the command "docker run -d -p 8888:8888 apache/druid_nano:0.20.2, I get an error as below:
/bin/start-nano-quickstart: no such file or directory
I removed the ENTRYPOINT command and built the image again just to check if the file exists in the bin directory inside the container. There is a file start-nano-quickstart under the bin directory inside the container.
Am I missing anything here? Please help.

Can we use RUN cd /app instead of using WORKDIR /app in dockerfile

I want to use RUN cd /app instead of WORKDIR /app in my dockerfile.
Is there any way to do this?
Yes, you can mkdir /app and then cd /app. WORKDIR is used to specify the directory whenever you exec bash to connect to container or the working directory when container start.

How to add c++ compiler to docker container?

I would like to create a dockerfile which will allow me to use gcc compiler into container. Currently I am using dockerfile generated by VS for my asp net core project.
My dockerfile:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 55712
EXPOSE 44396
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["Eunomia.API/Eunomia.API.csproj", "Eunomia.API/"]
COPY ["Eunomia.Insfrastrucutre/Eunomia.Infrastrucutre.csproj", "Eunomia.Insfrastrucutre/"]
COPY ["Eunomia.Core/Eunomia.Core.csproj", "Eunomia.Core/"]
RUN dotnet restore "Eunomia.API/Eunomia.API.csproj"
COPY . .
WORKDIR "/src/Eunomia.API"
RUN dotnet build "Eunomia.API.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "Eunomia.API.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Eunomia.API.dll"]
I was trying solution like this:
FROM gcc:4.9
COPY . /usr/src/compiler_cpp
WORKDIR /usr/src/compiler_cpp
RUN apt-get update && \
apt-get -y install gcc mono-mcs && \
rm -rf /var/lib/apt/lists/*
To add gcc, but that didn't help me still I couldn't reach gcc from container bash.
Why I need this?
I need this, becouse I am writing a dot net core web API which allow to check if code writed in c++ is correct by using unit tests.
In advice thanks for help :)