Unable to run docker image with an app in python - python

I am following the docker tutorials from the docker website (https://docs.docker.com/get-started/part2/) and trying to run an app (app.py - code given below) after building the image "friendlyhello". However when I try to run the app, I get the below error. I guess it is something to do with the code (app.py)
I have built the docker image successfully. However when I try to run the app which is to display the output in the browser, I get an error as
Name error: name "null" is not defined as shown in the screenshot below
I believe this because of the json format of the app.py which has a parameter execution_count and value as null. I understand pYthon has "None" but when I manually change it run, it still throws the same error
App.py - from the tutorial website
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2,
socket_timeout=2)
app = Flask(__name__)
#app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
v isits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"),
hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
JSON format - autogenerated - I only have Jupyter notebook and don't have pycharm in my system to open it. Not sure whether how is this json format generated.
I expect the output to be able to run the docker image and see the output as shown in the image below
Output

Related

Config var does not work in python Heroku app

I have an application that uses some environments variables like host, users, dbname to protect sensive data in a database connection. In local ambient, using localhost with Pycharm IDE that works fine!!! But when I upload code to Heroku, it don´t recognize my environment variables and app crashes.
Here is small code showing how I call variables at Pycharm IDE. That is fine for localhost:
from flask.app import Flask
from flask.templating import render_template
from flask_socketio import SocketIO, emit, send
import os
app = Flask(__name__)
host = os.environ['HOST']
dbname = os.environ['dbname']
#app.route("/")
def home():
return('<div>Host: ' + host + '</div><div>Dbname: ' + dbname + '</div>'
)
if __name__ == "__main__":
#io.run(app, debug=False)
app.run()
Here is response in local browser, that´s ok!
enter image description here
In Heroko, config var are equal variables above, follow print os settings:
Here is the result of same code uploaded to Heroku
enter image description here
And here is the return of logs --tail from heroku
enter image description here
enter image description here
Well, any suggestions to solve this problem? How can I adapt code to run in Heroku app?
Thx

Sending the output of a docker container as a response to a post request in flask

I am trying to build an application which takes a post request and runs a docker container which executes a shell script.I want to send back the output of the shell script as a response to this post request.For example the output of the shell file is "hello world" and It should be sent back as response to the post request.Here is the code
from flask import Flask, request
app = Flask(__name__)
#app.get('/run')
def test():
return 'running'
#app.post('/run')
def handle_request():
lang='python'
language = request.data
code=language.decode('utf-8')
if lang=='python':
file = open('input.py', 'w')
file.write(code)
else:
file = open('input.cpp', 'w')
file.write(code)
output=dockersandbox()
return output
if __name__ == '__main__':
app.run(debug=True)
import docker
import os
def dockersandbox():
image = 'myimage'
client = docker.from_env()
container = client.containers.run(
image=image,
volumes={os.getcwd(): {'bind': '/container/files', 'mode': 'rw'}},
remove=True,
stdout=True
)
output = container.decode('utf-8')
return output
Here the expected response for the post request is "helloworld" as the output of the shell file execution is "helloworld" but when I send a post request from postman I get this "Error: connect ECONNREFUSED 127.0.0.1:5000".I have separately ran that dockersandbox function and it works as intended and gives the correct output.I have also tested by sending only a string like "Test" as ouput of the dockersandbox function without implementing any docker container logic and code,in that case it gives the correct response for that post request,this issue happens if I implement this docker client logic in the dockersandbox function.I am using python's docker library to implement the docker logic and run the container.

How to fix internal server error when loading my database page (Flask/Heroku)?

