I'm trying to create a simple web application container within Ubuntu-WSL2 with the help of the Docker. So I've built my container creating my-simple-webapp folder and within that folder, I've created Dockerfile and app.py files;
Dockerfile
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y python python-pip
RUN pip install flask
COPY app.py /opt/
ENTRYPOINT FLASK_APP=/opt/app.py flask run --host=0.0.0.0 --port=8080
app.py
import os
from flask import Flask
app = Flask(__name__)
#app.route("/")
def main():
return "Welcome!"
#app.route('/how are you')
def hello():
return 'I am good, how about you?'
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
When I run the command docker build ./my-simple-webapp it works without error. However when I use my browser to connect my container typing 172.17.0.2:8080, o.o.o.o:8080 or localhost:8080 connection times out.
Resource : https://github.com/mmumshad/simple-webapp-flask
If all you run is docker build... then you still need to start your container with docker run....
You can open the docker dashboard (in your Windows tray) to see if your container is actually running.
To actually run your app you need to start a container. First, build the image:
docker build -t simple-webapp-flask .
Then start a container using the image, with 8080:8080 mapping from container to your host:
docker run -p 8080:8080 simple-webapp-flask
If you want to deploy your flask application, you need to choose from the following options:
https://flask.palletsprojects.com/en/1.1.x/deploying/
The way you are trying to do it, can be used only for development purposes.
Related
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?
I am trying to run a flask app using a docker.
Operating system Windows 11, WSL image Ubuntu-20.04.
A simple reproducible example:
https://github.com/Konrad-H/stackoverflow-question
If I run (inside a venv)
$ python app/main.py
the following message appears in the console:
Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
And I can successfully connect to the app.
On the other hand, if I try to run the repo using:
$ docker build -t s-o-question:latest .
$ docker run -p 5000:5000 s-o-question
I get the exact same message on the console, but the webpage takes a long time loading and after a while a connection timeout appears.
The error appears both inside WSL2 and inside Windows.
Source Code:
main.py
import logging
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
print("Hello World I am Sea")
return "Hello big world"
if __name__ == "__main__":
app.logger = logging.getLogger("audio-gui")
app.run( host='0.0.0.0',port=5000, debug=True)
Dockerfile
FROM python:3.8
# Working Directory
WORKDIR /app
# Copy source code to working directory
COPY . ./app /app/
# Install packages from requirements.txt
# hadolint ignore=DL3013
RUN pip install --no-cache-dir --upgrade pip &&\
pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt
EXPOSE 5000
ENTRYPOINT [ "python" ]
CMD [ "app/main.py" ]
I had the same issue. The URL http/localhost:5000/ worked for me (5000 is my exposed port number). you can try and see if it works. Alternatively, you can also try http://<host-ip>:5000/. Note that the host-ip should be IP address of your local machine not the IP address of the docker container.
you can also check this answer
The issue is that you cannot use same port number for ex if your app runs on port 5000 it must be bind to another port like 8080 in docker .
try this docker run -p 8080:5000 s-o-question
I had the same issue on my win 11 device , i worked around this using the above solution.
I am newbie to Docker and Python.I have created a simple python application using Flask .I would like to run it in a Docker container.The docker container shows it is running.However when I access the url ,I get localhost didn’t send any data.
docker container ls shows my container running on localhost and port no 8081
app.py
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
#app.route("/hello", methods=["GET","POST"])
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(debug=True, port=8081,host='0.0.0.0')
Dockerfile
FROM python:2.7
ADD app.py /
RUN pip install flask
EXPOSE 8081
CMD ["flask", "run", "--host=0.0.0.0"]
CMD ["python", "app.py", "--host=0.0.0.0"]
When I run the same app.py in my local environment.I get the desired data on the localhost url. Could someone guide me in the right direction?
Image is tagged dockerimage:latest and I run it with:
docker run -it -p 8081:8081 dockerimage
And checking for the container with docker container ls shows:
0.0.0.0:8081->8081/tcp
Everything seems fine in your Dockerfile and the Flask script, but I will suggest two thing.
Update base image to python:3.7 as 2.7 will reach its end of life.
Remove CMD ["flask", "run", "--host=0.0.0.0"] this as there is only one CMD per dockerfile.
FROM python:3.7.4-alpine3.10
RUN pip install flask
ADD app.py /
EXPOSE 8081
CMD ["python", "app.py", "--host=0.0.0.0"]
Now run the container
docker run -it --name my_app --rm -p 8081:8081 dockerimage
Open the browser and hit
http://localhost:8081/hello
or
docker exec -it my_app ash -c "apk add --no-cache curl && curl localhost:8081/hello"
One of the above should work.
If you the second command work then something wrong with host configuration.
I have created a simple flask app that is running on a this is the skeleton o the flask app, which by default runs at port 5000:
# Create the application instance
app = connexion.App(__name__, specification_dir="./")
# read the swagger.yml file to configure the endpoints
app.add_api("swagger.yml")
# Create a URL route in our application for "/"
#app.route("/")
def home():
"""
This function just responds to the browser URL
localhost:5000/
:return: the rendered template "home.html"
"""
return render_template("home.html")
if __name__ == "__main__":
app.run(debug=True)
In the Dockerfile I'm exposing the same port:
RUN python3 -m pip install -r requirements.txt
COPY . /app
EXPOSE 5000
Then I run the container as:
sudo docker run -d -p 5000:5000 my_app:latest
and once the container is up, I'm able to acces to app at:
http://localhost:5000
Now, I'm trying to change to port 5100, for that I'm changing:
a) In the Dockerfile:
COPY . /app
EXPOSE 5100
...
b) When I run the container:
sudo docker run -d -p 5100:5100 my_app:latest
But when I try to visit: http://localhost:5100/
The app is not running there
When I do Docker ps this is shown:
EDIT:
I tried changing the flask app:
app.run(host='0.0.0.0', port=5100)
Still not working, this is the screenshot from docker ps:
Not sure if the error is because still says 5000: at the begining:
5000/tcp, 0.0.0.0:5100->5100/tcp romantic_fermi
This is what I get from docker logs...
* Serving Flask app "server" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
You could technically change the default port assigned to the Flask object, but it's simpler to just change the docker mapping.
When you run a command like this:
$ docker run -d -p 5100:5100 my_app:latest
You are saying that you want to forward a port from inside the container (on the right) to your host machine (on the left).
# Left side is your host machine
# Right side is inside of the container
5100:5100
So you could update your run to map to 5000 inside of the container:
$ docker run -d -p 5100:5000 my_app:latest
Then you'll be able to access via http://localhost:5100
PS: If you haven't used docker-compose before, I would highly recommend setting it up after you've worked through this issue. It'll make your life easier in general.
On your .py script ou need to set 5100 port with:
app.run(debug=True,host='0.0.0.0', port=5100)
Everything else you did is correct!
If still your python are listening on port 5000, probably it's the old version.
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