I'm building an image for Web API .Net 5
My folder directory looks like this
D:\Working\Phong_Nguyen_Super_Hero\Weather Forecast Application\WeatherForecast-main\TLY.WeatherForecast
|- TLY.WeatherForecast.sln
|- Dockerfile
|- .dockerignore
|- TLY.WeatherForecast
And my Dockerfile content looks like this
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
ENV ASPNETCORE_URLS=http://+:80
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["TLY.WeatherForecast/TLY.WeatherForecast.csproj", "TLY.WeatherForecast/"]
RUN dotnet restore "TLY.WeatherForecast/TLY.WeatherForecast.csproj"
COPY . .
RUN dotnet publish "TLY.WeatherForecast.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "TLY.WeatherForecast.dll"]
And when I run this command
docker build -t phongnguyen94/weatherforecast_api:latest .
I got errors below
> [+] Building 110.7s (14/15) => [internal] load build definition from
> Dockerfile
=> transferring dockerfile: 569B
=> [internal] load .dockerignore
=> transferring context: 388B
=> [internal] load metadata for mcr.microsoft.com/dotnet/sdk:5.0
=> [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:5.0
=> [internal] load build context
=> transferring context: 4.46MB
=> [base 1/2] FROM mcr.microsoft.com/dotnet/aspnet:5.0#sha256:c0cc95b0d87a31401763f8c7b2a25aa106e7b45bfcaa2f302dc9d0ff5ab93fa2
=> => resolve mcr.microsoft.com/dotnet/aspnet:5.0#sha256:c0cc95b0d87a31401763f8c7b2a25aa106e7b45bfcaa2f302dc9d0ff5ab93fa2
=> extracting sha256:1396b16d0d87d441988017c78df3fe711ae12f60cce661c2a9a004bdce6f4ee3
=> [build 1/6] FROM mcr.microsoft.com/dotnet/sdk:5.0#sha256:85ea9832ae26c70618418cf7c699186776ad066d88770fd6fd1edea9b260379a
=> resolve mcr.microsoft.com/dotnet/sdk:5.0#sha256:85ea9832ae26c70618418cf7c699186776ad066d88770fd6fd1edea9b260379a
=> extracting sha256:9887694812e570c8e6fab2fbffd327127283e4360cce25677d9ee7a7c309162d
=> [base 2/2] WORKDIR /app
=> [final 1/2] WORKDIR /app
=> [build 2/6] WORKDIR /src
=> [build 3/6] COPY [TLY.WeatherForecast/TLY.WeatherForecast.csproj, TLY.WeatherForecast/]
=> [build 4/6] RUN dotnet restore "TLY.WeatherForecast/TLY.WeatherForecast.csproj"
=> [build 5/6] COPY . .
=> ERROR [build 6/6] RUN dotnet publish "TLY.WeatherForecast.csproj" -c Release -o /app/publish
------
> [build 6/6] RUN dotnet publish "TLY.WeatherForecast.csproj" -c Release -o /app/publish:
#14 0.578 Microsoft (R) Build Engine version 16.9.0+57a23d249 for .NET
#14 0.578 Copyright (C) Microsoft Corporation. All rights reserved.
#14 0.578
#14 0.579 MSBUILD : error MSB1009: Project file does not exist.
#14 0.579 Switch: TLY.WeatherForecast.csproj
I've changed the Dockerfile content this line then it works fine
From
RUN dotnet publish "TLY.WeatherForecast.csproj" -c Release -o /app/publish
To
RUN dotnet publish "TLY.WeatherForecast/TLY.WeatherForecast.csproj" -c Release -o /app/publish
Because I've placed the Dockerfile file outside the project. So I need to redirect into TLY.WeatherForecast folder.
Related
I have two ContainerApps in the same solution, both build and run locally in Docker desktop, and 1 of them publishes to an Azure ContainerApp properly. The other one appears identical structurally and w.r.t. dockerfile/projectFile but fails to publish with the "failed to compute cache key" project copy error
Windows 11
VisualStudio 17.3.4
Docker Desktop 4.12.0 / WSL2
\SolutionDir
\FR911.Worker.Project1
Dockerfile
FR911.Worker.Project1.csproj
\FR911.Worker.Project2
Dockerfile
FR911.Worker.Project2.csproj
Dockerfile for Project1 (publishes correctly)
#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:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["FR911.Worker.Project1/FR911.Worker.Project1.csproj", "FR911.Worker.Project1/"]
RUN dotnet restore "FR911.Worker.Project1/FR911.Worker.Project1.csproj"
COPY . .
WORKDIR "/src/FR911.Worker.Project1"
RUN dotnet build "FR911.Worker.Project1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "FR911.Worker.Project1.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FR911.Worker.Project1.dll"]
Dockerfile for Project2 (does not publish)
#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:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["FR911.Worker.Project2/FR911.Worker.Project2.csproj", "FR911.Worker.Project2/"]
RUN dotnet restore "FR911.Worker.Project2/FR911.Worker.Project2.csproj"
COPY . .
WORKDIR "/src/FR911.Worker.Project2"
RUN dotnet build "FR911.Worker.Project2.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "FR911.Worker.Project2.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FR911.Worker.Project2.dll"]
Log for Project1 Publish (publishes correctly)
FR911.Worker.Project1 -> G:\FR911Cloud\FR911.Worker.Project1\bin\Release\net6.0\FR911.Worker.Project1.dll
FR911.Worker.Project1 -> G:\FR911Cloud\FR911.Worker.Project1\obj\Docker\publish\
Docker version 20.10.17, build 100c701
docker build -f "G:\FR911Cloud\FR911.Worker.Project1\Dockerfile" --force-rm -t fr911workerProject1 --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=FR911.Worker.Project1" "G:\FR911Cloud"
#1 [internal] load build definition from Dockerfile
#1 sha256:f35cad84d8f344f22ff5c01ec0f2b5593a1e8e8106c5a291cbb81d75702e8f4b
#1 transferring dockerfile: 980B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:773696df5d1b3a2e3082d19ade268ad9cee78057bcc7d5bf617dbf42632a68c3
#2 transferring context: 35B 0.0s done
#2 DONE 0.0s
#4 [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:6.0
#4 sha256:ac4494cbca04ddb415c76edcbcc7688784c2a6ea65dd656286c013738aa3b75f
#4 DONE 0.0s
#3 [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0
#3 sha256:9eb4f6c3944cfcbfe18b9f1a753c769fc35341309a8d4a21f8937f47e94c712b
#3 DONE 0.3s
#8 [build 1/7] FROM mcr.microsoft.com/dotnet/sdk:6.0#sha256:a788c58ec0604889912697286ce7d6a28a12ec28d375250a7cd547b619f19b37
#8 sha256:fff7c57bbc14150de4574cecfd040bdf8a628dc4f5265c2e038bd3fd64bdd55a
#8 DONE 0.0s
#5 [base 1/2] FROM mcr.microsoft.com/dotnet/aspnet:6.0
#5 sha256:50f1ddc10932c4a74c7af5704e931a9489c710faea4f2381fe2380827a900e00
#5 DONE 0.0s
#10 [internal] load build context
#10 sha256:a7dbe6d5c5594ebe893dc072a634555501969a46c9ae9d648db74ea23d0ee810
#10 transferring context: 673.15kB 1.4s done
#10 DONE 1.4s
#9 [build 2/7] WORKDIR /src
#9 sha256:fd721b9ab8612450c39dfab43831d16b893f71b294b4d92a8c1d6fdaf0c47a22
#9 CACHED
#11 [build 3/7] COPY [FR911.Worker.Project1/FR911.Worker.Project1.csproj, FR911.Worker.Project1/]
#11 sha256:91f73142833c22e9b36d6dfb095a3421596ba684c3076da61c19a7d7aae5f1bc
#11 CACHED
... continues until success
Log for Project2 Publish (fails)
FR911.Worker.Project2 -> G:\FR911Cloud\FR911.Worker.Project2\bin\Release\net6.0\FR911.Worker.Project2.dll
FR911.Worker.Project2 -> G:\FR911Cloud\FR911.Worker.Project2\obj\Docker\publish\
Docker version 20.10.17, build 100c701
docker build -f "G:\FR911Cloud\FR911.Worker.Project2\Dockerfile" --force-rm -t fr911workerProject2 --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=FR911.Worker.Project2" "G:\FR911Cloud"
#1 [internal] load build definition from Dockerfile
#1 sha256:69dc10bf751883ff6fa38a281a2a6e3570552aeded8c5f82fc34e54ad9c820c0
#1 transferring dockerfile: 32B done
#1 DONE 0.0s
#2 [internal] load .dockerignore
#2 sha256:5089ff4c45602d16118aed124a38ee56bbe29b79f636b726f36a16f813470f64
#2 transferring context: 35B 0.0s done
#2 DONE 0.0s
#4 [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:6.0
#4 sha256:ac4494cbca04ddb415c76edcbcc7688784c2a6ea65dd656286c013738aa3b75f
#4 DONE 0.0s
#3 [internal] load metadata for mcr.microsoft.com/dotnet/sdk:6.0
#3 sha256:9eb4f6c3944cfcbfe18b9f1a753c769fc35341309a8d4a21f8937f47e94c712b
#3 DONE 0.3s
#8 [build 1/7] FROM mcr.microsoft.com/dotnet/sdk:6.0#sha256:a788c58ec0604889912697286ce7d6a28a12ec28d375250a7cd547b619f19b37
#8 sha256:fff7c57bbc14150de4574cecfd040bdf8a628dc4f5265c2e038bd3fd64bdd55a
#8 DONE 0.0s
#9 [build 2/7] WORKDIR /src
#9 sha256:fd721b9ab8612450c39dfab43831d16b893f71b294b4d92a8c1d6fdaf0c47a22
#9 CACHED
#5 [base 1/2] FROM mcr.microsoft.com/dotnet/aspnet:6.0
#5 sha256:50f1ddc10932c4a74c7af5704e931a9489c710faea4f2381fe2380827a900e00
#5 DONE 0.0s
#10 [internal] load build context
#10 sha256:193c5f727995c82adbaa58aed42c8a05308b1cbab22f31bea74fad6ffe5c2e83
#10 transferring context: 673.11kB 1.4s done
#10 DONE 1.4s
#11 [build 3/7] COPY [FR911.Worker.Project2/FR911.Worker.Project2.csproj, FR911.Worker.Project2/]
#11 sha256:687c29b5b257b0efc68aa34321eca5a6576a579c63371f320e619daa0c9c705c
#11 ERROR: "/FR911.Worker.Project2/FR911.Worker.Project2.csproj" not found: not found
------
> [build 3/7] COPY [FR911.Worker.Project2/FR911.Worker.Project2.csproj, FR911.Worker.Project2/]:
------
failed to compute cache key: "/FR911.Worker.Project2/FR911.Worker.Project2.csproj" not found: not found
The publish profiles are also identical except for the container & environment names, and the project files both target net6.0 and Linux. The Docker command that VisualStudio runs to build each also seems identical(except for the path & name):
docker build -f "G:\FR911Cloud\FR911.Worker.Project2\Dockerfile" --force-rm -t fr911workerProject2 --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=FR911.Worker.Project2" "G:\FR911Cloud"
I'm having trouble finding out why one works and the other fails - presumably because it cannot find the project at step 3 of the build from the dockerfile COPY ["FR911.Worker.Project2/FR911.Worker.Project2.csproj", "FR911.Worker.Project2/"]
It was a casing issue in the Dockerfile on the project file name.
COPY ["FR911.Worker.Project2/FR911.Worker.Project2.csproj", "FR911.Worker.Project2/"]
is not the same as
COPY ["FR911.Worker.Project2/FR911.Worker.project2.csproj", "FR911.Worker.Project2/"]
I am trying to build a vue app docker image but I keep getting this error
Module not found: Error: Can't resolve './src/main.js' in '/app'
I am using the a multi-stage dockerfile
FROM node:15.4 as build
WORKDIR /app
COPY ./frontend/package.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.19
COPY ./frontend/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
Here's the script section of the package.json file
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
This is a detailed log of the build process
[+] Building 26.9s (14/16)
=> [internal] load build definition from frontend.dockerfile 0.0s
=> => transferring dockerfile: 293B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for docker.io/library/nginx:1.19 2.5s
=> [internal] load metadata for docker.io/library/node:15.4 2.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [auth] library/nginx:pull token for registry-1.docker.io 0.0s
=> [build 1/6] FROM docker.io/library/node:15.4#sha256:a76eb778d162f8fd96138d9ca7dbd14b8916c201775a97d2f2aa22e9f13eb105 0.0s
=> [stage-1 1/3] FROM docker.io/library/nginx:1.19#sha256:df13abe416e37eb3db4722840dd479b00ba193ac6606e7902331dcea50f4f1f2 0.0s
=> [internal] load build context 8.5s
=> => transferring context: 166.03MB 8.4s
=> CACHED [build 2/6] WORKDIR /app 0.0s
=> CACHED [build 3/6] COPY ./frontend/package.json . 0.0s
=> CACHED [build 4/6] RUN npm install 0.0s
=> [build 5/6] COPY . . 7.4s
=> ERROR [build 6/6] RUN npm run build 8.3s
------
> [build 6/6] RUN npm run build:
#14 2.913
#14 2.913 > frontend#0.1.0 build
#14 2.913 > vue-cli-service build
#14 2.913
#14 4.668 All browser targets in the browserslist configuration have supported ES module.
I move the frontend folder from the project to stand alone and I am able to build the image and run a container based on it successfully.
What could possibly be wrong here?
I try to give you some help. First of all I assume your nginx.conf file is located in the upper nginx folder. I see two in your repo. If this is the case you are copying one layer to deep. I suggest to change your file as follows with this order:
FROM node:alpine as build
WORKDIR /app
COPY ./package*.json ./
RUN npm install
COPY "frontend/target/dist" ./
FROM nginx:alpine as production
COPY ./frontend/nginx/nginx.conf /etc/nginx/conf.d/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build /app /usr/share/nginx/html
What I changed was the layer of the folders you are trying to add and the asterix (*) in package.json. If you are defining a frontend before, you are also searching it in the copied part, which is not existing in the nginx image. Also as you see you only need /app instead of /app/dist. Additional your /etc... config path was wrongly referenced. Give it a shot now. It should work like this with the given information I had.
Add in your .dockerignore file only those lines:
node_modules
dist
I am trying to create a docker image for a svelte application. The svelte application I am using is just the svelte template with TypeScript initiated. I have made no changes to the application itself, my only goal is to serve the svelte application using Docker. I am using yarn berry (v2) as my package manager and rollupjs for the build process. This is my first question so please let me know if something is missing.
I am expecting the image to be built, but when the build process reaches the "yarn build" command, it never completes. It doesn't crash either, but it never completes the build step either. It seems to hang at the bundling step:
=> => # src/main.ts → public/build/bundle.js...
The build command from package.json:
"build": "rollup -c"
My Dockerfile was initially taken from here: https://sveltesociety.dev/recipes/publishing-and-deploying/dockerize-a-svelte-app/. However, I had to make some changes to it for yarn v2 and I found the following stack thread: Using Yarn 2 (Berry) for packaging application in a Docker image. Adding some modifications form that question left me with the following Dockerfile:
WORKDIR /app
COPY package.json ./
RUN yarn set version berry
COPY .yarn ./.yarn
COPY yarn.lock .yarnrc.yml ./
RUN yarn plugin import workspace-tools
RUN yarn workspaces focus -A --production
COPY . ./
RUN yarn build # This is where it gets stuck
FROM nginx:1.19-alpine
COPY --from=build /app/public /usr/share/nginx/html
I run the command docker build -t svelte-image . to build and this is the output I get:
[+] Building 572.6s (16/18)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 34B 0.0s
=> [internal] load metadata for docker.io/library/nginx:1.19-alpine 1.2s
=> [internal] load metadata for docker.io/library/node:12 1.1s
=> CACHED [stage-1 1/2] FROM docker.io/library/nginx:1.19-alpine#sha256:07ab71a2c8e4ecb19a5a5abcfb3a4f175946c001c8af288b1aa766d67b0 0.0s
=> CACHED [build 1/6] FROM docker.io/library/node:12#sha256:cc4adb82efc04b74b9f96326e682ad04be2df84d23e40609802eb6d6c207abde 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 69.58kB 0.0s
=> CACHED [stage-1 2/3] RUN rm /etc/nginx/nginx.conf /etc/nginx/conf.d/default.conf 0.0s
=> CACHED [build 2/10] WORKDIR /app 0.0s
=> CACHED [build 3/10] COPY package.json ./ 0.0s
=> CACHED [build 4/10] RUN yarn set version berry 0.0s
=> [build 5/10] COPY .yarn ./.yarn 0.2s
=> [build 6/10] COPY yarn.lock .yarnrc.yml ./ 0.0s
=> [build 7/10] RUN yarn plugin import workspace-tools 1.5s
=> [build 8/10] RUN yarn workspaces focus -A --production 0.5s
=> [build 9/10] COPY . ./ 0.1s
=> [build 10/10] RUN yarn build 568.9s
=> => # src/main.ts → public/build/bundle.js... # -> Never completes
I have been trying to figure out why the build hangs, but I am unable to find the source of error. It works just fine when building locally with yarn build. Does anyone have any clue as to why it hangs in the bundling process?
I did not figure out what was wrong, but I managed to build the docker image and run it successfully. Here is the working Dockerfile:
FROM node:16 AS build
WORKDIR /app
COPY package.json ./
RUN yarn set version berry
COPY .yarn ./.yarn #
COPY yarn.lock .yarnrc.yml ./
RUN yarn install
# These two lines are from the original example. It did not work to use this,
# but I leave it here to highlight the difference
## RUN yarn plugin import workspace-tools
## RUN yarn workspaces focus -A --production
COPY . ./
RUN yarn build
FROM nginx:1.19-alpine
COPY --from=build /app/public /usr/share/nginx/html
I am trying to create a docker image for this sample project structure of it as follows
two modules - common and go-modules
Following is my Docker file
FROM golang as builder
ENV GO111MODULE=on
WORKDIR /go-modules-docker
COPY . .
COPY ./go-modules/go.mod .
COPY ./go-modules/go.sum .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o app ./go-modules/main.go
FROM alpine:3.8
WORKDIR /root/
COPY --from=builder /go-modules/app .
CMD ["./app"]
go.mod file is as follows
module go-modules
go 1.15
replace common => /go-modules-docker/common
require (
common v0.0.0-00010101000000-000000000000
github.com/julienschmidt/httprouter v1.3.0
)
Main.go is as follows
package main
import (
"fmt"
"log"
"net/http"
"go-modules/greet" // go-modules is our project namespace
"common/deps"
"github.com/julienschmidt/httprouter"
)
func main() {
r := httprouter.New()
r.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprintf(w, "hello world, v%v %v", greet.Version, deps.Version2)
})
log.Println("listening to port *:8080. press ctrl + c to cancel.")
log.Fatal(http.ListenAndServe(":8080", r))
}
When running this command from parent directory - go-modules-docker
docker build -t go-mod-docker -f go-modules/Dockerfile .
I am getting the following error
[+] Building 2.2s (13/15)
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.8 0.8s
=> [internal] load metadata for docker.io/library/golang:latest 0.8s
=> [internal] load build context 0.0s
=> => transferring context: 618B 0.0s
=> [builder 1/7] FROM docker.io/library/golang#sha256:cf46c759511d0376c706a923f2800762948d4ea1a9290360720d5124a730ed63 0.0s
=> [stage-1 1/3] FROM docker.io/library/alpine:3.8#sha256:2bb501e6173d9d006e56de5bce2720eb06396803300fe1687b58a7ff32bf4c14 0.0s
=> CACHED [builder 2/7] WORKDIR /go-modules-docker 0.0s
=> [builder 3/7] COPY . . 0.0s
=> [builder 4/7] COPY ./go-modules/go.mod . 0.0s
=> [builder 5/7] COPY ./go-modules/go.sum . 0.0s
=> [builder 6/7] RUN go mod download 0.8s
=> ERROR [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux go build -o app ./go-modules/main.go 0.5s
------
> [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux go build -o app ./go-modules/main.go:
#14 0.434 go-modules/main.go:8:2: package go-modules/greet is not in GOROOT (/usr/local/go/src/go-modules/greet)
------
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c CGO_ENABLED=0 GOOS=linux go build -o app ./go-modules/main.go]: runc did not terminate sucessfully
Can anyone suggest what can be done and how to solve this problem?
Issue was solved by updating the WORKDIR again the Dockerfile to the go-modules (Basically doing a CD - change directory) and building the whole module
Changing docker file to this fixed the issue
FROM golang as builder
ENV GO111MODULE=on
WORKDIR /go-modules-docker
COPY . .
WORKDIR /go-modules-docker/go-modules
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o /go-modules-docker/app
FROM alpine:3.8
WORKDIR /root/
COPY --from=builder /go-modules-docker/app .
CMD ["./app"]
I've the following docker file which is working for my application. I was able to access to the simple web app server.
FROM golang:1.14.7 AS builder
RUN go get github.com/go-delve/delve/cmd/dlv
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN CGO_ENABLED=0 GOOS=linux go build -gcflags="all=-N -l" -o main ./...
FROM alpine:3.12.0 AS production
COPY --from=builder /app .
EXPOSE 8000 40000
ENV PORT=8000
CMD ["./main"]
When I adopt it like following, I am not able to deploy it successfully to Kubernetes. The container crashed with some general error, not something that I can use.
standard_init_linux.go:190: exec user process caused "no such file or directory"
This not working
FROM golang:1.14.7 AS builder
RUN go get github.com/go-delve/delve/cmd/dlv
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN CGO_ENABLED=0 GOOS=linux go build -gcflags="all=-N -l" -o main ./...
FROM alpine:3.12.0 AS production
COPY --from=builder /app .
COPY --from=builder /go/bin/dlv /
EXPOSE 8000 40000
ENV PORT=8000
CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "./main"]
If someone want to try it out this is the simple program (this is minimum reproducible example), if you take the first docker file it will work for you, for the second it does not.
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
fmt.Println("app is starting!")
var port string
if port = os.Getenv("PORT"); len(port) == 0 {
port = "8080"
}
http.HandleFunc("/", handler)
http.ListenAndServe(":"+port, nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:])
}
You need to compile dlv itself with the static linking flags. Without that, dlv will have dynamic links to libc which doesn't exist within an alpine image. Other options include switching your production image to be debian based (FROM debian) or change to golang image to be alpine based (FROM golang:1.14.7-alpine). To compile dlv without dynamic links, the following Dockerfile works:
FROM golang:1.14.7 AS builder
RUN CGO_ENABLED=0 go get -ldflags '-s -w -extldflags -static' github.com/go-delve/delve/cmd/dlv
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN CGO_ENABLED=0 GOOS=linux go build -gcflags="all=-N -l" -o main ./...
FROM alpine:3.12.0 AS production
COPY --from=builder /app .
COPY --from=builder /go/bin/dlv /
EXPOSE 8000 40000
ENV PORT=8000
CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "./main"]
To see the dynamic links, build your builder image and run ldd against the output binaries:
$ docker build --target builder -t test-63403272 .
[+] Building 4.6s (11/11) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 570B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.14.7 0.2s
=> [builder 1/6] FROM docker.io/library/golang:1.14.7#sha256:1364cfbbcd1a5f38bdf8c814f02ebbd2170c93933415480480104834341f283e 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 591B 0.0s
=> CACHED [builder 2/6] RUN go get github.com/go-delve/delve/cmd/dlv 0.0s
=> CACHED [builder 3/6] RUN mkdir /app 0.0s
=> [builder 4/6] ADD . /app 0.1s
=> [builder 5/6] WORKDIR /app 0.0s
=> [builder 6/6] RUN CGO_ENABLED=0 GOOS=linux go build -gcflags="all=-N -l" -o main ./... 4.0s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:d2ca7bbc0bb6659d0623e1b8a3e1e87819d02d0c7f0a0762cffa02601799c35e 0.0s
=> => naming to docker.io/library/test-63403272 0.0s
$ docker run -it --rm test-63403272 ldd /go/bin/dlv
linux-vdso.so.1 (0x00007ffda66ee000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007faa4824d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007faa4808c000)
/lib64/ld-linux-x86-64.so.2 (0x00007faa48274000)
Libc is a common missing library when switching to alpine since it uses musl by default.