I have a Python Flask App running inside a Docker container in the default port 500. This is on a Ubuntu server.
I am able to access the Flask App through local host as follows:
URL = "http://127.0.0.1:5000/get_image"
Would like to know how to expose this server to outside world. I would like to use the server IP to expose the service so that others can access it as well.
Can some one guide on how to expose this docket to internet? Thank you
You should first put "0.0.0.0" as host for flask. Next you need to expose your docker port.
Flask file:
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/get_image')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
Dockerfile
FROM python:3.7
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python"]
CMD ["app.py"]
Build the docker image
docker build -t docker_flask:latest .
Run the image
docker run -d -p 5000:5000 docker_flask:latest
After checking everything is running fine in local, push the image to docker registry using docker push command. Then deploy the image on kubernetes or VM
Related
I'm brand new to Docker so I think there's something wrong in my setup.
Here's my app.py (reduced version):
import flask
from flask import request
from flask_cors import CORS, cross_origin
app = flask.Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route('/', methods=['GET'])
#cross_origin()
def index():
return('Home')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
My Dockerfile:
FROM python:3
WORKDIR /app
ENV FLASK_APP=app.py
COPY ./requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
I'm building the image with docker build -t flaskapi . and running with
docker run --rm -it -p 80:5000 flaskapi which gives the following output:
* Serving Flask app "app" (lazy loading)
* Environment: development
* Debug mode: on
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://172.17.0.2:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
Visiting localhost in the browser, everything works fine but when trying to vist http://172.17.0.2:5000/ or testing with Postman, I eventually get a timeout error. I feel like it's just a small mistake I've made somewhere but I can't quite see it. What can I do to fix this?
By default, Docker runs in a separate subnet that is not accessible by the outside world. To be able to access the service running inside the container, you will have to map one of your host's ports to the internal docker subnet.
In your run command, you map TCP 80 to TCP 5000 inside the docker network (the -p 80:5000 part). That's why your service is accessible when visiting http://localhost (80 is implied). In essence, any request to your port 80 will end up being served by the service running at http://172.17.0.2:5000/.
The 172.* ip is in Docker's subnet range. To communicate via that, with your current settings, you would have to be in another container that shares the same network as this one.
I have docker running on my Windows 10 OS and I have a minimal flask app
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run(host ='0.0.0.0', port = 5001, debug = True)
And I am dockerizing it using the following file
FROM python:alpine3.7
COPY . /opt
WORKDIR /opt
RUN pip install -r requirements.txt
EXPOSE 5001
ENTRYPOINT [ "python" ]
CMD ["app.py", "run", "--host", "0.0.0.0"]
From what I am seeing on other posts and on Flask tutorials having a 0.0.0.0 should allow me to connect from the windows firefox browser when I type 0.0.0.0:5001 but it is not connecting, I keep getting a 'unable to connect' message. I remember using the 0.0.0.0:port to connect in localhost on a linux ubuntu machine but for whatever reason its not letting me connect on Windows. Is there a special setting to connect on windows ?
Inside the Docker container, the private port is 5001. This private port then needs to be mapped to a public port when running the container. For example, to set the public port to 8000, you could run:
$ docker run --publish 8000:5001 --name <docker-container> <docker-container>:<version-tag>
The Flask app would then be accessible at URL: http://127.0.0.1:8000
Dockerfile
In addition, since in app.py you are setting the host and port, there is no need to specify these values in the Dockerfile CMD. But the public port (in this example 8000) needs to be exposed.
It also looks like the COPY command is placing everything under an /opt directory, so that needs to be included in the app path when launching the Flask app within Docker.
FROM python:alpine3.7
COPY . /opt
WORKDIR /opt
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "/opt/app.py"]
Docker-Flask Example
For a complete Flask-Docker example, including using Gunicorn, see:
Docker Python Flask Example using the Gunicorn WSGI HTTP Server
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.
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