I am new to Docker.
Here is a very simple application written in DashPlotly:
FROM python:3.8-slim
COPY . /app
WORKDIR /app
RUN pip3 install --no-cache -r requirements.txt
EXPOSE 8050
CMD ["python3","./app.py","--host","0.0.0.0"]
#docker build -t test .
#docker run -p 8051:8050 -it test
Connecting to the PostgreSQL database...
Running on http://127.0.0.1:8050/
Debugger PIN: 479-458-364
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
But when a point the browser to 127.0.0.1:8051, it says connection reset...
The solution is to force the DashPlotly server to run on 0.0.0.0
app.run_server(host='0.0.0.0',debug=False, port=8050)
Related
This question already has answers here:
Deploying a minimal flask app in docker - server connection issues
(8 answers)
Closed 7 months ago.
[Editted]
I am trying to dockerize a simple flask project. I kept getting this error when I run the project using docker. On the other hand the project works just fine when I run it normally using python3 test-flask.py
Docker File
FROM python:3.9.6-slim
# https://www.lifewithpython.com/2021/05/python-docker-env-vars.html
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONUTF8=1 \
PIP_DISABLE_PIP_VERSION_CHECK=on
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
curl \
wget \
unzip \
jq \
ffmpeg \
libsndfile1-dev \
&& rm -rf /var/lib/apt/lists/*
RUN wget "https://download.pytorch.org/whl/cpu/torch-1.10.2%2Bcpu-cp39-cp39-linux_x86_64.whl" \
&& pip install torch-1.10.2+cpu-cp39-cp39-linux_x86_64.whl
RUN mkdir app
WORKDIR /app
COPY README.md .
COPY requirements.txt .
COPY setup.py .
COPY src ./src
RUN pip install .
# COPY main.py .
COPY test_flask.py .
CMD [ "python", "test_flask.py", "run", "--host", "0.0.0.0"]
docker-compose.yml
version: '3.9'
services:
asr-cpu-local:
build:
context: ./
dockerfile: ./Dockerfile
volumes:
- ./data:/data
- ./models:/models
ports:
- 127.0.0.1:8000:8000
In the Terminal and Docker Container log, after I run it with docker, it shows no error at all
* Serving Flask app 'test_flask' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:8000 (Press CTRL+C to quit)
* Restarting with stat
For additional information, I have run docker port to check, but the error still occured:
docker port <container-name>
8000/tcp -> 127.0.0.1:8000
For the File test_flask.py:
from flask import Flask
app = Flask(__name__)
import librosa
from src.jrasr.predictors import Wav2vec2bert2bertPredictor
MODEL_CONFIG = {
"name": "Wav2vec2bert2bertPredictor",
"version": "0.0.1",
"models": [
{
"name": "wav2vec2",
"dir": "/models/wav2vec2-base-csj-kana-v0.0.1"
},
{
"name": "bert2bert",
"dir": "/models/bert2bert-csj-kana-v0.0.1"
}
]
}
#app.before_first_request
def load_model_to_app():
# Load the model
app.predictor = Wav2vec2bert2bertPredictor(MODEL_CONFIG)
#app.route('/')
def index():
return "This is Home Page"
#app.route('/data/<audio_path>')
def predict(audio_path):
model = app.predictor
audio_path = "/data/"+audio_path
data, _ = librosa.load(audio_path, sr=16000, mono=True, duration=10)
words = model.predict(data)
result = "".join(words)
return result
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000, debug=True)
But when I try to access the Ip address as shown in the Terminal and Docker Container Log, I got that 127.0.0.1 refuse to connect such as in the image shown below. The problem is in the terminal and docker log, there isn't any Error message, but still I can't access it, can anyone tell me, how to solve my problems?
Error at the local browser
127.0.0.1 is the localhost interface and when running inside the container only the container has access to it. To be accessible outside the container it should be the special IP 0.0.0.0 to bind all interfaces.
Solution 1
Change the host to be 0.0.0.0 instead of 127.0.0.1 in the test_flask.py. Something like the following snippet.
WARNING: As 0.0.0.0 binds all interfaces to the outside world it could be a security risk if running it locally instead of in a container. That said, the Solution 2 is the recommended one (With the 127.0.0.1 in the Python source as it is). So, when running it directly locally it binds to the localhost and when running it in the container it binds the outside world of the container itself.
...
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
Solution 2
On the other hand, to run it passing the host as an argument the Dockerfile should be changed to the following:
...
ENV FLASK_APP=test_flask
CMD ["flask", "run", "--host=0.0.0.0"]
Test it with the browser connecting to http://localhost:8000/ or http://127.0.0.1:8000/
I am dockerizing a React-Flask web application with separate containers for the frontend and the backend Flask API. Up to now I have only run this on my localhost using the default Flask development server. I then installed Gunicorn to prep the application for deployment with Docker later, and that also ran smoothly on my localhost.
After I ran docker compose up the two images built successfully, are attached to the same network, and I got this in the logs:
Logs For backend:
Starting gunicorn 20.1.0
Listening at: http://0.0.0.0:5000 (1)
Using worker: gthread
Logs For frontend:
react-flask-app#0.1.0 start
react-scripts start
Project is running at http://172.21.0.2/
Starting the development server...
But when I try to access the site at http://172.21.0.2/, localhost:5000 or localhost:3000 it is not accessible. Do I maybe need to add the name of the frontend or backend service?
In Docker Desktop it's showing that the frontend is running at port 5000 but there is no port listed for the backend, it just says it's running.
This is what my files and setup look like:
I added a gunicorn_config.py file as I read it is a good practice, rather than adding all of the arguments to the CMD in the Dockerfile:
bind = "0.0.0.0:5000"
workers = 4
threads = 4
timeout = 120
Then in my Flask backend Dockerfile I have the following CMD for Gunicorn:
FROM python:3.8-alpine
EXPOSE 5000
WORKDIR /app
COPY requirements.txt requirements.txt
ADD requirements.txt /app
RUN pip install --upgrade pip
ADD . /app
COPY . .
RUN apk add build-base
RUN apk add libffi-dev
RUN pip install -r requirements.txt
CMD ["gunicorn", "--config", "gunicorn_config.py", "main:app"]
Here I do "main:app" where my Flask app file is called main.pyand then app is my Flask app object.
I'm generally confused about ports and how this will interact with Gunicorn and in general. I specified port 5000 in the EXPOSE of both of my Dockerfiles.
This is my frontend Dockerfile:
WORKDIR /app
COPY . /app
RUN npm install --legacy-peer-deps
COPY package*.json ./
EXPOSE 3000
ENTRYPOINT [ "npm" ]
CMD ["start"]
And used 5000 in the bind value of my Gunicorn config file. Also, I previously added port 5000 as a proxy in package.json.
I will initially want to run the application using Docker on my localhost but will deploy it to a public host service like Digital Ocean later.
This is my Docker compose file:
services:
middleware:
build: .
ports:
- "5000:5000"
frontend:
build:
context: ./react-flask-app
dockerfile: Dockerfile
ports:
- "3000:3000"
The other thing to mention is that I also created a wsgi.py file and I was wondering do I need to add this to the Gunicorn CMD in my Dockerfile:
from main import app
if __name__ == "__main__":
app.run()
folks i have a web folder which has the following files inside:
app.py
Docker file
requirements.txt
outside that file i have a docker-compose.yml
the code is as follows:
app.py
code...
if __name__ == "__main__":
app.run(host='0.0.0.0')
on the requirements txt:
Flask
flask_restful
on the DockerFile:
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./app.py" ]
and on the docker-compose.yml:
version: '3'
services:
web:
build: ./web
ports:
- "5000:5000"
i go on the terminal and i run
docker compose build and
docker compose up
and server runs as below:
se 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
PS C:\Users\sarandis\Desktop\Python API\web service> docker compose up
webservice-web-1 | * Serving Flask app 'app' (lazy loading)
webservice-web-1 | * Environment: production 0.6s
webservice-web-1 | WARNING: This is a development server.
Do not use it in a production deployment.
webservice-web-1 | Use a production WSGI server instead.
webservice-web-1 | * Debug mode: off Do not use it in a production deployment.
webservice-web-1 | * Running on all addresses.
webservice-web-1 | WARNING: This is a development server.
Do not use it in a production deployment.
webservice-web-1 | * Running on http://172.18.0.2:5000/ (PreDo not use it in a production deployment.ss CTRL+C to quit) ss CTRL+C to quit)
Gracefully stopping...
the problem i have when i click on the url it provides me it says that the site cant be reached!!
why is that? what em i doing wrong?
note that when i do flask run the app runs at it should and all the get and post requests work fine!
Thank you in advance
Have you tried to access http://localhost:5000 instead of the provided URL?
Im new to docker and Flask and I'm getting an issue when I try to run the app. The browser says the site (172.17.0.2:5000) can't be reached.
For anyone wondering, the Dockerfiles:
FROM ubuntu
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install flask
RUN mkdir -p /opt/MyApp-test
COPY . /opt/MyApp-test
WORKDIR /opt/MyApp-test
EXPOSE 5000
ENTRYPOINT python3 main.py
CMD flask run --host 0.0.0.0
The main.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return 'IT WORKED! I AM RUNNING FROM A DOCKER CONTAINER!!!'
if __name__ == '__main__':
app.run()
And when I run the container, I get:
(base) daniellombardi#Daniels-MacBook-Pro MyApp-test % docker run 2625
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
I try to go to http://127.0.0.1:5000/, unable to connect, then I inspect the container to get its IP address, and it says 172.0.1 instead of 127.0.0.1:5000, but also unable to connect. And the app works when I run it on my computer.
You should just bind the exposed port inside of your container to a port in docker host when calling docker run, thus docker run should be called this way:
docker run 2625 -p 5000:5000
Here's my Dockerfile:
FROM alpine:3.5
RUN apk add --no-cache python3 && \
python3 -m ensurepip && \
rm -r /usr/lib/python*/ensurepip && \
pip3 install --upgrade pip setuptools && \
rm -r /root/.cache
# Copy files
COPY ./requirements.txt /app/requirements.txt
COPY ./main.py /app/main.py
# Install deps
RUN pip install --upgrade pip
RUN pip install --requirement /app/requirements.txt
# Set the default directory where CMD will execute
WORKDIR /app
EXPOSE 5000
CMD [ "python3", "-u", "./main.py" ]
and my main.py file:
from flask im
port Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
After building the tag and running it via docker run <tag>, get logs saying the flask server was successfully started:
$ docker run test:latest
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
But I cannot hit the server in my browser.
I thought the problem may be in the port mapping, so I ran the container like this:
$ docker run -p 5000:5000 test:latest
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Still no dice. I am able to run the server outside of the container, simply by running python3 main.py. what am I doing wrong?
The script is listening to 127.0.0.1 in the container, making it inaccessible from the host. It must listen to 0.0.0.0.
The 127.0.0.1 address that you see is the localhost of the container networking, that is not the same as the main host. When exposing ports, docker maps a port binding in container internal IP (172.17....) to a port in the hosts interfaces.
So you must tell your flask to listen to all of its interfaces:
app.run(host='0.0.0.0')
127.0.0.1 is the loopback address (also known as localhost).
0.0.0.0 is a non-routable meta-address used to designate an invalid, unknown, or non-applicable target (a ‘no particular address’ place holder). For things like address binding of network connections, the result can be to assign an appropriate interface address to the connection.
In Docker, the loopback address (127.0.0.1) of a container is not the same as the host. Use 0.0.0.0 as the host instead.
app.run(host='0.0.0.0')