首页 > 解决方案 > 在尝试控制 Docker Compose 中的启动和关闭顺序的脚本中找不到 psql

问题描述

我正在尝试确保我的 Django 应用程序等待我的 Postgres 数据库启动,所以我没有收到此错误django.db.utils.OperationalError: FATAL: the database system is starting up,我已阅读此https://docs.docker.com/compose/startup-order/和此处是我到目前为止所拥有的

docker-compose.yml

version: "3.9"

services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
  backend:
    build: ./backend
    command: python3 manage.py runserver
    volumes:
      - ./backend:/code
    ports:
      - "8000:8000"
    command: ["./wait-for-it.sh", "db", "bash", "entrypoint.sh"]
    depends_on:
      - db

wait-for-it.sh

#!/bin/sh
# wait-for-it.sh

set -e
  
host="$1"
shift
cmd="$@"
  
# postgres

until PGPASSWORD=$DB_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

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 && \
    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

编辑#1:这是我的目录结构根目录 在此处输入图像描述 后端目录 在此处输入图像描述

标签: djangopostgresqldockerdocker-compose

解决方案


您正在尝试组合几种不同的解决方案。

首先,如果您使用pg_isready,则不需要任何自定义wait-for-it.sh脚本,因为pg_isready效果很好。所以只需删除您的wait-for-it.sh文件。

此外,如果您在 中使用healthcheckdocker-compose.yml则无需在运行entrypoint.sh. 但是您需要在depends_on部分中添加条件。因此,将您的更改docker-compose.yml为以下内容:

version: "3.9"

services:
  db:
    image: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      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: entrypoint.sh
    depends_on:
      db:
        condition: service_healthy

请注意,我还在部分中更改了test命令并在图像healthcheck中首先删除。commandbackend


推荐阅读