简体   繁体   中英

gcloud Docker error because of user input taking

I am trying to deploy a Python App using Docker on Google Cloud

After typing the command gcloud run deploy --image gcr.io/id/name , I get this error:

ERROR: (gcloud.run.deploy) Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.

Logs explorer:

    TEST_MODE = input()
EOFError: EOF when reading a line 

I know with error is caused by trying to take in user input, and with Dockers this command solves the error: docker run -t -i

Any idea how to run this with gcloud?

Your example does not run a server and so it's not accepted by Cloud Run.

Cloud Run expects a server to be running on PORT (generally this evaluates to 8080 but you should not assume this).

While it's reasonable to want to run arbitrary containers on Cloud Run, the service expects to something to respond via HTTP.

One option would be to simply jam an HTTP server into your container that listens on PORT and then run your Python app alongside it but, Python is single-threaded and so it's less easy to do this. Plus, it's considered an anti-pattern to run multiple processes in a single container.

Therefore I propose the following:

Rewrite your app to return the input as an HTTP GET:

main.py :

from flask import Flask
app = Flask(__name__)


@app.route('/hello/<name>')
def hello(name):
    return "Hello {name}".format(name=name)

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

Test it:

python3 main.py
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)

NOTE Flask is running on localhost ( 127.0.0.1 ). We need to change this when we run it in a container. It's running on 8080

NAME="Freddie"
curl http://localhost:8080/hello/${NAME}
Hello Freddie

Or browse: http://localhost:8080/hello/Freddie

Containerize this:

Dockerfile :

FROM python:3.10-rc-slim

WORKDIR /app

RUN pip install flask gunicorn

COPY main.py .

ENV PORT 8080

CMD exec gunicorn --bind 0.0.0.0:$PORT main:app

NOTE ENV PORT 8080 sets the environment variable PORT to a value of 8080 unless we specify otherwise (we'll do that next)

NOTE The image uses gunicorn as a runtime host for Flask. This time the Flask service is bound to 0.0.0.0 which permits it to accessible from outside the container (which we need) and it uses the value of PORT

Then:

# Build
docker build --tag=66458821 --file=./Dockerfile .

# Run
PORT="9999"
docker run \
--rm --interactive --tty \
--env=PORT=${PORT} \
--publish=8080:${PORT} \
66458821

[INFO] Starting gunicorn 20.0.4
[INFO] Listening at: http://0.0.0.0:9999 (1)

NOTE Because --env=${PORT} , Flask now runs on 0.0.0.0:9999 but, we remap this port to 8080 on the host. This is just to show how the PORT variable is now used by the container

Test it (using the commands as before)!

Publish it and gcloud run deploy...

Test it!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM