Auto reloading flask server on Docker

22,705

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:

enter image description here

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"
Share:
22,705

Related videos on Youtube

coucou
Author by

coucou

Updated on October 15, 2020

Comments

  • coucou
    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
      vishes_shell almost 7 years
      I 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
      Robert almost 7 years
      Please, post your docker-compose and I will see to adapt it
    • coucou
      coucou almost 7 years
      @Robert I added it. Please look into it and help me.
    • Robert
      Robert almost 7 years
      @James, does the below answer help you?
    • coucou
      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
      CristiFati almost 5 years
      Not related to the question itself, but for newer versions, also check stackoverflow.com/questions/55271912/….
  • The Fool
    The Fool almost 6 years
    perfect now we can finally ditch from the app.py: if name == 'main': app.run(debug = True, host = '0.0.0.0')
  • Joost Döbken
    Joost Döbken almost 6 years
    is it correct you still need the WORKDIR app COPY * /app/ commands from lepsch ?
  • dtasev
    dtasev almost 5 years
    A 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
    whatapalaver almost 4 years
    Thanks 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
    MattSom about 3 years
    This does not show your file structure so not informative enough.
  • MattSom
    MattSom about 3 years
    could you describe how volumes: ['./web:/app'] works please?
  • MattSom
    MattSom about 3 years
    Could you explain the volumes, why the naming is that what you've provided?
  • lepsch
    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. The volumes then is just sharing this folder into a new one called app inside the container. BTW, app because in the Dockerfile the default WORKDIR is app and everything is copied to /app/ also (volumes in the docker-compose is going to take priority over the copied files).
  • lepsch
    lepsch almost 3 years
    It's nice to keep the COPY * /app/ in the Dockerfile so the Dockerfile is self-contained apart from the docker-compose.
  • MattSom
    MattSom almost 3 years
    Thank 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 used Copy . . but hot realoding did not want to work. I went crazy for days but with this one it works!
  • Máxima Alekz
    Máxima Alekz almost 3 years
    Why are you EXPOSing port from Dockerfile if docker-compose.yaml is already exposing it?
  • lepsch
    lepsch almost 3 years
    @MáximaAlekz just to make the Dockerfile self-contained. I.e. you can docker build... and docker run... it manually and it still works without docker-compose
  • Aderbal Nunes
    Aderbal Nunes about 2 years
    @MattSom By adding the volume, docker compose will sync the host folder with the container folder.