Как отправить несколько образов Docker, созданных django-cookiecutter, в Heroku?

Я разработал локально, используя Docker и cookiecutter-django.

Cookiecutter-django создает несколько файлов Dockerfile в каталоге «compose».

Сейчас я пытаюсь отправить проект на Heroku.
Однако heroku container:push web вернет No images to push.

Если я попробую ту же команду в подкаталоге каталога компоновки, она в конечном итоге сломается — вероятно, из-за попытки отправить только частичные файлы докеров.

Как мне настроить и запустить это на Heroku, используя преимущества контейнеров Heroku?

В этой статье от Heroku говорится, что я могу отправлять использование нескольких изображений путем переименования файлов Docker, но я не уверен, как выяснить, какие из этих файлов Docker, сгенерированных cookiecutter, относятся к какому типу процесса.

docker images вернет:

REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
<none>                                        <none>              16e570f295a7        10 minutes ago      318MB
luup_celeryworker                           latest              bd7ff7e5eb10        2 hours ago         531MB
luup_django                                 latest              bd7ff7e5eb10        2 hours ago         531MB
luup_celerybeat                             latest              bd7ff7e5eb10        2 hours ago         531MB
luup_postgres                               latest              e50eb7b8a704        2 hours ago         287MB
registry.heroku.com/fierce-forest-57627/web   latest              27690b3e49d4        16 hours ago        766MB
python                                        3.6-alpine          c3a4a35c9244        22 hours ago        90MB

Это Dockerfile, созданный cookiecutter. Это DF в compose/production/django. Существуют и другие DF — для caddy, postgres, а также DF для локальных.

FROM python:3.6-alpine

ENV PYTHONUNBUFFERED 1

RUN apk update \
  # psycopg2 dependencies
  && apk add --virtual build-deps gcc python3-dev musl-dev \
  && apk add postgresql-dev \
  # Pillow dependencies
  && apk add jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
  # CFFI dependencies
  && apk add libffi-dev openssl-dev py-cffi

RUN addgroup -S django \
    && adduser -S -G django django

# Requirements have to be pulled and installed here, otherwise caching won't work
COPY ./requirements /requirements
RUN pip install --no-cache-dir -r /requirements/production.txt \
    && rm -rf /requirements

COPY ./compose/production/django/gunicorn.sh /gunicorn.sh
RUN sed -i 's/\r//' /gunicorn.sh
RUN chmod +x /gunicorn.sh
RUN chown django /gunicorn.sh

COPY ./compose/production/django/entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
RUN chown django /entrypoint.sh

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

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

COPY . /app

RUN chown -R django /app

USER django

WORKDIR /app

ENTRYPOINT ["/entrypoint.sh"]

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация

Редактировать - добавление дерева:

примечание: я переименовал Dockerfiles в Dockerfile.processtype в соответствии с инструкциями Heroku здесь — хотя я больше не отправляю несколько изображений. Как видно из дерева, я также переместил копию Dockerfile.django и Dockerfile.local в корень проекта, так как именно там он должен быть, чтобы Heroku container:push processtype --recursive.

