In FROM scratch, which user is executing the file? - docker

My goal is to build an image with FROM scratch and to know which user is executing the file, maybe with whoami, and to check the file permission, maybe with ls -l.
The problem are, FROM scratch don't have whoami or ls -l. Installing the busybox throws error as well.
The surprising thing is, that I still can do USER after FROM scratch. I just can't choose any user.
What I've did:
Create non-root user and do COPY --from=0 /etc/passwd /etc/passwd it to the next layer and do USER nonroot
Download busybox binary and do ENTRYPOINT ["/busybox"]
It throws error:
docker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/busybox": permission denied: unknown
Dockerfile
# syntax=docker/dockerfile:1
## Build
# Alpine is chosen for its small footprint
# compared to Ubuntu
FROM golang:1.19-alpine
WORKDIR /app
# Download necessary Go modules
COPY go.mod ./
# COPY go.sum ./
# RUN go mod download
COPY *.go ./
RUN go build -o /main
RUN adduser \
-h "/dev/null" \
-g "" \
-s "/sbin/nologin" \
-D \
-H \
-u 10001 \
playerone
## Deploy
FROM scratch
WORKDIR /
COPY --from=0 /main /main
COPY --from=0 /etc/passwd /etc/passwd
USER playerone
ENTRYPOINT [ "/main" ]
main.go
package main
import "log"
func main() {
log.Println("Hello World!")
}
go.mod
module github.com/kidfrom/learn-golang/docker-scratch
go 1.19

The example you provided runs for me.
$ docker run --rm test-go-scratch
2022/09/10 19:17:55 Hello World!
Changing FROM scratch to FROM busybox allows me to run:
$ docker run -it --rm --entrypoint /bin/sh test-go-busybox
/ $ id
uid=10001(playerone) gid=10001 groups=10001
showing that the container is configured to run as the requested user.
To see that is still happening in scratch, I changed to main.go to:
package main
import (
"log"
"os"
)
func main() {
uid := os.Getuid()
gid := os.Getgid()
log.Printf("Hello World! uid=%d, gid=%d", uid, gid)
}
And running that outputs the expected:
$ docker run --rm test-go-scratch
2022/09/10 19:23:42 Hello World! uid=10001, gid=10001

Related

create a symlink in an unprivileged container error

