nekeal
nekeal

Reputation: 23

Release phase with container registry on heroku runs container

I created simple project in Django with docker. According to heroku's documentation about release phase with container registry (https://devcenter.heroku.com/articles/container-registry-and-runtime#release-phase) I created a new app with postgres addon. To deploy app with docker I executed following commands:

heroku container:push web
heroku container:push release
heroku container:release web release

But after last command my terminal is blocked and it looks like release phase actually run a container.

Releasing images web,release to teleagh... done
Running release command...
[2019-12-30 21:22:00 +0000] [17] [INFO] Starting gunicorn 19.9.0
[2019-12-30 21:22:00 +0000] [17] [INFO] Listening at: http://0.0.0.0:5519 (17)
[2019-12-30 21:22:00 +0000] [17] [INFO] Using worker: sync
[2019-12-30 21:22:00 +0000] [27] [INFO] Booting worker with pid: 27

My goal is tu run django migrations before release. I would really apreciate any help.

Procfile:

release: python manage.py migrate

Dockerfile:

FROM python:3.7-slim

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD gunicorn --bind 0.0.0.0:$PORT teleagh.wsgi 

Upvotes: 1

Views: 831

Answers (2)

David
David

Reputation: 14404

You can add a release phase to the heroku.yml file.

ex.

build:
  ...
release:
  command:
    - rake db:migrate
run:
  web: bundle exec puma -C config/puma.rb

Source

Upvotes: 0

artembo
artembo

Reputation: 640

Procfile does not make effect when container deploy is used in heroku. If you want to set release phase command I can suggest two options that I have tested a lot:

1. Create dedicated Dockerfile for each phase with extensions matching the phase name.

Dockerfile.web

FROM python:3.7-slim

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD gunicorn --bind 0.0.0.0:$PORT teleagh.wsgi 

Dockerfile.release

FROM python:3.7-slim

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD python manage.py migrate

The deploying process will be looking the same like yours with one exception — push command must have additional argument --recursive. Moreover it is possible to push all containers in one command:

heroku container:push web release --recursive
heroku container:release web release

2. Create a bash script to detect what phase is running in the container at the moment.

start.sh

#!/bin/bash

if [ -z "$SSH_CLIENT" ] && [ -n "$HEROKU_EXEC_URL" ];
then
    source <(curl --fail --retry 3 -sSL "$HEROKU_EXEC_URL")
fi

if [[ "$DYNO" =~ ^release.* ]];
then
    set -e
    python3 manage.py migrate
else
    exec gunicorn teleagh.wsgi  -b 0.0.0.0:${PORT} --reload --access-logfile -
fi

Then the only Dockerfile will be looking like:

FROM python:3.7-slim

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT=8000
WORKDIR /app
ADD requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y curl
ADD . ./
RUN python manage.py collectstatic --noinput
CMD ./start.sh 

Hope this will be helpful

Upvotes: 1

Related Questions