dockergodockerfileopenshiftredhat

Go App deployment error on redhat openshift. CreateContainerError


status:
  containerStatuses:
    - name: go-drinkapp
      state:
        waiting:
          reason: CreateContainerError
          message: |
            container create failed: time="2024-11-18T15:36:18Z" level=error msg="runc create failed: unable to start container process: exec: \"./main\": stat ./main: permission denied"
      lastState: {}
      ready: false
      restartCount: 0
      image: 'docker.io/mridul017/go-drinkapp@sha256:4c8c422edf0f1dbbf6bed26c931412b4f1893880b446b64f4e0a6eb47005f1d8'
      imageID: ''

this is the part of YML code from openshift after deploying.

I have a dockerfile to build go app

# Use a newer Go version as the base image
FROM golang:1.23-alpine AS builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Initialize the Go module inside the Docker container
RUN go mod init drink || true

# Download dependencies
COPY . .
RUN go mod tidy

# Install Swagger CLI
RUN go install github.com/swaggo/swag/cmd/swag@latest

# Run the swag init command to generate Swagger docs
RUN swag init

# Build the Go app
RUN go build -o main .

# Start a new stage from scratch
FROM alpine:latest

# Set the working directory in the final image
WORKDIR /root/

# Copy the Pre-built binary file from the builder stage
COPY --from=builder /app/main .
COPY --from=builder /app/docs ./docs

# Expose port 8082 to the outside world
EXPOSE 8082

# Command to run the executable
CMD ["./main"]

It works locally I can build image and i can access the application. But When I try to deploy in openshift I got above createcontainererror. and /.main file can't execute. I tried also Chmod +x ./main but it doesn't work it gives me the same error. Any suggestion how can I solve this.


Solution

  • OpenShift contains a number of configurable security policies. In a production Unix environment in general, a reasonable constraint is that executables can only be run out of a set of known trusted directories. If you know that the administrator will only install software into /usr/local/bin, for example, then a software bug that wound up trying to run /app/uploads/malicious-upload.bin would be trapped by the security policy. It's possible your Kubernetes cluster is similarly configured.

    For compiled applications in languages like Go (also Rust or C++), your Dockerfile can just put the binary in a correct directory. Since the system directories are also on the default $PATH, this also makes the image very marginally easier to run.

    FROM golang:1.23-alpine AS builder
    ...
    FROM alpine
    COPY --from=builder /app/main /usr/local/bin/main
    #                             ^^^^^^^^^^^^^^^
    EXPOSE 8082
    CMD ["main"]  # no explicit path, the binary is on $PATH already