Как запустить Django в контейнере Docker с удаленной базой данных PostgreSQL?

Я пытаюсь собрать контейнер Django, который подключается к удаленной базе данных PostgreSQL с sslmode=require на порту 25060. Во время сборки все выглядит нормально, и контейнер запускается вместе со своими аналогами. Однако, когда я пытаюсь migrate создать модели Django, возникает ошибка :

$ docker-compose exec django python manage.py migrate
  
  [...]
  psycopg2.OperationalError: could not connect to server: Connection timed out
Is the server running on host "db-postgresql-fra1-controller-do-user-12355871-0.b.db.ondigitalocean.com" (164.92.230.148) and accepting
TCP/IP connections on port 25060?

Я открыл порт 25060 в docker-compose.yml и открыл порт в хосте Docker с помощью sudo ufw allow 25060, но он продолжает выдавать то же сообщение. Параллельно, контейнер рабочего Celery выводит:

Waiting for PostgreSQL to become available...

В конце концов, я отключил команду /start, которая ждет, пока база данных будет готова перед запуском контейнера, просто для проверки, но ничего не изменилось.

Как я могу это сделать?

settings.py

DATABASES = {
    "default": {
        "ENGINE": 'django.db.backends.postgresql',
        "NAME": os.environ.get("PSQL_DATABASE"),
        "USER": os.environ.get("PSQL_USER"),
        "PASSWORD": os.environ.get("PSQL_PASSWORD"),
        "HOST": os.environ.get("PSQL_HOST"),
        "PORT": os.environ.get("PSQL_PORT"),
        "OPTIONS": {'sslmode': 'require'},
    }
}

.env

PSQL_DATABASE=defaultdb
PSQL_USER=username
PSQL_PASSWORD=password
PSQL_HOST=db-postgresql-fra1-controller-do-user.db.ondigitalocean.com
PSQL_PORT=25060

docker-compose.yml

version: '3.8'

services:
  django:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: controller
    command: /start
    volumes:
      - .:/app
    ports:
      - 8011:8000
      - 25060:25060
    env_file:
      - controller/.env
    depends_on:
      - redis

  redis:
    container_name: controller_redis
    image: redis

  celery_worker:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: controller_worker
    command: /start-celeryworker
    volumes:
      - .:/app
    env_file:
      - controller/.env
    depends_on:
      - redis

  celery_beat:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: controller_beat
    command: /start-celerybeat
    volumes:
      - .:/app
    env_file:
      - controller/.env
    depends_on:
      - redis

  flower:
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: controller_flower
    command: /start-flower
    volumes:
      - .:/app
    env_file:
      - controller/.env
    ports:
      - 5558:5555
    depends_on:
      - redis

Dockerfile

FROM python:3.10

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

RUN apt-get update \
  && apt-get install -y build-essential \
  && apt-get install -y libpq-dev \
  && apt-get install -y gettext \
  && apt-get install -y git \
  && apt-get install -y openssh-client \
  && apt-get install -y libcurl4-openssl-dev libssl-dev \
  && apt-get install -y python3-requests \
  && apt-get install -y cargo \
  && apt-get install -y procps telnet \
  && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
  && rm -rf /var/lib/apt/lists/*

# Requirements are installed here to ensure they will be cached.

RUN mkdir logs && cd logs && touch flat_line.log && touch json.log

COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt

COPY ./compose/local/django/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint

COPY ./compose/local/django/start /start
RUN sed -i 's/\r$//g' /start
RUN chmod +x /start

COPY ./compose/local/django/celery/worker/start /start-celeryworker
RUN sed -i 's/\r$//g' /start-celeryworker
RUN chmod +x /start-celeryworker

COPY ./compose/local/django/celery/beat/start /start-celerybeat
RUN sed -i 's/\r$//g' /start-celerybeat
RUN chmod +x /start-celerybeat

COPY ./compose/local/django/celery/flower/start /start-flower
RUN sed -i 's/\r$//g' /start-flower
RUN chmod +x /start-flower

WORKDIR /app

ENTRYPOINT ["/entrypoint"]

точка входа

#!/bin/bash

# if any of the commands in your code fails for any reason, the entire script fails
set -o errexit
# fail exit if one of your pipe command fails
set -o pipefail
# exits if any of your variables is not set
set -o nounset

postgres_ready() {
python << END
import sys

import psycopg2

try:
    psycopg2.connect(
        dbname="${PSQL_DATABASE}",
        user="${PSQL_USER}",
        password="${PSQL_PASSWORD}",
        host="${PSQL_HOST}",
        port="${PSQL_PORT}",
        sslmode="require",
    )
except psycopg2.OperationalError:
    sys.exit(-1)
sys.exit(0)

END
}
until postgres_ready; do
  >&2 echo 'Waiting for PostgreSQL to become available...'
  sleep 1
done
>&2 echo 'PostgreSQL is available'

exec "$@"
Вернуться на верх