Как запустить 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 "$@"