我试图在docker中运行Postgres、Celery、Redis和项目本身,但数据库似乎根本没有连接。它尝试连接但失败了。
以下是它在运行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
我想知道我配置错了什么,下面是我的docker-compose.yml
文件:
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
然后,我的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"]
最后,shell脚本文件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
出现此错误的原因可能是什么
您可以在容器上使用healthcheck依赖项。
在您的flask_application
容器上,在依赖项下,使用:
depends_on:
db:
condition: service_healthy
现在,您必须实现一种方法来确定postgres何时是健康的。为此,您可以在db
容器上运行healthcheck测试命令:
db:
healthcheck:
test: ["CMD", "pg_isready", "-q"]
如果出现类似FATAL: role "root" does not exist
的错误,请使用此healthcheck命令,并确保相应地设置环境变量:
db:
healthcheck:
test: [ "CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}" ]
在postgres准备好之前,您的flask_application
容器现在不会启动
在运行flask应用程序之前,您需要使用包装器来测试数据库是否准备就绪。Docker文档标题为";控制Compose"中的启动和关闭顺序;有一个示例脚本:
#!/bin/sh
# wait-for-postgres.sh
set -e
host="$1"
shift
cmd="$@"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c 'q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
使此脚本可执行chmod +x wait-for-postgres.sh
并将烧瓶启动命令更改为:
command: ["./wait-for-postgres.sh", "db", "python", "app.py"]
在您的情况下,您可以在docker-compose.yml
:的flask_service
部分添加command
flask_service:
...
command: ["./wait-for-postgres.sh", "db", "bash", "entrypoint.sh"]