I'm running K8s deployment and trying to harden the security of one of my pod and because of that I started using the following docker image:
nginxinc/nginx-unprivileged:alpine
The problem is that I need to create a symlink and cannot get it done.
Here is the structure of my dockerfile
FROM nginxinc/nginx-unprivileged:alpine
ARG name
ARG ver
USER root
COPY ./outbox/${name}-${ver}.tgz ./
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./mime.types /etc/nginx/mime.types
COPY ./about.md ./
RUN mv /${name}-${ver}.tgz /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
RUN tar -zxf ${name}-${ver}.tgz \
&& mv ngdist/* . \
&& mv /about.md ./assets \
&& rm -fr ngdist web-ui-${ver}.tgz \
&& mkdir -p /tmp/reports
RUN chown -R 1001 /usr/share/nginx/html/
COPY ./entrypoint.sh.${name} /bin/entrypoint.sh
RUN chown 1001 /bin/entrypoint.sh
USER 1001
EXPOSE 8080
CMD [ "/bin/entrypoint.sh" ]
and here my entrypoint.sh
#!/bin/sh
ln -s /tmp/reports /usr/share/nginx/html/reports
and here is my container in the pod deployment yaml file
containers:
- name: web-ui
image: "myimage"
imagePullPolicy: Always
ports:
- containerPort: 8080
name: web-ui
volumeMounts:
- name: myvolume
mountPath: /tmp/reports
I tried to set the entrypoint under the root execution but that did not help either, the error i'm getting is this:
Error: failed to start container "web-ui": Error response from daemon:
OCI runtime create failed: container_linux.go:380: starting container
process caused: exec: "/bin/entrypoint.sh": permission denied: unknown
Like other Linux commands, a Docker container's main CMD can't run if the program it names isn't executable.
Most source-control systems will track whether or not a file is executable, and Docker COPY will preserve that permission bit. So the best way to address this is to make the scripts executable on the host:
chmod +x entrypoint.sh.*
git add entrypoint.sh.*
git commit -m 'make entrypoint scripts executable'
docker-compose build
docker-compose up -d
If that's not an option, you can fix this up in the Dockerfile too.
COPY ./entrypoint.sh.${name} /bin/entrypoint.sh
RUN chmod 0755 /bin/entrypoint.sh
Like other things in /bin, the script should usually be owned by root, executable by everyone, and writable only by its owner; you do not generally want the application to have the ability to overwrite its own code.

/bin/sh -c docker : not found returned a non-zero code: 127

The command /bin/sh -c docker login xxxx.live.dynatrace.com -u XXXX -p XXXXX returned a non-zero code: 127
I am also facing this error when i am trying to execute my default docker file.
The code is here as follows:
FROM node:10
WORKDIR /usr/src
RUN apt-get -y update
RUN docker login xxxx.live.dynatrace.com -u XXXX -p XXXXXX
COPY --from=sqx97905.live.dynatrace.com/linux/oneagent-codemodules:all / /
ENV LD_PRELOAD /opt/dynatrace/oneagent/agent/lib64/liboneagentproc.so
COPY . .
RUN npm install
EXPOSE 8080
CMD [ "node", "server.js" ]
i need to login so that i can copy the dynatrace agent so i had put the login command ahead of the COPY command. It works fine when i am logged into the terminal but i need to log into the dynatrace at run time then i am facing /bin/sh : 1 docker not found

Docker build "no such file or directory" error

RUN adduser -D appUser
RUN mkdir /usr/share/app
RUN mkdir /logs
ADD Function/target/foo.jar /usr/share/app
WORKDIR /usr/share/app
RUN chown -R appUser /usr/share/app
RUN chown -R appUser /logs
USER appUser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "foo.jar"]`
I've got this weird issue I can't seem to work my head around.
My root folder contains two directories, (both with subdirectories) 'Demo/Dockerfile' and 'Function/target/foo.jar'
I have a copy command in my Dockerfile that reads
COPY Function/target/foo.bar /usr/share/app
but when I run docker build -f Demo/Dockerfile from the root folder, I get an error
stat /var/lib/docker/tmp/docker-builder238823934/Function/target/foo.jar: no such file or directory
I find this a bit strange because when I edit the copy command to read COPY /target/foo.bar /usr/share/app and then I cd into the Function directory and run
docker build -f ../Demo/Dockerfile
it builds successfully, or if I edit the Dockerfile to read COPY foo.bar /usr/share/app and then cd into the target directory and run docker build -f ../../Demo/Dockerfile, this also works.
Is there an explanation for this sort of behavior?
This is what my dockerignore file looks like
!**/Dockerfile
!DockerServiceDescription/**
!Function/target/*.war
!server.xml
!tomcat-users.xml
Docker uses context directory and children only and does not allow using any files outside for security reasons.
You should show context directory to docker using '.' or so:
cd myproject
docker build -f Demo/Dockerfile .

kaniko docker build: can't find command

Newbie to kaniko, and try to build docker images in ubuntu docker host.
I have a local Dockerfile and main.go app
# Dockefile
FROM golang:1.10.3-alpine AS build
ADD . /src
RUN cd /src && go build -o app
FROM alpine
WORKDIR /app
COPY --from=build /src/app /app/
CMD [ "./app" ]
#main.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
And in command line, i run
docker run -it -v $(pwd):/usr \
gcr.io/kaniko-project/executor:latest \
--dockerfile=Dockerfile --context=/usr --no-push
Unfortunately, I got error like below
...
INFO[0006] Skipping paths under /proc, as it is a whitelisted directory
INFO[0006] Using files from context: [/usr]
INFO[0006] ADD . /src
INFO[0006] Taking snapshot of files...
INFO[0006] RUN cd /src && go build -o app
INFO[0006] cmd: /bin/sh
INFO[0006] args: [-c cd /src && go build -o app]
/bin/sh: go: not found
error building image: error building stage: waiting for process to exit: exit status 127
What's wrong? (docker version 18.09.0)
You need to use different path for context in kaniko. Your command to run this build should look like this:
docker run -it -v $(pwd):/context \
gcr.io/kaniko-project/executor:latest \
--dockerfile=Dockerfile --context=/context --no-push
In your command with /usr as context kaniko where overriding this path in all of Dockerfiles and in golang image, go is located in /usr path thats why it couldn't find it then
# which go
/usr/local/go/bin/go

Building clean Go application in Docker

I'm trying to create Go web server into small Docker images. Ideally the clean image contains only the Go application itself (and maybe supporting web components, but not the Go-building environment).
Here is my Dockerfile:
# golang:latest as build-env
FROM golang:latest AS build-env
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN cd /app && GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
# go build -o myapp
FROM scratch
COPY --from=build-env /app/myapp /app/images /
EXPOSE 8080
ENTRYPOINT /myapp
It uses the Docker Builder Pattern and scratch image, which is a special docker image that's empty.
It builds OK, but when I run it, I'm getting:
docker: Error response from daemon: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.
UPDATE:
So the ENTRYPOINT need to be changed to the exec form:
ENTRYPOINT ["/myapp"]
Having done that, I'm getting a new error:
standard_init_linux.go:207: exec user process caused "no such file or directory"
Having use a small footprint Linux image as the base (i.e. Alpine Linux) instead of scratch wouldn't help either:
$ docker run -it -p 8080:8080 go-web-docker-small
standard_init_linux.go:207: exec user process caused "no such file or directory"
$ docker run -it -p 8080:8080 go-web-docker-small /bin/sh -i
standard_init_linux.go:207: exec user process caused "no such file or directory"
How to fix it? Thx!
The last line of your Dockerfile is
ENTRYPOINT /myapp
There are two forms of the ENTRYPOINT (and CMD and RUN) instructions. An "exec form" looks like a JSON list, and provides an uninterpreted list of arguments to run as the main container process. A "shell form" does not look like a JSON list, and is implicitly wrapped in /bin/sh -c '...'.
Your ENTRYPOINT uses the shell form, and a FROM scratch image doesn't have a shell, producing the error you get. You can change this to the exec form
ENTRYPOINT ["/myapp"]
While building Dockerfile provided by you, I am getting following error:
COPY failed: stat /var/lib/docker/overlay2/cc1f8144192760ce7bf9cda7a7dfd0af16065901594c38609c813ea103cfd8d7/merged/app/images: no such file or directory
Fixed copy command and few others and image is building with following in Dockerfile
# golang:latest as build-env
FROM golang:latest AS build-env
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN cd /app && GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
# go build -o myapp
FROM scratch
COPY --from=build-env /app/myapp .
EXPOSE 8080
ENTRYPOINT ["./myapp"]

Resources