Github actions throws error for permission denied: unknown for running dockerfile CMD

I am trying to build the following Dockerfile on Github Action. I have built and run it without any issue on a Linux locally.

FROM lukemathwalker/cargo-chef:latest-rust-1.53.0 as recipe

WORKDIR /usr/app

COPY ./ ./

RUN ["cargo", "chef", "prepare", "--recipe-path", "recipe.json"]

FROM lukemathwalker/cargo-chef:latest-rust-1.53.0 as cook

WORKDIR /usr/app

COPY --from=recipe /usr/app/recipe.json ./recipe.json

RUN ["cargo", "chef", "cook", "--release", "--recipe-path", "recipe.json"]

FROM rust:1.54.0 as build

WORKDIR /usr/app

COPY --from=cook /usr/app/target ./target

COPY --from=cook $CARGO_HOME $CARGO_HOME

COPY ./ ./

RUN ["cargo", "build", "--release", "--bin", "backend"]

FROM gcr.io/distroless/cc-debian10 as runtime

WORKDIR /usr/app

COPY --from=build /usr/app/target/release/backend ./backend

CMD [ "./backend" ]

EXPOSE 8080

However on Github Action, I got the error for the last CMD:

docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "./backend": permission denied: unknown.

Why is this happening and how can I solve it?

1 Like

How do you start the container in the Actions environment? For example if the workdir is changed that might mess with things.

@airtower-luna This is my action.yml. I just run it without changing any directory:

name: "Rust backend"
description: "Deploy rust backend"

runs:
  using: "docker"
  image: "Dockerfile"

1 Like

Ah, so a Docker action, that’s important. When running a Docker action the working directory is set to the workspace of the job, as described in the documentation. So calling ./backend will search in the repository you’re calling the action in, not the container image. :thinking:

Avoid using WORKDIR, and call your binary by an absolute path instead. You can change the end of your Dockerfile to something like this:

FROM gcr.io/distroless/cc-debian10 as runtime
COPY --from=build /usr/app/target/release/backend /usr/app/backend
CMD [ "/usr/app/backend" ]

I’m noticing two other things about that Dockerfile that might not work as expected when using it as the base for a Docker action:

  1. The EXPOSE instruction will do nothing. When the Docker action is called, the step waits for the container to terminate. So other steps can’t connect to the exposed port.

  2. The image is build every time the action is called. Using a multi-stage build shouldn’t break anything, but means you have to pull multiple base images without any benefit because the smaller final image isn’t stored or transferred anywhere.