├── Dockerfile.django
├── Dockerfile.local
├── LICENSE
├── Procfile
├── README.rst
├── compose
│   ├── local
│   │   └── django
│   │       ├── celery
│   │       │   ├── beat
│   │       │   │   └── start.sh
│   │       │   └── worker
│   │       │       └── start.sh
│   │       └── start.sh
│   └── production
│       ├── caddy
│       │   ├── Caddyfile
│       │   └── Dockerfile.caddy
│       ├── django
│       │   ├── Dockerfile.django
│       │   ├── celery
│       │   │   ├── beat
│       │   │   │   └── start.sh
│       │   │   └── worker
│       │   │       └── start.sh
│       │   ├── entrypoint.sh
│       │   └── gunicorn.sh
│       └── postgres
│           ├── Dockerfile.postgres
│           └── maintenance
│               ├── _sourced
│               │   ├── constants.sh
│               │   ├── countdown.sh
│               │   ├── messages.sh
│               │   └── yes_no.sh
│               ├── backup
│               ├── backups
│               └── restore
├── config
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   ├── __init__.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-35.pyc
│   │   │   ├── __init__.cpython-36.pyc
│   │   │   ├── base.cpython-35.pyc
│   │   │   ├── base.cpython-36.pyc
│   │   │   ├── local.cpython-35.pyc
│   │   │   ├── local.cpython-36.pyc
│   │   │   └── production.cpython-36.pyc
│   │   ├── base.py
│   │   ├── local.py
│   │   ├── production.py
│   │   └── test.py
│   ├── urls.py
│   └── wsgi.py
├── docs
│   ├── Makefile
│   ├── __init__.py
│   ├── conf.py
│   ├── deploy.rst
│   ├── docker_ec2.rst
│   ├── index.rst
│   ├── install.rst
│   └── make.bat
├── heroku.yml
├── local.yml
├── locale
│   └── README.rst
├── lurnup
│   ├── __init__.py
│   ├── __pycache__
│   │   └── __init__.cpython-36.pyc
│   ├── contrib
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   └── __init__.cpython-36.pyc
│   │   └── sites
│   │       ├── __init__.py
│   │       ├── __pycache__
│   │       │   └── __init__.cpython-36.pyc
│   │       └── migrations
│   │           ├── 0001_initial.py
│   │           ├── 0002_alter_domain_unique.py
│   │           ├── 0003_set_site_domain_and_name.py
│   │           ├── __init__.py
│   │           └── __pycache__
│   │               ├── 0001_initial.cpython-36.pyc
│   │               ├── 0002_alter_domain_unique.cpython-36.pyc
│   │               ├── 0003_set_site_domain_and_name.cpython-36.pyc
│   │               └── __init__.cpython-36.pyc
│   ├── static
│   │   ├── css
│   │   │   └── project.css
│   │   ├── fonts
│   │   ├── images
│   │   │   └── favicon.ico
│   │   ├── js
│   │   │   └── project.js
│   │   └── sass
│   │       ├── custom_bootstrap_vars.scss
│   │       └── project.scss
│   ├── taskapp
│   │   ├── __init__.py
│   │   ├── __pycache__
│   │   │   ├── __init__.cpython-36.pyc
│   │   │   └── celery.cpython-36.pyc
│   │   └── celery.py
│   ├── templates
│   │   ├── 403_csrf.html
│   │   ├── 404.html
│   │   ├── 500.html
│   │   ├── account
│   │   │   ├── account_inactive.html
│   │   │   ├── base.html
│   │   │   ├── email.html
│   │   │   ├── email_confirm.html
│   │   │   ├── login.html
│   │   │   ├── logout.html
│   │   │   ├── password_change.html
│   │   │   ├── password_reset.html
│   │   │   ├── password_reset_done.html
│   │   │   ├── password_reset_from_key.html
│   │   │   ├── password_reset_from_key_done.html
│   │   │   ├── password_set.html
│   │   │   ├── signup.html
│   │   │   ├── signup_closed.html
│   │   │   ├── verification_sent.html
│   │   │   └── verified_email_required.html
│   │   ├── base.html
│   │   ├── pages
│   │   │   ├── about.html
│   │   │   └── home.html
│   │   └── users
│   │       ├── user_detail.html
│   │       ├── user_form.html
│   │       └── user_list.html
│   └── users
│       ├── __init__.py
│       ├── __pycache__
│       │   ├── __init__.cpython-36.pyc
│       │   ├── adapters.cpython-36.pyc
│       │   ├── admin.cpython-36.pyc
│       │   ├── apps.cpython-36.pyc
│       │   ├── models.cpython-36.pyc
│       │   ├── urls.cpython-36.pyc
│       │   └── views.cpython-36.pyc
│       ├── adapters.py
│       ├── admin.py
│       ├── apps.py
│       ├── migrations
│       │   ├── 0001_initial.py
│       │   ├── __init__.py
│       │   └── __pycache__
│       │       ├── 0001_initial.cpython-36.pyc
│       │       └── __init__.cpython-36.pyc
│       ├── models.py
│       ├── tests
│       │   ├── __init__.py
│       │   ├── factories.py
│       │   ├── test_admin.py
│       │   ├── test_models.py
│       │   ├── test_urls.py
│       │   └── test_views.py
│       ├── urls.py
│       └── views.py
├── manage.py
├── merge_production_dotenvs_in_dotenv.py
├── production.yml
├── pytest.ini
├── requirements
│   ├── base.txt
│   ├── local.txt
│   └── production.txt

person Jay Jung    schedule 21.03.2018    source источник


Ответы (1)


Cookiecutter-django предоставляет стандартную конфигурацию создания докеров, которую вы можете использовать на нескольких хостингах с полной поддержкой Docker.

Однако Heroku поддерживает Docker с некоторыми ограничениями. Например, порт для сервера WSGI запрограммирован на 5000, где Heroku требует использовать переменную окружения $PORT.

Они НЕ учитываются в cookiecutter-django, поэтому вам придется кое-что изменить:

  • Я бы начал с изображений в compose/production/django и проигнорировал БД (предоставленную через add- on) и Caddy (вместо этого см. здесь).
  • Измените порт Gunicorn с 5000 по $PORT
  • Код для получения DATABASE_URL в entrypoint.sh, вероятно, не нужен.
  • И последнее, но не менее важное: создайте файл heroku.yml, чтобы указывал на DF, который вы хотите использовать.
  • С помощью docker-compose вы можете повторно использовать один и тот же файл Dockerfile и изменить точку входа, но я не думаю, что это возможно с Heroku. Возможно, вам потребуется создать дубликат веб-файла Dockerfile и изменить его для ваших динамометров Celery.

Я пробовал Docker на Heroku, но не с настройкой cookiecutter-django. Способ Heroku недостаточно стандартен, IMO, это что-то среднее между чистым Heroku и голым Docker.

Надеюсь, это поможет!

person Bruno A.    schedule 24.03.2018
comment
Я игнорирую Caddy, но воздерживаюсь от указаний SSL-сертификата. так как кажется, что они хотят, чтобы я обновился до платного динамометрического стенда - что я рассмотрю, если есть какой-либо признак того, что я могу заставить это работать. Наконец, я пробовал несколько способов создать файл heroku.yml, но получаю ошибки: invalid Compose File because: Unsuppoarted config option for build: 'docker'. На данный момент я переместил Dockerfiles cookiecutter в свой корень и вместо этого heroku container:push dockerfile --recursive использую их. Он поднимает контейнер на Heroku, но опять же, меня остановила проблема с Postgres. - person Jay Jung; 25.03.2018