Problem:
I’m trying to deploy a Flask app with a pre-trained machine learning model (stored as a model.pkl
file in the same directory) to Google Cloud Run. The container runs perfectly fine locally, but fails when deploying to Cloud Run with the following error:
ERROR: (gcloud.run.deploy) Revision 'mymodel-service-00015-svm' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable.
Commands I’m Using:
-
Building the Docker image:
docker build --no-cache -t gcr.io/dehaproject2024/mymodel:latest .
-
Pushing the Docker image:
docker push gcr.io/dehaproject2024/mymodel:latest
-
Deploying to Google Cloud Run:
gcloud run deploy mymodel-service --image gcr.io/dehaproject2024/mymodel:latest --platform managed --region me-west1 --allow-unauthenticated
The Project Structure:
.
├── server.py # The Flask app file
├── Dockerfile # The Dockerfile for building the container
├── model.pkl # The ML model (pickle file)
├── requirements.txt # Dependencies
server.py
(Flask App):
from flask import Flask, request, jsonify
import pandas as pd
import pickle
import os
app = Flask(__name__)
# Load your trained model (assuming it's a pickle file)
model = pickle.load(open('model.pkl', 'rb'))
@app.route('/predict', methods=['POST'])
def predict():
try:
json_data = request.get_json() # Get data posted as JSON
data = pd.DataFrame(json_data) # Convert JSON to pandas DataFrame
# Assuming your model expects the data in the same format as your training data
# Make sure to handle preprocessing if needed
predictions = model.predict(data)
return jsonify(predictions.tolist()) # Return predictions as JSON
except Exception as e:
return jsonify({"error": str(e)}), 400
if __name__ == "__main__":
port = int(os.environ.get("PORT", 8080))
app.run(host="0.0.0.0", port=port)
Dockerfile
:
FROM python:3.10-slim
WORKDIR /app
COPY . /app
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080
ENV PORT 8080
CMD ["gunicorn", "--bind", "0.0.0.0:$PORT", "server:app"]
What I Tried:
-
The container works locally when I run it like this:
docker run -p 8080:8080 gcr.io/dehaproject2024/mymodel:latest
-
I have confirmed the app runs fine locally and responds to
/predict
endpoint. -
I’ve tried making sure that the app is binding to the correct port by using
$PORT
environment variable, both in theserver.py
file and the Dockerfile. -
I’m still getting the same error message as stated above.
-
the requirements.txt is up-to-date with all necessary dependencies.
What Could Be the Issue?
3
- Remove
EXPOSE 8080
andENV PORT 8080
(You’re removing the latter because cloud run documentation says
In particular, the PORT environment variable is injected inside your container by Cloud Run. You should not set it yourself
- Change the final line to
CMD exec gunicorn --bind :$PORT server:app
1