Auto reloading flask server on Docker
Solution 1
Flask supports code reload when in debug mode as you've already done. The problem is that the application is running on a container and this isolates it from the real source code you are developing. Anyway, you can share the source between the running container and the host with volumes on your docker-compose.yaml
like this:
Here is the docker-compose.yaml
version: "3"
services:
web:
build: ./web
ports: ['5000:5000']
volumes: ['./web:/app']
And here the Dockerfile
:
FROM python:alpine
EXPOSE 5000
WORKDIR app
COPY * /app/
RUN pip install -r requirements.txt
CMD python app.py
Solution 2
I managed to achieve flask auto reload in docker using docker-compose with the following config:
version: "3"
services:
web:
build: ./web
entrypoint:
- flask
- run
- --host=0.0.0.0
environment:
FLASK_DEBUG: 1
FLASK_APP: ./app.py
ports: ['5000:5000']
volumes: ['./web:/app']
You have to manually specify environment variables and entrypoint in the docker compose file in order to achieve auto reload.
Solution 3
Assuming your file structure is the below:
Dockerfile: (note WORKING DIR)
FROM python:3.6.5-slim
RUN mkdir -p /home/project/bottle
WORKDIR /home/project/bottle
COPY requirements.txt .
RUN pip install --upgrade pip --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]
Docker Compose:
version: '3'
services:
web:
container_name: web
volumes:
- './web:/home/project/bottle/' <== Local Folder:WORKDIR
build: ./web
ports:
- "8080:8080"
Related videos on Youtube
coucou
Updated on October 15, 2020Comments
-
coucou over 3 years
I want my flask server to detect changes in code and reload automatically. I'm running this on docker container. Whenever I change something, I have to build and up again the container. I have no idea where's wrong. This is my first time using flask.
Here's my tree
├── docker-compose.yml └── web ├── Dockerfile ├── app.py ├── crawler.py └── requirements.txt
and code(app.py)
from flask import Flask import requests app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello Flask!!' if __name__ == '__main__': app.run(debug = True, host = '0.0.0.0')
and docker-compose
version: '2' services: web: build: ./web ports: - "5000:5000" volumes: - ./web:/code
Please give me some advice. Thank you in advance.
-
vishes_shell almost 7 yearsI believe what you need to do is to watch this thread on github more closely. And you never put your command on how you run your docker
-
Robert almost 7 yearsPlease, post your docker-compose and I will see to adapt it
-
coucou almost 7 years@Robert I added it. Please look into it and help me.
-
Robert almost 7 years@James, does the below answer help you?
-
coucou almost 7 years@Robert, Fortunately, yes. The problem was './web:/code'. I changed it to './web:/abb' and it works. But don't know why...
-
CristiFati almost 5 yearsNot related to the question itself, but for newer versions, also check stackoverflow.com/questions/55271912/….
-
-
The Fool almost 6 yearsperfect now we can finally ditch from the app.py: if name == 'main': app.run(debug = True, host = '0.0.0.0')
-
Joost Döbken almost 6 yearsis it correct you still need the
WORKDIR app COPY * /app/
commands from lepsch ? -
dtasev almost 5 yearsA bit late but no - you shouldn't need to as the
/app
is now a mounted volume. Copying over the files is not necessary -
whatapalaver almost 4 yearsThanks this helped me. This trick is to make sure you mount your local code folder to the WORKDIR you've set in the Dockerfile. For me that was
WORKDIR=/home/app
so under volumes in the docker-compose file I needed to mount like this: ``- ./app:/home/app` -
MattSom about 3 yearsThis does not show your file structure so not informative enough.
-
MattSom about 3 yearscould you describe how
volumes: ['./web:/app']
works please? -
MattSom about 3 yearsCould you explain the volumes, why the naming is that what you've provided?
-
lepsch almost 3 years@MattSom, volumes are the folders that you're going to bind from your machine to the container itself. I.e. the local folder is going to exist inside the container. If you follow the OP question and take a look at the file-tree structure, the source code is inside a folder named
web
. Thevolumes
then is just sharing this folder into a new one calledapp
inside the container. BTW,app
because in theDockerfile
the defaultWORKDIR
isapp
and everything is copied to/app/
also (volumes
in the docker-compose is going to take priority over the copied files). -
lepsch almost 3 yearsIt's nice to keep the
COPY * /app/
in theDockerfile
so theDockerfile
is self-contained apart from the docker-compose. -
MattSom almost 3 yearsThank you so much for the great explanation, you should add it to the answer imho. Thanks for the
Copy * /app/
comment as well. I had a react app and usedCopy . .
but hot realoding did not want to work. I went crazy for days but with this one it works! -
Máxima Alekz almost 3 yearsWhy are you EXPOSing port from Dockerfile if docker-compose.yaml is already exposing it?
-
lepsch almost 3 years@MáximaAlekz just to make the
Dockerfile
self-contained. I.e. you candocker build...
anddocker run...
it manually and it still works withoutdocker-compose
-
Aderbal Nunes about 2 years@MattSom By adding the volume, docker compose will sync the host folder with the container folder.