GCP Cloud Run deployment failure - python

I am trying to execute a basic GCP Cloud Run example.
Code it self is very simple:
import os
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello_world():
name = os.environ.get("NAME", "World")
return "Hello {} This is our first application !".format(name)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
Then I tried a deployment using Cloud Code/Deploy on Cloud Run
Here is the result I get when I hit Deploy:
"Failed to build the app. Error: Build Failed. No push access to specified image repository. Try running with --default-repo flag."
Note that I am using Artifact-Registry, repo creation works fine
Docker file content is this:
FROM python:3.9-slim
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
RUN pip install Flask gunicorn
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
Anybody face this issue ?
Any help is appreciated.

Related

Deploying Flask API to 'cloud run' result in error using gcloud run deploy

I have a basic flask API to execute a python file.
Structure is as follows:
app.py
Dockerfile
requirements.txt
test.py
app.py:
from flask import Flask, request
import subprocess
import os
app = Flask(__name__)
#app.route("/execute", methods=["GET"])
def execute():
result = subprocess.run(["python", "test.py"], capture_output=True)
return result.stdout
if __name__ == "__main__":
app.run(port=int(os.environ.get("PORT", 8080)),host='0.0.0.0',debug=True)
Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /app
COPY . .
RUN pip install flask
RUN pip install -r requirements.txt --no-cache
EXPOSE 8080
CMD ["python", "app.py"]
test.py:
Python script that copies one document from a mongodb collection to another as a test.
The app runs on local machine.
Steps I followed in order to deploy to cloud run on gcloud:
docker build -t .
docker tag gcr.io//
docker push gcr.io//
gcloud run deploy --image gcr.io// --platform managed --command="python app.py"
Error on step 4. When I look at the logs the error returned are as follows:
terminated: Application failed to start: kernel init: cannot resolve init executable: error finding executable "python app.py" in PATH [/usr/local/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin]: no such file or directory
Please note I am on a windows machine and the Path in the error looks like a Linux path so I am not sure where to go from here
It looks like you are overriding the entrypoint of your docker image via the gcloud command.
You should not need to do so since it is already set in the Dockerfile.
Try changing the 4. step to:
gcloud run deploy --image gcr.io// --platform managed
Note
Looking at the error it seams that passing --command="python app.py" is changing the CMD command of your Dockerfile to something like
CMD ["python app.py"]
This is interpreted as a single executable called python app.py which is of course not found (since the executable is python and app.py is just an argument you want to pass to it.
Also as a sidenote I would suggest changing the last line of the Dockerfile to be an ENTRYPOINT instead of CMD:
FROM python:3.8-slim-buster
WORKDIR /app
COPY . .
RUN pip install flask
RUN pip install -r requirements.txt --no-cache
EXPOSE 8080
ENTRYPOINT ["python", "app.py"]
See here for some details
I have been able to successfully deploy to cloud run using the following, however when accessing the deployed API it returns a 404 error. Any suggestions will be appreciated.
I switch to Waitress (Waitress is meant to be a production-quality pure-Python WSGI server).
app.py
from flask import Flask, request
import subprocess
app = Flask(__name__)
#app.route("/run_script", methods=["GET", "POST"])
def run_script():
result = subprocess.run(["python", "test.py"], capture_output=True)
return result.stdout
if __name__ == "__main__":
from waitress import serve
serve(app, host='0.0.0.0', port=8080)
Dockerfile:
FROM python:3.9
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]
test.py:
df_AS = db.collectionName
#convert entire collection to Pandas dataframe
df_AS = pd.DataFrame(list(df_AS.find()))
newCollection.insert_many(df_AS.to_dict("records"))
this successfully deployed however the end point is not included in the url and have to be manually inserted at the end of the url. is this normal?

Google Cloud Run Flask App error import module

I have developed a flask rest API and I'm using flask_smorest.
I'm developing into cloud shell editor into google cloud.
When I run google cloud run emulator, I receive the error:
##########Linting Output - pylint##########
************* Module app
3,0,error,import-error:Unable to import 'flask_smorest'
and this my dockerfile:
FROM python:3.10
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
RUN pip install Flask gunicorn flask-smorest marshmallow
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app
This is app.py file:
import os
from flask import Flask, request
from flask_smorest import Api
app = Flask(__name__)
app.config["PROPAGATE_EXCEPTIONS"] = True
app.config["API_TITLE"] = "Stores REST API"
app.config["API_VERSION"] = "v1"
app.config["OPENAPI_VERSION"] = "3.0.3"
app.config["OPENAPI_URL_PREFIX"] = "/"
app.config["OPENAPI_SWAGGER_UI_PATH"] = "/swagger-ui"
app.config["OPENAPI_SWAGGER_UI_URL"] ="https://cdn.jsdelivr.net/npm/swagger-ui-dist/"
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
how i can fix this issue? And why i have this error?
Posting this as a community wiki from #dev_:
The issue was resolved by installing the module from the Cloud Shell Terminal.

Unable to run Python flask app in different port using docker-compose

