Docker Compose配置启停顺序时psql未找到及Django连Postgres报错问题
报错原因与解决步骤
psql未找到的核心原因是backend容器的Alpine运行环境中没有安装PostgreSQL客户端工具包,你之前安装的postgresql-dev属于编译Python PostgreSQL依赖的构建依赖,构建完成后已经通过apk purge命令删除,运行时没有留存psql可执行文件。按以下步骤修改即可解决:
- 第一步:修改backend目录下的Dockerfile,新增PostgreSQL客户端安装
将postgresql-client加入到永久留存的运行依赖中,修改后的Dockerfile如下:
# syntax=docker/dockerfile:1 FROM python:3.9.6-alpine3.14 ENV PYTHONUNBUFFERED=1 WORKDIR /code COPY requirements.txt /code/ RUN \ apk add --no-cache postgresql-libs postgresql-client && \ apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev && \ python3 -m pip install -r requirements.txt --no-cache-dir && \ apk --purge del .build-deps COPY . /code/ RUN chmod u+x ./wait-for-it.sh
- 第二步:修正docker-compose.yml的配置错误
你当前配置存在两处冗余/错误:backend服务重复定义了command字段(后定义的会覆盖前定义的)、执行脚本时调用了Alpine默认未安装的bash,同时可以完善启动依赖规则,等待db健康检查通过后再启动backend,修改后的配置如下:
version: "3.9" services: db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"] interval: 5s timeout: 5s retries: 5 environment: - POSTGRES_DB=${DB_NAME} - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} backend: build: ./backend volumes: - ./backend:/code ports: - "8000:8000" command: ["./wait-for-it.sh", "db", "sh", "entrypoint.sh"] depends_on: db: condition: service_healthy environment: - DB_NAME=${DB_NAME} - DB_USER=${DB_USER} - DB_PASSWORD=${DB_PASSWORD}
- 第三步:修正wait-for-it.sh的硬编码问题
你当前脚本硬写了连接用户为postgres,和你环境变量中自定义的DB_USER可能不一致,会导致后续认证失败,修改后的脚本如下:
#!/bin/sh # wait-for-it.sh set -e host="$1" shift cmd="$@" until PGPASSWORD=$DB_PASSWORD psql -h "$host" -U "$DB_USER" -d "$DB_NAME" -c '\q'; do >&2 echo "Postgres is unavailable - sleeping" sleep 1 done >&2 echo "Postgres is up - executing command" exec $cmd
修改完成后执行docker-compose build backend重新构建镜像,再启动服务即可解决报错,同时实现Django等待Postgres完全启动后再运行的需求。
内容的提问来源于stack exchange,提问作者A.K.M. Adib
相关产品推荐
相关产品推荐

