Golang docker file for debug - docker

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.

Related

Dockerfile cannot run a container using "docker-compose-up --build" command

Dockerfile cannot run a container using "docker-compose-up --build" command
When I run Dockerfile using the "docker-compose up --build" command, the file not found is output, and the container is not running.
Dockerfile, docker-compose.yaml, directory and result is below.
Docker version :
\server>docker --version
Docker version 20.10.14, build a224086
Dockerfile :
FROM openjdk:14-jdk-alpine3.10
RUN mkdir -p /app/workspace/config && \
mkdir -p /app/workspace/lib && \
mkdir -p /app/workspace/bin
WORKDIR /app/workspace
VOLUME /app/workspace
COPY ./bin ./bin
COPY ./config ./config
COPY ./lib ./lib
RUN chmod 774 /app/workspace/bin/*.sh
EXPOSE 6969
WORKDIR /app/workspace/bin
ENTRYPOINT ./startServer.sh
docker-compose.yaml:
version: '3'
services:
server:
container_name: cn-server
build:
context: ./server/
dockerfile: Dockerfile
ports:
- "6969:6969"
volumes:
- ${SERVER_HOST_DIR}:/app/workspace
networks:
- backend
networks:
backend:
driver: bridge
directories :
enter image description here
"docker-compose up --build" command execution result :
Building server
[+] Building 3.7s (13/13) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 425B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:14-jdk-alpine3.10 2.0s
=> [internal] load build context 0.0s
=> => transferring context: 239B 0.0s
=> CACHED [1/8] FROM docker.io/library/openjdk:14-jdk-alpine3.10#sha256:b8082268ef46d44ec70fd5a64c71d445492941813ba9d68049be6e63a0da542f 0.0s
=> [2/8] RUN mkdir -p /app/workspace/config && mkdir -p /app/workspace/lib && mkdir -p /app/workspace/bin 0.4s
=> [3/8] WORKDIR /app/workspace 0.1s
=> [4/8] COPY ./bin ./bin 0.1s
=> [5/8] COPY ./config ./config 0.1s
=> [6/8] COPY ./lib ./lib 0.1s
=> [7/8] RUN chmod 774 /app/workspace/bin/*.sh 0.5s
=> [8/8] WORKDIR /app/workspace/bin 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:984554c9d7d9b3312fbe2dc76b4c7381e93cebca3a808ca16bd9e3777d42f919 0.0s
=> => naming to docker.io/library/docker_cn-server 0.0s
Creating cn-server ... done
Attaching to cn-server
cn-server | /bin/sh: ./startServer.sh: not found
cn-server exited with code 127
Also bin, config, lib directories are not created in host volume directory and no files.
Please tell me what I was wrong or what I used wrong.
Thank you.
There are two obvious problems here, both related to Docker volumes.
In your Dockerfile, you switch to WORKDIR /app/workspace and do some work there, but then in the Compose setup, you bind-mount a host directory over all of /app/workspace. This causes all of the work in the Dockerfile to be lost, and replaces the code in the image with unpredictable content from the host. In the docker-compose.yml file you should delete the volumes: block. You should be able to reduce what you've shown to as little as
version: '3.8'
services:
server:
build: ./server
ports:
- '6969:6969'
The second problem is in the Dockerfile itself. You declare VOLUME /app/workspace fairly early on. This is unnecessary, though, and its most visible effect is to cause later RUN commands in that directory to have no effect. So in particular your RUN chmod ... command isn't happening. Deleting the VOLUME line can help with that. (You also don't need to RUN mkdir directories you're about to COPY into the image.)
FROM openjdk:14-jdk-alpine3.10
WORKDIR /app/workspace
COPY ./bin ./bin
COPY ./config ./config
COPY ./lib ./lib
RUN chmod 0755 bin/*.sh
EXPOSE 6969
WORKDIR /app/workspace/bin
CMD ["./startServer.sh"]
There are other potential problems depending on the content of the startServer.sh file. I'd expect this to be a shell script and its first line to be a "shebang" line, #!/bin/sh. If it explicitly names GNU Bash or another shell, that won't be present in an Alpine-based image. If you're working on a Windows-based system and the file has DOS line endings, that will also cause an error.

Docker build for vue project module not found error

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

Yarn build using rollup hangs in docker build process

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

ERROR [build 6/6] RUN dotnet publish "" -c Release -o /app/publish

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.

Docker build from parent directory is giving error - package is not in GOROOT

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"]

Resources