Am trying to run Postgres, Celery, Redis, and the project itself in docker, but it seems the database is not connecting at all. It tries to connect and fails.
Below is the error it throws after running docker :
travel_dev_container | File "/usr/local/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 656, in __connect
travel_dev_container | connection = pool._invoke_creator(self)
travel_dev_container | File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/strategies.py", line 114, in connect
travel_dev_container | return dialect.connect(*cargs, **cparams)
travel_dev_container | File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 493, in connect
travel_dev_container | return self.dbapi.connect(*cargs, **cparams)
travel_dev_container | File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 127, in connect
travel_dev_container | conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
travel_dev_container | psycopg2.OperationalError: FATAL: the database system is starting up
Am wondering what I have configured wrong, below is my docker-compose.yml
file :
version: "3.7"
services:
redis:
container_name: redis_huxy_tour_dev_container
image: redis
ports:
- "6379:6379"
db:
environment:
POSTGRES_USER: test
POSTGRES_PASSWORD: test
POSTGRES_DB: test
image: postgres:latest
networks:
- default
ports:
- 5405:5432
restart: always
volumes:
- ./postgres-data:/var/lib/postgresql/data
flask_service:
container_name: travel_dev_container
restart: always
image: flask
build:
context: ./
dockerfile: Dockerfile
depends_on:
- redis
- db
ports:
- "5000:5000"
volumes:
- ./:/app
environment:
- FLASK_DEBUG=1
- FLASK_APP=run.py
- DATABASE_URL=postgresql://test:test@db/test
- REDIS_URL=redis://redis:6379/0
- WEATHER_API_KEY=1d4ce67223a53a013fc03ead36137396
- SECRET_KEY=jfdjhfl
then, my Dockerfile
:
FROM python:3.7
RUN mkdir app
COPY . /app/
WORKDIR /app
RUN chmod +x entrypoint.sh
# Install the Python libraries
RUN pip3 install --no-cache-dir -r requirements.txt
EXPOSE 5000
#CMD ["./entrypoint.sh"]
CMD ["bash", "entrypoint.sh"]
finally, the shell script file entrypoint.sh
:
#Run migrations
flask db upgrade
# Run Celery worker
celery -A app.tasks.weather_tasks.celery worker -l info &
# Run Celery beat
celery -A app.tasks.weather_tasks.celery beat -l info &
python run.py
What could be the reason of this error
2
Answers
You need to use a wrapper to test for the database to be ready before running the flask app. Docker Docs titled "Control startup and shutdown order in Compose" has an example script:
Make this script executable
chmod +x wait-for-postgres.sh
and change the flask startup command to be:
command: ["./wait-for-postgres.sh", "db", "python", "app.py"]
In your case, you would add the
command
in theflask_service
section of thedocker-compose.yml
:You can use healthcheck dependencies on your containers.
On your
flask_application
container, under dependencies, use:Now you must implement a way to determine when postgres is healthy.
To do that, you can run a healthcheck test command on your
db
container:In case you are getting some error like
FATAL: role "root" does not exist
, make use of this healthcheck command instead, and ensure your environment variables are set accordingly:Your
flask_application
container will now not start until postgres is ready