I'm trying to deploy a simple Python-based Docker container based on Ubuntu 20.04 via Google Cloud Run. I've successfully built the image, but when I try to deploy the Cloud Run service, I get the following error (project details omitted):
Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
error: "Invalid command \"/bin/sh\": fil
e not found"
e not found"
]....failed
Deployment failed
What's strange, though, is if I pull and run the image locally, it works just fine.
docker run --rm --publish 5000:5000 -e PORT=5000 -it gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}
My Dockerfile is about as basic as it gets:
FROM ubuntu:20.04
COPY . /app
WORKDIR /app
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y python3 python3-pip \
&& pip3 install gunicorn Flask flask-cors
CMD exec gunicorn --bind :$PORT --worker-tmp-dir /dev/shm --timeout 900 wsgi:app
What's even stranger still is that if I replace the base image with debian:buster-slim
, it works just fine.
Does anyone have any idea what might be going on?
Additional info:
status:
conditions:
- type: Ready
status: 'False'
message: |-
Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
error: "Invalid command \"/bin/sh\": file not found"
].
lastTransitionTime: '2020-05-12T07:40:12.804Z'
- type: ConfigurationsReady
status: 'False'
message: |-
Cloud Run error: Invalid argument error. Invalid ENTRYPOINT. [name: "gcr.io/{PROJECT_ID}/{SERVICE_NAME}@sha256:{HASH}"
error: "Invalid command \"/bin/sh\": file not found"
].
lastTransitionTime: '2020-05-12T07:40:12.804Z'
- type: RoutesReady
status: 'True'
lastTransitionTime: '2020-05-12T06:19:12.224Z'
I ran into the same issue. It seems to be intermittent: in the day time I couldn't deploy to Cloud Run, but in the late evening, various workarounds worked about half the time.
The most reliable workaround I found is to not depend on /bin/sh or /bin/bash in CMD or ENTRYPOINT. It appears /bin/sh exists at runtime, but it sometimes doesn't exist while Cloud Run is testing the container before deployment.
Instead of this in Dockerfile:
CMD exec gunicorn --bind :$PORT --workers 1 --threads 4 main:app
I used this instead:
CMD ["/usr/bin/python3", "/app/run_gunicorn.py", "--workers", "1", "--threads", "4", "main:app"]
Then I added the run_gunicorn.py script:
import os
import sys
from gunicorn.app.wsgiapp import run
port = os.environ['PORT']
sys.argv[-1:-1] = ['--bind', f':{port}']
print("sys.argv:", sys.argv)
run()
That's a way to keep the port number dynamic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With