I am running Flask application in Python using docker-compose. I am able to run the Flask app using 5000 port. I am trying to run it on 6000 besides another Flask app running on 5000. But I am unable run it on 6000 port. Any help would be appreciated.
docker-compose.yml
version: '3.8'
services:
web:
build: ./web
ports:
- "6000:5000"
app.py
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Dockerfile:
FROM python:3
COPY . /app
WORKDIR /app
RUN pip install -U pip
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
requirements.txt
Flask==1.1.1
Port 6000 is listening. I am able to get a connection succeeded by executing nc command with host and port.
I am unable to run the app on port 6000.
I got the following when I hit http://#{HOST_IP}:6000 in browser
This site can’t be reached
The web page at http://#{HOST_IP}:6000/ might be temporarily down or it may have moved permanently to a new web address.
6000 is unsafe port that is why browser not allowing to access the application.
how-to-fix-err-unsafe-port-error-on-chrome-when-browsing-to-unsafe-ports
But you should not allow this port, just try to publish another port.
version: '3.8'
services:
web:
build: ./web
ports:
- "5001:5000"
For downvoter
Here is Github Repo to verify this
git clone https://github.com/Adiii717/dockerize-flask-app.git
cd dockerize-flask-app/
# this will not work in the browser
PORT=6000 docker-compose up
You haven't defined any routes. The app server has no idea what routes are available nor does it know what you want to return, so you need to specify that.
Here's a more complete version of app.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Please refer to the Flask tutorial for a minimal app.

Getting ERROR 502 when trying to run a Docker Flask app on App Engine

I'd like to deploy a Docker image on App Engine which contains a basic Flask app. Also, this app will be a web-socket endpoint for my front-end.
Deployment is a success. But i'm getting an error 502.
I've read the doc, I've tried many configuration but I don't get it works, if someone has any idea, i'd highly appreciate.
My project structure :
- socket/
- socket/
- main.py
- Dockerfile
- app.yaml
- requirements.txt
- cloudbuild.yaml
main.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route('/')
def hello():
"""Return a friendly HTTP greeting."""
return 'Hello World!'
if __name__ == '__main__':
# This will be only used locally. App Engine will use gunicorn.
app.run(host='127.0.0.1', port=8080, debug=True)
requirements.txt
Flask==1.0.3
Flask-Sockets==0.2.1
gunicorn==19.9.0
Dockerfile
FROM python:2.7
WORKDIR /app
COPY . /app
EXPOSE 8080
RUN pip install --trusted-host pypi.python.org -r requirements.txt
ENTRYPOINT ["gunicorn","--bind=0.0.0.0:8080", "-k flask_sockets.worker", "main:app"]
app.yaml
runtime: custom
env: flex
service: socket
entrypoint: gunicorn -b :$PORT -k flask_sockets.worker main:app
manual_scaling:
instances: 1
network:
session_affinity: true
cloudbuild.yaml
steps:
# Decrypt env secrets
- name: gcr.io/cloud-builders/gcloud
args:
- kms
- decrypt
- --ciphertext-file=./socket/conf/gcp_credentials.json.enc
- --plaintext-file=./socket/conf/gcp_credentials.json
- --location=global
- --keyring=cloudbuild-env
- --key=cloudbuild-env
id: decrypt
# Build the docker image
- name: gcr.io/cloud-builders/docker
args: [ 'build', '-t', 'gcr.io/$PROJECT_ID/tweets-socket-dataflow', './socket/' ]
id: build
# Deploy the image
- name: gcr.io/cloud-builders/gcloud
args: ['app', 'deploy', './socket/app.yaml', '-v', '1-socket-latest']
id: deploy
timeout: 600s
This actually works locally.
Docker command used
docker run -it -d -p 8080:8080 144005a4e426
docker ps
c2763d0b8b75 144005a4e426 "gunicorn --bind=0.0…" 3 seconds ago Up 1 second 0.0.0.0:8080->8080/tcp sleepy_ganguly
http:127.0.0.1:8080

Google Container Engine Expose Service "Site Cannot Be Reached"

I am looking build a simple web application using Flask, Docker, and Google Container Engine. I have specified the following DockerFile:
# Use an official Python runtime as a base image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 8080
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
Note I am exposing port 8080.
Here is my simple Flask application:
from flask import Flask, jsonify
from flask import make_response
app = Flask(__name__)
tasks = [
{
'type': 'order',
'contents':[1,2,3,4,5,6,7,8,9,10]
}
]
#app.route('/', methods=['GET'])
def get_tasks():
return jsonify({'tasks': tasks})
#app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Note host='0.0.0.0' and port=8080.
I run the docker container locally, successfully:
docker run --rm -p 8080:8080 gcr.io/${PROJECT_ID}/hello-node:v1
However, when I deploy the application using the Google Container Engine I am not able to access the application via the external port provided by kubectl get service.
I run the following to deploy a Pod:
kubectl run hello-world --image=gcr.io/${PROJECT_ID}/hello-node:v1 --port 8080
I run the following commands to create a Service to access from the internet:
kubectl expose deployment hello-world --type=LoadBalancer --port 8080
Why am I not able to access the service? It seems I have opened port 8080 within every step 1) Flask application 2) Dockerfile 3) Pod Deployment 4) Service creation.
I think you should point out the target port as well when exposing your deployment, like this:
kubectl expose deployment hello-world --type=LoadBalancer --port=8080 --target-port=8080
Hope it helps

Categories

Resources