Docker-compose работает, просто Docker с использованием Dockerfile — нет. Почему?

#docker #flask #docker-compose #gunicorn #google-cloud-run

#docker #flask #docker-compose #gunicorn #google-cloud-run

Вопрос:

Я ни в коем случае не эксперт по Docker, поэтому, возможно, у него есть простое решение. У меня такая «странная» проблема: долгое время в локальной разработке я использовал Docker-compose для своего сервера Python Flask gunicorn с довольно простой настройкой, мой docker-compose.yaml выглядит так:

 version: '2'

services: 
    website:
        build: .
        command: >
            gunicorn -b 0.0.0.0:443
            --reload
            --workers=2
            --timeout 0
            --certfile=scert.crt
            --keyfile=skey.key
            db_app.app:create_app()
        environment: 
            PYTHONUNBUFFERED: 'true'
        volumes: 
            - '.:/db_app'
        ports: 
            - '443:443'
  

Обычно я запускал его с docker-compose up --build помощью обновления локальных файлов, автоматически перестраивал сервер и так далее — отлично. Клиентское приложение подключено без каких-либо проблем. Но теперь мне нужно, чтобы он работал только с Dockerfile (размещая его в Google Cloud Run). Я придумал это:

 FROM python:3.8-slim

ENV PYTHONUNBUFFERED True

ENV INSTALL_PATH /db_app
RUN mkdir -p ${INSTALL_PATH}

WORKDIR ${INSTALL_PATH}

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

COPY . .

EXPOSE 443
CMD exec gunicorn --bind 0.0.0.0:443 --reload --workers=2 --threads 8 --timeout 0 --certfile=scert.crt --keyfile=skey.key db_app.app:create_app
  

Он строится нормально, работает нормально, но.. всякий раз, когда я пытаюсь подключиться к своему клиентскому приложению, я получаю 503. Это происходит как при запуске Google Cloud, так и локально, где я просто не вижу никаких выходных данных с сервера, даже если он запускается (при запуске с docker run containername помощью so он выполняет dockerfile, а не с помощью docker-compose (который работает просто отлично)). Что я сделал не так?

Дополнительная информация:

Результат docker run containername ls -l /db_app

 total 28
drwxr-xr-x 3 root root 4096 Sep 17 16:12 config
-rw-r--r-- 1 root root  496 Nov 14 11:13 docker-compose.yaml
drwxr-xr-x 2 root root 4096 Sep 16 20:34 instance
-rw-r--r-- 1 root root  252 Oct 11 15:37 requirements.txt
-rwxrwxrwx 1 root root 1456 Oct 15 14:09 scert.crt
-rwxrwxrwx 1 root root 1704 Oct 15 14:09 skey.key
drwxr-xr-x 3 root root 4096 Oct 27 18:05 db_app
  

Комментарии:

1. Не могли бы вы опубликовать результат docker run containername ls -l /db_app ?

2. @emi опубликовал это.

3. Это правильно? Я вижу, что есть /db_app/db_app каталог.

4. Требуется ли вашему приложению какой-либо экземпляр базы данных?

Ответ №1:

Отвечая на мой собственный вопрос, потому что я понял, что было не так.

По-видимому, Google Cloud Run сам заботится о безопасности, он не хочет, чтобы мы использовали какие-либо самозаверяющие или иным образом сгенерированные сертификаты с выводом экземпляра контейнера. На всякий случай я также использовал порт по умолчанию. Удаление строк об этом из команды Gunicorn заставило ее работать и правильно реагировать на клиента (который по-прежнему подключается по https).

Итак, это единственное изменение, которое было необходимо для Dockerfile:

 CMD exec gunicorn --bind 0.0.0.0:8080 --reload --workers=1 --threads 8 --timeout 0 "db_app.app:create_app()"
  

Суть в том, что Google использует для этого собственные сертификаты и не нуждается в наших.