everspader
everspader

Reputation: 1710

Google Cloud Run error: Invalid Command \"/bin/sh\": file not found when deploying from Docker image

I am trying to deploy a fairly simple Python web app with FastAPI and Gunicorn on Google Cloud Run with a Docker container following this tutorial and upon deploying I keep falling on the same error:

Invalid ENTRYPOINT. [name: "gcr.io/<project_id>/<image_name>@sha256:xxx" error: "Invalid command \"/bin/sh\": file not found" ].

It works fine to build the image and push it to the Container Registry.

On the cloud run I have set my secrets for database connection and I am passing as an argument to the Dockerfile which settings.py file to use for the production environment, as I did locally to build/run the container.

Any idea on what am I missing or doing wrong in the process? It's my first attempt to deploying a web app on a cloud service so I might not have all the concepts on point just yet.

Dockerfile

FROM ubuntu:latest

ENV PYTHONUNBUFFERED 1

RUN apt update && apt upgrade -y

RUN apt install -y -q build-essential python3-pip python3-dev
RUN pip3 install -U pip setuptools wheel
RUN pip3 install gunicorn uvloop httptools

COPY requirements.txt /code/requirements.txt
RUN pip3 install -r /code/requirements.txt

COPY . code/

# Pass the settings_module as an argument when building the image
ARG SETTINGS_MODULE
ENV SETTINGS_MODULE $SETTINGS_MODULE

EXPOSE $PORT

CMD exec /usr/local/bin/gunicorn -b :$PORT -w 4 -k uvicorn.workers.UvicornWorker app.main:app --chdir /code

cloudbuild.yaml

steps:
- name: gcr.io/cloud-builders/docker
  args: ["build", "--build-arg", "SETTINGS_MODULE=app.settings_production", "-t", "gcr.io/$PROJECT_ID/<image_name>", "."]
images:
- gcr.io/$PROJECT_ID/<image_name>
gcloud builds submit --config=cloudbuild.yaml

Upvotes: 0

Views: 1923

Answers (1)

DazWilkin
DazWilkin

Reputation: 40426

Update

I replaced ubuntu:latest (==20.04) with debian:buster-slim and it worked.

Previously

Deploying to Cloud Run, I receive the error too...I suspect it's the PORT, investigating. Not the PORT. Curiously, the image runs locally. Trying a different OS!

I repro'd your Dockerfile and cloudbuild.yaml in a project and the build and run succeed for me:

docker run \
--interactive --tty \
--env=PORT=8888 \
gcr.io/${PROJECT}/67486954
[2021-05-11 16:09:44 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2021-05-11 16:09:44 +0000] [1] [INFO] Listening at: http://0.0.0.0:8888 (1)

NOTE To build from a Dockerfile, you need not create a cloudbuild.yaml and can just gcloud builds submit --tag gcr.io/PROJECT_ID/...

A good way to diagnose the issue is to run the docker build locally:

docker build \
--build-arg=SETTINGS_MODULE=app.settings_production \
--tag=gcr.io/$PROJECT_ID/<image_name> \
.

And then attempt to run it:

docker run \
--interactive --tty --rm \
gcr.io/$PROJECT_ID/<image_name>

This isolates Cloud Build as the issue and will likely result in the same error.

The error suggests that the container isn't finding a shell (/bin/sh) in the ubuntu:latest image which is curious.

I think you can|should drop the `exec` after `CMD`

NOTE I read through Google's tutorial and see that the instructions include CMD exec ..., I'm unclear why that would be necessary but presumably it's not a problem.

Can you run the gunicorn command locally without issue??

/usr/local/bin/gunicorn -b :$PORT -w 4 -k uvicorn.workers.UvicornWorker app.main:app --chdir /code

The placement of --chdir /code is curious too. How about:

WORKDIR code
COPY . .

...

CMD /usr/local/bin/gunicorn -b :$PORT -w 4 -k uvicorn.workers.UvicornWorker app.main:app

Hmmm link perhaps move the --chdir before the app.main:app too so that it's applied to the gunicorn rather than your app.

/usr/local/bin/gunicorn -b :$PORT -w 4 -k uvicorn.workers.UvicornWorker --chdir /code app.main:app

Upvotes: 1

Related Questions