'django_1 | no port[s] to connect to' после запуска docker-compose up
Я новичок в docker, и написал контейнерное приложение django и приложение react. Когда я запускаю docker-compose up
, я получаю странную, постоянную ошибку, что django не имеет порта(ов) для подключения. Запуск сервера со стороны react и python работает.
Frontend dockerfile:
COPY ./react_app/package.json .
RUN apk add --no-cache --virtual .gyp \
python \
make \
g++ \
&& npm install \
&& apk del .gyp
COPY ./react_app .
ARG API_SERVER
ENV REACT_APP_API_SERVER=${API_SERVER}
RUN REACT_APP_API_SERVER=${API_SERVER} \
npm run build
WORKDIR /usr/src/app
RUN npm install -g serve
COPY --from=builder /usr/src/app/build ./build
Django Python backend Dockerfile
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
FROM python:3.7.9-slim-stretch
RUN apt-get update && apt-get install -y --no-install-recommends netcat && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*
WORKDIR /usr/src/app
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY ./django_app .
RUN chmod +x /usr/src/app/entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
and the nginx dockerfile
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
WORKDIR /usr/src/app
Django Python backend Dockerfile
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt .
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
FROM python:3.7.9-slim-stretch
RUN apt-get update && apt-get install -y --no-install-recommends netcat && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/src/app/wheels /wheels
COPY --from=builder /usr/src/app/requirements.txt .
RUN pip install --no-cache /wheels/*
WORKDIR /usr/src/app
COPY ./entrypoint.sh /usr/src/app/entrypoint.sh
COPY ./django_app .
RUN chmod +x /usr/src/app/entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
and the nginx dockerfile
FROM nginx:1.19.0-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
WORKDIR /usr/src/app
и докерфайл nginx
FROM nginx:1.19.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d
WORKDIR /usr/src/app
Я не могу найти ничего связанного с этим, и я также новичок в Docker.
Это ошибка netcat. В частности, она возникает, когда вы указываете имя хоста, но не указываете порт при запуске nc
.
Пример:
# nc -z 8.8.8.8
no port[s] to connect to
Затем ваш скрипт точки входа видит, что netcat завершился с ошибкой, и запускает его заново, пока не добьется успеха, чего никогда не произойдет.
Процесс отладки
Я подозревал, что это проблема с netcat, потому что сценарий точки входа выводит "Waiting for postgres...", но не "PostgreSQL started". Однако я не смог заставить netcat выдать ошибку "нет порта".
Поэтому я запустил копию базового образа и вручную установил netcat.
docker run -it python:3.7.9-slim-stretch bash
# in container
apt-get update
apt-get install netcat
Я все еще не мог заставить netcat выдать ошибку. Тогда я скачал исходный код netcat:
# still in container
apt-get source netcat
Затем, вооружившись копией исходного кода netcat, я нашел этот код:
if (argv[optind] == NULL)
bail ("no port[s] to connect to");
Перевод: Если код разбора аргументов, который только что закончил разбор значения хоста, исчерпал аргументы, то выдает ошибку "нет порта для подключения".
Мы можем проверить это, запустив nc внутри контейнера:
root@cc139fd40237:/source/netcat-1.10# nc -z localhost
no port[s] to connect to
Интересно, что Ubuntu имеет другую версию netcat, с другим сообщением об ошибке.
$ nc -z localhost
nc: missing port number
...так вот почему я не смог воспроизвести ошибку netcat вне контейнера!
Надежные сценарии оболочки
В этой строке либо DB_HOST, либо DB_PORT не установлены:
while ! nc -z $DB_HOST $DB_PORT; do
Помимо простого устранения проблемы, это хорошая возможность сделать ваш сценарий более надежным. Если бы вы добавили set -u
в начало вашего сценария оболочки, то вместо этого вы получили бы гораздо более полезное сообщение об ошибке:
Waiting for postgres...
entrypoint.sh: 7: DB_PORT: parameter not set
Вы также можете использовать инструмент shellcheck - в вашем скрипте он рекомендует заключать аргументы в кавычки:
In entrypoint.sh line 6:
while ! nc -z $DB_HOST $DB_PORT; do
^------^ SC2086: Double quote to prevent globbing and word splitting.
^------^ SC2086: Double quote to prevent globbing and word splitting.
Did you mean:
while ! nc -z "$DB_HOST" "$DB_PORT"; do
что также является отличной идеей.