Add Heroku config

experiments
Karl Hobley 2020-09-11 09:34:30 +01:00
rodzic a123cace75
commit b3295a6b4b
5 zmienionych plików z 72 dodań i 80 usunięć

Wyświetl plik

@ -1,72 +1,69 @@
FROM python:3.7-slim
FROM node:14 as frontend
# Install packages needed to run your application (not build deps):
# We need to recreate the /usr/share/man/man{1..8} directories first because
# they were clobbered by a parent image.
RUN set -ex \
&& RUN_DEPS=" \
libexpat1 \
libjpeg62-turbo \
libpcre3 \
libpq5 \
mime-support \
postgresql-client \
procps \
zlib1g \
" \
&& seq 1 8 | xargs -I{} mkdir -p /usr/share/man/man{} \
&& apt-get update && apt-get install -y --no-install-recommends $RUN_DEPS \
&& rm -rf /var/lib/apt/lists/*
# TODO: Leaving this here in case we ever need it for experiments in the future
# COPY ./wagtail-localize /wagtail-localize
# RUN cd /wagtail-localize && make build
ADD requirements/ /requirements/
RUN set -ex \
&& BUILD_DEPS=" \
build-essential \
git \
libexpat1-dev \
libjpeg62-turbo-dev \
libpcre3-dev \
libpq-dev \
zlib1g-dev \
" \
&& apt-get update && apt-get install -y --no-install-recommends $BUILD_DEPS \
&& python3.7 -m venv /venv \
&& /venv/bin/pip install -U pip \
&& /venv/bin/pip install --no-cache-dir -r /requirements/production.txt \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $BUILD_DEPS \
&& rm -rf /var/lib/apt/lists/*
# We use Debian images because they are considered more stable than the alpine
# ones becase they use a different C compiler. Debian images also come with
# all useful packages required for image manipulation out of the box. They
# however weight a lot, approx. up to 1.5GiB per built image.
FROM python:3.7-stretch as backend
RUN mkdir /code/
WORKDIR /code/
ADD . /code/
RUN useradd bakerydemo
RUN mkdir -p /home/bakerydemo
RUN chown bakerydemo /home/bakerydemo
WORKDIR /app
# Set default environment variables. They are used at build time and runtime.
# If you specify your own environment variables on Heroku or Dokku, they will
# override the ones set here. The ones below serve as sane defaults only.
# * PATH - Make sure that Poetry is on the PATH
# * PYTHONUNBUFFERED - This is useful so Python does not hold any messages
# from being output.
# https://docs.python.org/3.8/using/cmdline.html#envvar-PYTHONUNBUFFERED
# https://docs.python.org/3.8/using/cmdline.html#cmdoption-u
# * PYTHONPATH - enables use of django-admin command.
# * DJANGO_SETTINGS_MODULE - default settings used in the container.
# * PORT - default port used. Please match with EXPOSE so it works on Dokku.
# Heroku will ignore EXPOSE and only set PORT variable. PORT variable is
# read/used by Gunicorn.
# * WEB_CONCURRENCY - number of workers used by Gunicorn. The variable is
# read by Gunicorn.
# * GUNICORN_CMD_ARGS - additional arguments to be passed to Gunicorn. This
# variable is read by Gunicorn
ENV PYTHONUNBUFFERED=1 \
PYTHONPATH=/app \
DJANGO_SETTINGS_MODULE=bakerydemo.settings.production \
PORT=8000 \
HOME=/app \
WEB_CONCURRENCY=3 \
GUNICORN_CMD_ARGS="-c gunicorn-conf.py --max-requests 1200 --access-logfile - --timeout 25"
# Port exposed by this container. Should default to the port used by your WSGI
# server (Gunicorn). This is read by Dokku only. Heroku will ignore this.
EXPOSE 8000
# Add custom environment variables needed by Django or your settings file here:
ENV DJANGO_SETTINGS_MODULE=bakerydemo.settings.production DJANGO_DEBUG=off
# Copy application code.
COPY --chown=bakerydemo . .
# TODO See above COPY --chown=bakerydemo --from=frontend /wagtail-localize ./wagtail-localize
# Tell uWSGI where to find your wsgi file:
ENV UWSGI_WSGI_FILE=bakerydemo/wsgi.py
# Install your app's Python requirements.
RUN pip install -r requirements/production.txt
# Base uWSGI configuration (you shouldn't need to change these):
ENV UWSGI_VIRTUALENV=/venv UWSGI_HTTP=:8000 UWSGI_MASTER=1 UWSGI_HTTP_AUTO_CHUNKED=1 UWSGI_HTTP_KEEPALIVE=1 UWSGI_UID=1000 UWSGI_GID=2000 UWSGI_LAZY_APPS=1 UWSGI_WSGI_ENV_BEHAVIOR=holy
# Collect static. This command will move static files from application
# directories and "static_compiled" folder to the main static directory that
# will be served by the WSGI server.
RUN SECRET_KEY=none django-admin collectstatic --noinput --clear
# Number of uWSGI workers and threads per worker (customize as needed):
ENV UWSGI_WORKERS=2 UWSGI_THREADS=4
# Don't use the root user as it's an anti-pattern and Heroku does not run
# containers as root either.
# https://devcenter.heroku.com/articles/container-registry-and-runtime#dockerfile-commands-and-runtime
USER bakerydemo
# uWSGI uploaded media file serving configuration:
ENV UWSGI_STATIC_MAP="/media/=/code/bakerydemo/media/"
ENTRYPOINT ["/app/docker-entrypoint.sh"]
# Call collectstatic with dummy environment variables:
RUN DATABASE_URL=postgres://none REDIS_URL=none /venv/bin/python manage.py collectstatic --noinput
# make sure static files are writable by uWSGI process
RUN mkdir -p /code/bakerydemo/media/images && chown -R 1000:2000 /code/bakerydemo/media
# mark the destination for images as a volume
VOLUME ["/code/bakerydemo/media/images/"]
# start uWSGI, using a wrapper script to allow us to easily add more commands to container startup:
ENTRYPOINT ["/code/docker-entrypoint.sh"]
# Start uWSGI
CMD ["/venv/bin/uwsgi", "--show-config"]
# Run the WSGI server. It reads GUNICORN_CMD_ARGS, PORT and WEB_CONCURRENCY
# environment variable hence we don't specify a lot options below.
CMD ["gunicorn", "bakerydemo.wsgi:application"]

Wyświetl plik

@ -1,19 +1,3 @@
#!/bin/sh
set -e
until psql $DATABASE_URL -c '\l'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - continuing"
if [ "$1" = '/venv/bin/uwsgi' ]; then
/venv/bin/python manage.py migrate --noinput
fi
if [ "x$DJANGO_LOAD_INITIAL_DATA" = 'xon' ]; then
/venv/bin/python manage.py load_initial_data
fi
#!/bin/sh -e
exec "$@"

4
gunicorn-conf.py 100644
Wyświetl plik

@ -0,0 +1,4 @@
# Replace gunicorn's 'Server' HTTP header to avoid leaking info to attackers
import gunicorn
gunicorn.SERVER_SOFTWARE = ""

7
heroku.yml 100644
Wyświetl plik

@ -0,0 +1,7 @@
build:
docker:
web: Dockerfile
release:
image: web
command:
- django-admin migrate --noinput

Wyświetl plik

@ -4,7 +4,7 @@
elasticsearch==2.4.1
# Additional dependencies for Heroku, AWS, and Google Cloud deployment
dj-database-url==0.4.1
uwsgi>=2.0.17,<2.1
gunicorn==20.0.4
psycopg2>=2.7,<3.0
whitenoise>=5.0,<5.1
boto3==1.9.189