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"]
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:
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.')
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
3
Answers
About your
docker-compose.yml
defining networks is not necessary asbridge
network is the default already. You can update yourdocker-compose.yml
to:And I geuss changing line
app.config['REDIS_URL'] = 'redis://redis:6379/0'
toapp.config['REDIS_URL'] = 'http://redis:6379'
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.
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?
In your Dockerfile you specify a
CMD
that tells the container toflask run
your application. That reads in theapp.py
file (from$FLASK_APP
) and launches a Web server. In thedocker-compose.yml
file, though, you override this withcommand: 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
callapp.run()
itself, but it’d be easier to strip out all of the unnecessary parts from thedocker-compose.yml
file. Especially deleting thecommand:
override should resolve this.(Compose automatically provides a network named
default
for you, so you don’t usually need to specifynetworks:
. Thevolumes:
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 youdocker-compose build
the image again.)