In FROM scratch, which user is executing the file?

Viewed 21

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:

  1. Create non-root user and do COPY --from=0 /etc/passwd /etc/passwd it to the next layer and do USER nonroot
  2. 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
1 Answers

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