I have a very basic Heroku web app where you can click on links (on the main page) to be redirected to other pages. I have done this to test the database page. All the pages work apart from when I click to view the database page. when I try I get an error message:
Internal Server Error
The server encountered an internal error and was unable to complete
your request.
Either the server is overloaded or there is an error in
the application.
I did try to play around with the procfile but in the end nothig worked. My current proctfile looks like this:
web: gunicorn flask-sqlalchemy-test-02.wsgi:application --log-file=-
To be honest I'm not too sure if its the procfile or the sytax in app.py which is causing me problems.
My app.py file:
import os
import psycopg2
from flask import Flask, render_template, g, url_for
app = Flask(__name__)
DATABASE_URL = os.environ.get('postgres://fikwczdiymxhwf:73bf42c2c8a15fa59b77e93654b6383e1cf4f85bdf0156818d1cf39a77815f13#ec2-54-243-47-196.compute-1.amazonaws.com:5432/d3uburco4fea1b'
#app.route('/')
def index():
return render_template("index.html")
#app.route('/page2')
def page_2():
return render_template("random_page_2.html")
#app.route('/hello')
def hello():
return render_template("hello.html")
#app.route('/view_database')
def view_db():
conn = psycopg2.connect(DATABASE_URL)
db = conn.cursor()
data = db.execute("SELECT * FROM example").fetchall()
db.close()
conn.close()
return render_template('view_database.html', data=data)
I expected to view the database in a form of an unordered list but recieved an error message instead:
Internal Server Error
The server encountered an internal error and was unable to complete your request.
Either the server is overloaded or there is an error in the application.
The way you are using os.environ.get() is wrong.
os.environ.get() is used to obtain environment variables that are exported by your OS, so DATABASE_URL returns None, you cannot connect to None URL, so internal server error.
**Correct Way : **
First, export the environment variable, if using Linux :
export DATABASE_URL=postgres://fikwczdiymxhwf:73bf42c2c8a15fa59b77e93654b6383e1cf4f85bdf0156818d1cf39a77815f13#ec2-54-243-47-196.compute-1.amazonaws.com:5432/d3uburco4fea1b
Then, in your code, replace that line as :
DATABASE_URL = os.environ.get('DATABASE_URL', '')

Docker - Can't get user webcam: getUserMedia() no longer works on insecure origins

WHAT WORKS
I created a simple Web Application in Flask that takes care of operating a simple return render_template("index.html") when the root node is accessed by a Web Browser.
# app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/")
def show_index():
return render_template("index.html")
if __name__ == "__main__":
app.run(port=80)
The index.html is a simple page that uses tracking.js in order to get the user webcam and track his/her face in the live video stream.
Opening cmd and typing python app.py results in Running on http://127.0.0.1:80/
Accessing the above mentioned URL results in the correct display of the page, that asks me for permission to use the camera, opens it and correctly tracks my face in the live video feed. So it's all working fine till here.
WHAT DOES NOT WORKS
The problem I'm experiencing arises when I dockerize my application using Docker. docker-machine ip is 192.168.99.100
Opening cmd and typing: docker run -p 4000:80 my_face_track_app results in: Running on http://0.0.0.0:80/
Accessing 192.168.99.100:4000 results in the correct display of index.html but I am not asked anymore for permission on the camera and inspecting the JS console I read the following exception:
getUserMedia() no longer works on insecure origins
Here the full error log:
I know the error is telling me I'm not serving the page in HTTPS.
Has anyone else encountered this problem?
What would be the proper solution to the issue or a possible walkaround?
Any help will be highly appreciated, thank you a lot in advance
WHAT I HAVE TRIED TO DO IN ORDER TO SOLVE THE PROBLEM
Since an HTTPS serving of the page is needed in order for JS to execute the function getUserMedia() I tought about serving my Flask application with an SSL certificate by modifying app.py like this:
# app.py
from flask import Flask, render_template
import OpenSSL
app = Flask(__name__)
#app.route("/")
def show_index():
return render_template("index.html")
if __name__ == "__main__":
app.run(port=80, ssl_context="adhoc")
I then dockerized the app building a new image. Typing:
docker run -p 443:80 facetrackapphttps
Results in
Running on https://127.0.0.1:80
So yeah, here HTTPS is ON: the problem is that the port 80 of the HTTPS Flask App is mapped to the port 443 of the docker-machine ip 192.168.99.100.
Trying to access 192.168.99.100:443 does not work and nothing is shown.
Does anybody have an idea about how to do this?
If your application is bound to 127.0.0.1 inside the container, you're not going to be able to access it from your host. According to the flask docs, flask will bind to 127.0.0.1 by default.
You'll need to modify your service so that it binds to 0.0.0.0 inside the container:
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80, ssl_context="adhoc")

Python indentation error in docker docs

Attempting Docker get-started example I continue to get the indentation error message included at the bottom of this question and I cannot diagnose the problem. I have edited the copy/paste version from the link to "look like" the browser view and have replaced all Tabs with 4 spaces. But I do not understand the code itself well enough to know if the browser indented view looks like its meant to or not.
My version of the app.py code is as follows.
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
#app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
The error is enclosed in the console session below.
server:docker0 brian$ docker run -p 4000:80 friendlyhello
File "app.py", line 15
except RedisError:
^
IndentationError: unexpected indent
server:docker0 brian$
How can I fix the error?
While continuing to debug, as a test I deleted the word RedisError from the except line. But the error message still contained RedisError. That was my clue that the app.py I thought was being executed was not being executed. I had to execute docker build ./ -t friendlyhello again before I could docker run.

Categories