Home > Back-end >  Docker | Flask Redis | Flask not launching
Docker | Flask Redis | Flask not launching

Time:11-15

I'm trying to containerize a simple python app which stores amount of time a site has been visited. Redis seems to work but Flask is refusing to lunch. I get this error on running docker-compose up --build :

web-fe_1 exited with code 0

Below are my Dockerfile, docker-compose.yml & app.py

FROM python:3.6-alpine
ENV FLASK_APP app.py
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD [ "flask","run","--host=0.0.0.0","--port=5000"]
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

version: "3.5"
services:
  web-fe:
    build: .
    command: python app.py
    ports:
      - target: 5000
        published: 5000
    networks:
      - counter-net
    volumes:
      - type: volume
        source: counter-vol
        target: /code
  redis:
    image: "redis:alpine"
    networks:
      counter-net:

networks:
  counter-net:

volumes:
  counter-vol:
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

import os

from flask import Flask
from flask_redis import FlaskRedis

app = Flask(__name__)
app.config['REDIS_URL'] = 'redis://redis:6379/0'

redis = FlaskRedis(app)


@app.route('/')
def counter():
    return '{0} {1} {2}'.format('Hello! You have visited me:',str(redis.incr('web2_counter')),' times.')
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

This is almost identical to Poulton's counter-app on https://github.com/nigelpoulton/counter-app .. with only difference that my app.py has no call function (if__name__== “main ).. And the problem is that I would like to make this work without modification to app.py and solve this only through Dockerfile / docker-compose

CodePudding user response:

About your docker-compose.yml defining networks is not necessary as bridge network is the default already. You can update your docker-compose.yml to:

version: "3.5"
services:
  web-fe:
    build: .
    command: python app.py
    ports:
      - target: 5000
        published: 5000
    volumes:
      - type: volume
        source: counter-vol
        target: /code
  redis:
    image: "redis:alpine"

volumes:
  counter-vol:

And I geuss changing line app.config['REDIS_URL'] = 'redis://redis:6379/0' to app.config['REDIS_URL'] = 'http://redis:6379'

CodePudding user response:

You're missing the final 2 lines of his app.py which makes the app listen for connections. When you don't have those 2 lines, your app exits immediately and your container stops.

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

I'm not very good with python. Can you just leave out the 'if' line and keep the 'app.run' line so it always runs?

CodePudding user response:

In your Dockerfile you specify a CMD that tells the container to flask run your application. That reads in the app.py file (from $FLASK_APP) and launches a Web server. In the docker-compose.yml file, though, you override this with command: python app.py which just runs the Python file, without the Flask wrapper.

One way to address this is with @HansKillian's approach to make app.py call app.run() itself, but it'd be easier to strip out all of the unnecessary parts from the docker-compose.yml file. Especially deleting the command: override should resolve this.

version: "3.5"
services:
  web-fe:
    build: .
    # command: python app.py  <-- CMD in the Dockerfile
    ports:
      - target: 5000
        published: 5000
    # networks:               <-- Compose provides a "default" network
    #   - counter-net
    # volumes:                <-- Code is in the image and does not need
    #   - type: volume            to be hidden with a volume
    #     source: counter-vol
    #     target: /code
  redis:
    image: "redis:alpine"
    # networks:               <-- Compose provides a "default" network
    #   counter-net:

# networks:                   <-- Unused
#   counter-net:

# volumes:                    <-- Unused
#   counter-vol:

(Compose automatically provides a network named default for you, so you don't usually need to specify networks:. The volumes: declaration mounts a Docker named volume over your application code, so you're not actually running the code in the image. This particular setup will apparently work the first time but ignore any changes if you docker-compose build the image again.)

  • Related