I have a docker-compose config like the following:
version: '3.7'
services:
flask:
command: [python, app.py]
ports:
- "127.0.0.1:5000:5000"
frontend:
command: [sh, -c, "npm run start"]
ports:
- "127.0.0.1:7600:7600"
links:
- flask
The frontend container has a webpack development server running which proxies /api/* path requests to flask:5000 for processing. This works great when I use docker-compose up -d.
However, let's say I want to debug something in the flask app using pdb, and I run it manually instead using:
docker-compose stop flask
docker-compose run --rm --service-ports flask python app.py
Then suddenly, my frontend service cannot proxy request to my flask service and I'm getting an error like: Error occurred while trying to proxy request /testing from frontend:7600 to http://flask:5000 (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
What am I missing? How do I make this configuration work for interactive debugging of my python code?
Edit: I'm running Docker version 18.09.0, build 4d60db4 and docker-compose version 1.23.2, build 1110ad01
The problem is when you run manually, the container name is no longer flask, you can see that with docker network inspect your_network.
You need to first docker-compose rm flask to free the name flask, then docker-compose run --service-ports --name flask flask.
Finally, I don't know how you use pdb, but you can normally use docker-compose exec flask sh or docker attach container_id to get an interactive prompt.
Related
I'm developing some python microservices with grpc and i'm using docker for the cassandra database and the microservices. Is there a way to setup reload on change within docker-compose?
I'm guessing that first I need the code mounted as a volume but I don't see a way to reload on GRPC server like for example flask does.
We use watchdog[watchmedo] with our grpc services and Docker.
Install watchdog or add to your requirements.txt file
python -m pip install watchdog[watchmedo]
Then in your docker-compose.yml add watchmedo auto-restart --recursive --pattern="*.py" --directory="/usr/src/app/" python -- -m app to your container where --directory is the directory to where your app is contained inside the docker container, and python -- -m app is the file that starts your grpc Server. In this example the file that starts the server is called app.py:
app:
build:
context: ./app/
dockerfile: ./Dockerfile
target: app
command: watchmedo auto-restart --recursive --pattern="*.py" --directory="/usr/src/app/" python -- -m app
volumes:
- ./app/:/usr/src/app/
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.
First time using Docker(version 19.03.5) and trying this tutorial
I'm stuck on step 2.3.4 Running an image
When I go to http://localhost:8888 I see
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 updated Dockerfile to this to match my directory:
# our base image
FROM alpine:3.5
# Install python and pip
RUN apk add --update py2-pip
# install Python modules needed by the Python app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# copy files required for the app to run
COPY app.py .
COPY templates/index.html templates
# tell the port number the container should expose
EXPOSE 5000
# run the application
CMD ["python", "app.py"]
On my command line I have
C:\Users\user\docker\flask-app>docker run -p 8888:5000 --name flask-app 11111111/flask-app
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
When I visit the page I see on the prompt
172.17.0.1 - - [05/Jan/2020 07:14:34] "GET / HTTP/1.1" 500 -
I have this in my app.py
from flask import Flask, render_template
import random
app = Flask(__name__)
# list of cat images
images = [
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-1376-1381846217-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3391-1381844336-26.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-29111-1381845968-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3409-1381844582-13.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr02/15/9/anigif_enhanced-buzz-19667-1381844937-10.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-18774-1381844645-6.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif",
"http://img.buzzfeed.com/buzzfeed-static/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif"
]
#app.route('/')
def index():
url = random.choice(images)
return render_template('index.html', url=url)
if __name__ == "__main__":
app.run(host="0.0.0.0")
I can't figure out why my page isnt loading. Any help would be appreciated.
Note: I have WAMP installed and this might be conflicting but not sure if thats the case and/or how to fix it.
Flask might be unable to locate your templates. Try changing
COPY templates/index.html templates
to
COPY templates templates
to copy everything inside ./templates to <WORKDIR>/templates.
Using COPY templates/index.html templates will copy index.html as a file at path <WORKDIR>/templates, not copy it under that directory.
How to debug your Flask application in Docker:
Turn on Flask debugger by adding ENV FLASK_DEBUG=1 to your Dockerfile
Try to run the Flask app outside of Docker. It may be easier to set breakpoints inside your IDE (VSCode or PyCharm) and debug the app.
Try pdb to debug the app inside the container. It may be hard for a beginner, but in general, it's an essential skill. Check Debugging a Python Flask Application in a Docker Container for a step-by-step guide.
Note: This is more aimed at the question "How do I debug". It was unclear that the OP actually wanted a solution, not a way to solve the problem.
First thing to do is to start the container without the app in it. For that, you replace the CMD ["python", "app.py"] with CMD ["sleep", "inf"]. Now, after starting the container, you can get a shell in the container using docker exec -it flask-app /bin/bash to get a shell. In the shell, you can then use the regular Python debugger to set a breakpoint in the / handler and then single-step through the code to track down what Python's doing.
I have a Docker container which runs a Flask application. When Flask receives and http request, I would like to trigger the execution of a new ephemeral Docker container which shutdowns once it completes what it has to do.
I have read Docker-in-Docker should be avoided so this new container should be run as a sibling container on my host and not within the Flask container.
What would be the solution to do this with docker-py?
we are doing stuff like this by mounting docker.sock as shared volume between the host machine and the container. This allows the container sending commands to the machine such as docker run
this is an example from our CI system:
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Answering my own question. Here is a complete setup which works.
In one folder, create the following files:
requirements.txt
Dockerfile
docker-compose.yml
api.py
requirements.txt
docker==3.5.0
flask==1.0.2
Dockerfile
FROM python:3.7-alpine3.7
# Project files
ARG PROJECT_DIR=/srv/api
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR
COPY requirements.txt ./
# Install Python dependencies
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
docker-compose.yml
Make sure to mount docker.sock in volumes as mentioned in the previous answer above.
version: '3'
services:
api:
container_name: test
restart: always
image: test
build:
context: ./
volumes:
- ./:/srv/api/
- /var/run/docker.sock:/var/run/docker.sock
environment:
FLASK_APP: api.py
command: ["flask", "run", "--host=0.0.0.0"]
ports:
- 5000:5000
api.py
from flask import Flask
import docker
app = Flask(__name__)
#app.route("/")
def hello():
client = docker.from_env()
client.containers.run('alpine', 'echo hello world', detach=True, remove=True)
return "Hello World!"
Then open your browser and navigate to http://0.0.0.0:5000/
It will trigger the execution of the alpine container. If you don't already have the alpine image, it will take a bit of time the first time because Docker will automatically download the image.
The arguments detach=True allows to execute the container asynchronously so that Flask does not wait for the end of the process before returning its response.
The argument remove=True indicates Docker to remove the container once its execution is completed.
I'm trying to put up 3 apps using docker. One of them is a flask web app, the other is a redis server, and the other one is a celery app that will communicate with the flask one via redis.
Now the first 2 seem to come up without any issues, but for the flask app i'm getting this error:
celery_1 exited with code 1
My docker-compose.yml file looks like this:
version: '2'
services:
redis:
image: "redis:alpine"
web:
build: .
ports:
- "7998:7998"
command: "gunicorn -b 0.0.0.0:7998 --log-level TRACE common_apps:app"
celery:
build: .
command: "celery -A common_apps.celery_app worker"
And if I cut out the celery part and launch it individually, the error message I get is not being able to find the redis host (but this may be because the hostname redis is only present within the docker-compose context)
Any thoughts on what's broken here ?
Thanks a lot
The problem was the .env file was being ignored. After I moved the values from the .env file to the docker-compose.yml file, the application started working as intended