From 82c987f5412cfdb047d548a408238cd72966888c Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Wed, 2 Feb 2022 22:59:20 +0100 Subject: [PATCH] Make docker compose work locally --- .dockerignore | 4 +- .gitignore | 1 + compose/{production => }/django/Dockerfile | 30 ++++++-- compose/django/docker_entrypoint.sh | 44 +++++++++++ compose/django/docker_start.sh | 11 +++ compose/local/django/Dockerfile | 69 ------------------ compose/local/django/start | 9 --- compose/local/docs/Dockerfile | 64 ---------------- compose/local/docs/start | 7 -- compose/local/node/Dockerfile | 9 --- compose/production/django/entrypoint | 42 ----------- compose/production/django/start | 10 --- compose/production/postgres/Dockerfile | 6 -- .../maintenance/_sourced/constants.sh | 5 -- .../maintenance/_sourced/countdown.sh | 12 --- .../postgres/maintenance/_sourced/messages.sh | 41 ----------- .../postgres/maintenance/_sourced/yes_no.sh | 16 ---- .../production/postgres/maintenance/backup | 38 ---------- .../production/postgres/maintenance/backups | 22 ------ .../production/postgres/maintenance/restore | 55 -------------- compose/production/traefik/Dockerfile | 5 -- compose/production/traefik/traefik.yml | 58 --------------- config/settings/base.py | 21 +----- docker-compose-local.yml | 29 ++++++++ env/docker_local.env | 10 +-- env_secrets/production.env | Bin 1399 -> 1379 bytes local.yml | 69 ------------------ merge_production_dotenvs_in_dotenv.py | 67 ----------------- package.json | 4 +- tailwind.config.js | 7 ++ vbv_lernwelt/templates/base.html | 2 +- 31 files changed, 128 insertions(+), 639 deletions(-) rename compose/{production => }/django/Dockerfile (65%) create mode 100644 compose/django/docker_entrypoint.sh create mode 100644 compose/django/docker_start.sh delete mode 100644 compose/local/django/Dockerfile delete mode 100644 compose/local/django/start delete mode 100644 compose/local/docs/Dockerfile delete mode 100644 compose/local/docs/start delete mode 100644 compose/local/node/Dockerfile delete mode 100644 compose/production/django/entrypoint delete mode 100644 compose/production/django/start delete mode 100644 compose/production/postgres/Dockerfile delete mode 100644 compose/production/postgres/maintenance/_sourced/constants.sh delete mode 100644 compose/production/postgres/maintenance/_sourced/countdown.sh delete mode 100644 compose/production/postgres/maintenance/_sourced/messages.sh delete mode 100644 compose/production/postgres/maintenance/_sourced/yes_no.sh delete mode 100644 compose/production/postgres/maintenance/backup delete mode 100644 compose/production/postgres/maintenance/backups delete mode 100644 compose/production/postgres/maintenance/restore delete mode 100644 compose/production/traefik/Dockerfile delete mode 100644 compose/production/traefik/traefik.yml create mode 100644 docker-compose-local.yml delete mode 100644 local.yml delete mode 100644 merge_production_dotenvs_in_dotenv.py create mode 100644 tailwind.config.js diff --git a/.dockerignore b/.dockerignore index b4d081d7..2d776ac1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ +.direnv .editorconfig .gitattributes .github @@ -7,6 +8,5 @@ .pre-commit-config.yaml .readthedocs.yml .travis.yml -venv -.direnv node_modules +venv diff --git a/.gitignore b/.gitignore index b96ee850..a9f70e96 100644 --- a/.gitignore +++ b/.gitignore @@ -275,6 +275,7 @@ vbv_lernwelt/media/ .ipython/ project.css project.min.css +tailwind-output.css vendors.js *.min.js .env diff --git a/compose/production/django/Dockerfile b/compose/django/Dockerfile similarity index 65% rename from compose/production/django/Dockerfile rename to compose/django/Dockerfile index 989f1044..6dd66fbf 100644 --- a/compose/production/django/Dockerfile +++ b/compose/django/Dockerfile @@ -1,4 +1,12 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye +# create a new version of this docker image +# from https://stackoverflow.com/a/42125241/669561 +# build from project top directory! +# > docker build -f Dockerfile -t iterativ/vbv-lernwelt-django . +# run locally +# > docker run -v $(dirname $(pwd)) -p 8080:80 -it iterativ/vbv-lernwelt-django /bin/bash +# push to registry +# > docker push iterativ/vbv-lernwelt-django +ARG PYTHON_VERSION=3.10-slim-bullseye FROM node:16-bullseye-slim as client-builder @@ -29,8 +37,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ COPY ./requirements . # Create Python Dependency and Sub-Dependency Wheels. -RUN pip wheel --wheel-dir /usr/src/app/wheels \ - -r ${BUILD_ENVIRONMENT}.txt +RUN pip wheel --wheel-dir /usr/src/app/wheels -r requirements-dev.txt # Python 'run' stage @@ -68,15 +75,28 @@ RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \ && rm -rf /wheels/ -COPY --chown=django:django ./compose/production/django/entrypoint /entrypoint +COPY --chown=django:django ./compose/django/docker_entrypoint.sh /entrypoint RUN sed -i 's/\r$//g' /entrypoint RUN chmod +x /entrypoint -COPY --chown=django:django ./compose/production/django/start /start +COPY --chown=django:django ./compose/django/docker_start.sh /start RUN sed -i 's/\r$//g' /start RUN chmod +x /start +#COPY --chown=django:django ./compose/production/django/celery/worker/start /start-celeryworker +#RUN sed -i 's/\r$//g' /start-celeryworker +#RUN chmod +x /start-celeryworker +# +#COPY --chown=django:django ./compose/production/django/celery/beat/start /start-celerybeat +#RUN sed -i 's/\r$//g' /start-celerybeat +#RUN chmod +x /start-celerybeat +# +# +#COPY ./compose/production/django/celery/flower/start /start-flower +#RUN sed -i 's/\r$//g' /start-flower +#RUN chmod +x /start-flower + # copy application code to WORKDIR COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME} diff --git a/compose/django/docker_entrypoint.sh b/compose/django/docker_entrypoint.sh new file mode 100644 index 00000000..ade7774d --- /dev/null +++ b/compose/django/docker_entrypoint.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + + + +# N.B. If only .env files supported variable expansion... +# export CELERY_BROKER_URL="${REDIS_URL}" + +if [ -z "${POSTGRES_USER}" ]; then + base_postgres_image_default_user='postgres' + export POSTGRES_USER="${base_postgres_image_default_user}" +fi +export VBV_DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" + +postgres_ready() { +python << END +import sys + +import psycopg2 + +try: + psycopg2.connect( + dbname="${POSTGRES_DB}", + user="${POSTGRES_USER}", + password="${POSTGRES_PASSWORD}", + host="${POSTGRES_HOST}", + port="${POSTGRES_PORT}", + ) +except psycopg2.OperationalError: + sys.exit(-1) +sys.exit(0) + +END +} +until postgres_ready; do + >&2 echo 'Waiting for PostgreSQL to become available...' + sleep 1 +done +>&2 echo 'PostgreSQL is available' + +exec /start diff --git a/compose/django/docker_start.sh b/compose/django/docker_start.sh new file mode 100644 index 00000000..aebb6c98 --- /dev/null +++ b/compose/django/docker_start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + + +python /app/manage.py collectstatic --noinput +python /app/manage.py migrate + +/usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:80 --chdir=/app -k uvicorn.workers.UvicornWorker diff --git a/compose/local/django/Dockerfile b/compose/local/django/Dockerfile deleted file mode 100644 index d1e10b29..00000000 --- a/compose/local/django/Dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye - -# define an alias for the specfic python version used in this file. -FROM python:${PYTHON_VERSION} as python - -# Python build stage -FROM python as python-build-stage - -ARG BUILD_ENVIRONMENT=local - -# Install apt packages -RUN apt-get update && apt-get install --no-install-recommends -y \ - # dependencies for building Python packages - build-essential \ - # psycopg2 dependencies - libpq-dev - -# Requirements are installed here to ensure they will be cached. -COPY ./requirements . - -# Create Python Dependency and Sub-Dependency Wheels. -RUN pip wheel --wheel-dir /usr/src/app/wheels \ - -r ${BUILD_ENVIRONMENT}.txt - - -# Python 'run' stage -FROM python as python-run-stage - -ARG BUILD_ENVIRONMENT=local -ARG APP_HOME=/app - -ENV PYTHONUNBUFFERED 1 -ENV PYTHONDONTWRITEBYTECODE 1 -ENV BUILD_ENV ${BUILD_ENVIRONMENT} - -WORKDIR ${APP_HOME} - -# Install required system dependencies -RUN apt-get update && apt-get install --no-install-recommends -y \ - # psycopg2 dependencies - libpq-dev \ - # Translations dependencies - gettext \ - # cleaning up unused files - && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ - && rm -rf /var/lib/apt/lists/* - -# All absolute dir copies ignore workdir instruction. All relative dir copies are wrt to the workdir instruction -# copy python dependency wheels from python-build-stage -COPY --from=python-build-stage /usr/src/app/wheels /wheels/ - -# use wheels to install python dependencies -RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \ - && rm -rf /wheels/ - -COPY ./compose/production/django/entrypoint /entrypoint -RUN sed -i 's/\r$//g' /entrypoint -RUN chmod +x /entrypoint - -COPY ./compose/local/django/start /start -RUN sed -i 's/\r$//g' /start -RUN chmod +x /start - - - -# copy application code to WORKDIR -COPY . ${APP_HOME} - -ENTRYPOINT ["/entrypoint"] diff --git a/compose/local/django/start b/compose/local/django/start deleted file mode 100644 index c057aa11..00000000 --- a/compose/local/django/start +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o pipefail -set -o nounset - - -python manage.py migrate -uvicorn config.asgi:application --host 0.0.0.0 --reload diff --git a/compose/local/docs/Dockerfile b/compose/local/docs/Dockerfile deleted file mode 100644 index 6f1bb8b5..00000000 --- a/compose/local/docs/Dockerfile +++ /dev/null @@ -1,64 +0,0 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye - -# define an alias for the specfic python version used in this file. -FROM python:${PYTHON_VERSION} as python - - -# Python build stage -FROM python as python-build-stage - -ENV PYTHONDONTWRITEBYTECODE 1 - -RUN apt-get update && apt-get install --no-install-recommends -y \ - # dependencies for building Python packages - build-essential \ - # psycopg2 dependencies - libpq-dev \ - # cleaning up unused files - && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ - && rm -rf /var/lib/apt/lists/* - -# Requirements are installed here to ensure they will be cached. -COPY ./requirements /requirements - -# create python dependency wheels -RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels \ - -r /requirements/local.txt -r /requirements/production.txt \ - && rm -rf /requirements - - -# Python 'run' stage -FROM python as python-run-stage - -ARG BUILD_ENVIRONMENT -ENV PYTHONUNBUFFERED 1 -ENV PYTHONDONTWRITEBYTECODE 1 - -RUN apt-get update && apt-get install --no-install-recommends -y \ - # To run the Makefile - make \ - # psycopg2 dependencies - libpq-dev \ - # Translations dependencies - gettext \ - # Uncomment below lines to enable Sphinx output to latex and pdf - # texlive-latex-recommended \ - # texlive-fonts-recommended \ - # texlive-latex-extra \ - # latexmk \ - # cleaning up unused files - && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ - && rm -rf /var/lib/apt/lists/* - -# copy python dependency wheels from python-build-stage -COPY --from=python-build-stage /usr/src/app/wheels /wheels - -# use wheels to install python dependencies -RUN pip install --no-cache /wheels/* \ - && rm -rf /wheels - -COPY ./compose/local/docs/start /start-docs -RUN sed -i 's/\r$//g' /start-docs -RUN chmod +x /start-docs - -WORKDIR /docs diff --git a/compose/local/docs/start b/compose/local/docs/start deleted file mode 100644 index fd2e0de6..00000000 --- a/compose/local/docs/start +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o pipefail -set -o nounset - -make livehtml diff --git a/compose/local/node/Dockerfile b/compose/local/node/Dockerfile deleted file mode 100644 index 8062fa68..00000000 --- a/compose/local/node/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM node:16-bullseye-slim - -WORKDIR /app - -COPY ./package.json /app - -RUN npm install && npm cache clean --force - -ENV PATH ./node_modules/.bin/:$PATH diff --git a/compose/production/django/entrypoint b/compose/production/django/entrypoint deleted file mode 100644 index aa78749d..00000000 --- a/compose/production/django/entrypoint +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o pipefail -set -o nounset - - - - -if [ -z "${VBV_POSTGRES_USER}" ]; then - base_postgres_image_default_user='postgres' - export VBV_POSTGRES_USER="${base_postgres_image_default_user}" -fi -export VBV_DATABASE_URL="postgres://${VBV_POSTGRES_USER}:${VBV_POSTGRES_PASSWORD}@${VBV_POSTGRES_HOST}:${VBV_POSTGRES_PORT}/${VBV_POSTGRES_DB}" - -postgres_ready() { -python << END -import sys - -import psycopg2 - -try: - psycopg2.connect( - dbname="${VBV_POSTGRES_DB}", - user="${VBV_POSTGRES_USER}", - password="${VBV_POSTGRES_PASSWORD}", - host="${VBV_POSTGRES_HOST}", - port="${VBV_POSTGRES_PORT}", - ) -except psycopg2.OperationalError: - sys.exit(-1) -sys.exit(0) - -END -} -until postgres_ready; do - >&2 echo 'Waiting for PostgreSQL to become available...' - sleep 1 -done ->&2 echo 'PostgreSQL is available' - -exec "$@" diff --git a/compose/production/django/start b/compose/production/django/start deleted file mode 100644 index a82c1ad2..00000000 --- a/compose/production/django/start +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o pipefail -set -o nounset - - -python /app/manage.py collectstatic --noinput - -/usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker diff --git a/compose/production/postgres/Dockerfile b/compose/production/postgres/Dockerfile deleted file mode 100644 index 71c2b44a..00000000 --- a/compose/production/postgres/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM postgres:14.1 - -COPY ./compose/production/postgres/maintenance /usr/local/bin/maintenance -RUN chmod +x /usr/local/bin/maintenance/* -RUN mv /usr/local/bin/maintenance/* /usr/local/bin \ - && rmdir /usr/local/bin/maintenance diff --git a/compose/production/postgres/maintenance/_sourced/constants.sh b/compose/production/postgres/maintenance/_sourced/constants.sh deleted file mode 100644 index 6ca4f0ca..00000000 --- a/compose/production/postgres/maintenance/_sourced/constants.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - - -BACKUP_DIR_PATH='/backups' -BACKUP_FILE_PREFIX='backup' diff --git a/compose/production/postgres/maintenance/_sourced/countdown.sh b/compose/production/postgres/maintenance/_sourced/countdown.sh deleted file mode 100644 index e6cbfb6f..00000000 --- a/compose/production/postgres/maintenance/_sourced/countdown.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - - -countdown() { - declare desc="A simple countdown. Source: https://superuser.com/a/611582" - local seconds="${1}" - local d=$(($(date +%s) + "${seconds}")) - while [ "$d" -ge `date +%s` ]; do - echo -ne "$(date -u --date @$(($d - `date +%s`)) +%H:%M:%S)\r"; - sleep 0.1 - done -} diff --git a/compose/production/postgres/maintenance/_sourced/messages.sh b/compose/production/postgres/maintenance/_sourced/messages.sh deleted file mode 100644 index f6be756e..00000000 --- a/compose/production/postgres/maintenance/_sourced/messages.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env bash - - -message_newline() { - echo -} - -message_debug() -{ - echo -e "DEBUG: ${@}" -} - -message_welcome() -{ - echo -e "\e[1m${@}\e[0m" -} - -message_warning() -{ - echo -e "\e[33mWARNING\e[0m: ${@}" -} - -message_error() -{ - echo -e "\e[31mERROR\e[0m: ${@}" -} - -message_info() -{ - echo -e "\e[37mINFO\e[0m: ${@}" -} - -message_suggestion() -{ - echo -e "\e[33mSUGGESTION\e[0m: ${@}" -} - -message_success() -{ - echo -e "\e[32mSUCCESS\e[0m: ${@}" -} diff --git a/compose/production/postgres/maintenance/_sourced/yes_no.sh b/compose/production/postgres/maintenance/_sourced/yes_no.sh deleted file mode 100644 index fd9cae16..00000000 --- a/compose/production/postgres/maintenance/_sourced/yes_no.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - - -yes_no() { - declare desc="Prompt for confirmation. \$\"\{1\}\": confirmation message." - local arg1="${1}" - - local response= - read -r -p "${arg1} (y/[n])? " response - if [[ "${response}" =~ ^[Yy]$ ]] - then - exit 0 - else - exit 1 - fi -} diff --git a/compose/production/postgres/maintenance/backup b/compose/production/postgres/maintenance/backup deleted file mode 100644 index e41feb57..00000000 --- a/compose/production/postgres/maintenance/backup +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - - -### Create a database backup. -### -### Usage: -### $ docker-compose -f .yml (exec |run --rm) postgres backup - - -set -o errexit -set -o pipefail -set -o nounset - - -working_dir="$(dirname ${0})" -source "${working_dir}/_sourced/constants.sh" -source "${working_dir}/_sourced/messages.sh" - - -message_welcome "Backing up the '${VBV_POSTGRES_DB}' database..." - - -if [[ "${VBV_POSTGRES_USER}" == "postgres" ]]; then - message_error "Backing up as 'postgres' user is not supported. Assign 'VBV_POSTGRES_USER' env with another one and try again." - exit 1 -fi - -export PGHOST="${VBV_POSTGRES_HOST}" -export PGPORT="${VBV_POSTGRES_PORT}" -export PGUSER="${VBV_POSTGRES_USER}" -export PGPASSWORD="${VBV_POSTGRES_PASSWORD}" -export PGDATABASE="${VBV_POSTGRES_DB}" - -backup_filename="${BACKUP_FILE_PREFIX}_$(date +'%Y_%m_%dT%H_%M_%S').sql.gz" -pg_dump | gzip > "${BACKUP_DIR_PATH}/${backup_filename}" - - -message_success "'${VBV_POSTGRES_DB}' database backup '${backup_filename}' has been created and placed in '${BACKUP_DIR_PATH}'." diff --git a/compose/production/postgres/maintenance/backups b/compose/production/postgres/maintenance/backups deleted file mode 100644 index 0484ccff..00000000 --- a/compose/production/postgres/maintenance/backups +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - - -### View backups. -### -### Usage: -### $ docker-compose -f .yml (exec |run --rm) postgres backups - - -set -o errexit -set -o pipefail -set -o nounset - - -working_dir="$(dirname ${0})" -source "${working_dir}/_sourced/constants.sh" -source "${working_dir}/_sourced/messages.sh" - - -message_welcome "These are the backups you have got:" - -ls -lht "${BACKUP_DIR_PATH}" diff --git a/compose/production/postgres/maintenance/restore b/compose/production/postgres/maintenance/restore deleted file mode 100644 index 0a1c0046..00000000 --- a/compose/production/postgres/maintenance/restore +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - - -### Restore database from a backup. -### -### Parameters: -### <1> filename of an existing backup. -### -### Usage: -### $ docker-compose -f .yml (exec |run --rm) postgres restore <1> - - -set -o errexit -set -o pipefail -set -o nounset - - -working_dir="$(dirname ${0})" -source "${working_dir}/_sourced/constants.sh" -source "${working_dir}/_sourced/messages.sh" - - -if [[ -z ${1+x} ]]; then - message_error "Backup filename is not specified yet it is a required parameter. Make sure you provide one and try again." - exit 1 -fi -backup_filename="${BACKUP_DIR_PATH}/${1}" -if [[ ! -f "${backup_filename}" ]]; then - message_error "No backup with the specified filename found. Check out the 'backups' maintenance script output to see if there is one and try again." - exit 1 -fi - -message_welcome "Restoring the '${VBV_POSTGRES_DB}' database from the '${backup_filename}' backup..." - -if [[ "${VBV_POSTGRES_USER}" == "postgres" ]]; then - message_error "Restoring as 'postgres' user is not supported. Assign 'VBV_POSTGRES_USER' env with another one and try again." - exit 1 -fi - -export PGHOST="${VBV_POSTGRES_HOST}" -export PGPORT="${VBV_POSTGRES_PORT}" -export PGUSER="${VBV_POSTGRES_USER}" -export PGPASSWORD="${VBV_POSTGRES_PASSWORD}" -export PGDATABASE="${VBV_POSTGRES_DB}" - -message_info "Dropping the database..." -dropdb "${PGDATABASE}" - -message_info "Creating a new database..." -createdb --owner="${VBV_POSTGRES_USER}" - -message_info "Applying the backup to the new database..." -gunzip -c "${backup_filename}" | psql "${VBV_POSTGRES_DB}" - -message_success "The '${VBV_POSTGRES_DB}' database has been restored from the '${backup_filename}' backup." diff --git a/compose/production/traefik/Dockerfile b/compose/production/traefik/Dockerfile deleted file mode 100644 index aa879052..00000000 --- a/compose/production/traefik/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM traefik:v2.2.11 -RUN mkdir -p /etc/traefik/acme \ - && touch /etc/traefik/acme/acme.json \ - && chmod 600 /etc/traefik/acme/acme.json -COPY ./compose/production/traefik/traefik.yml /etc/traefik diff --git a/compose/production/traefik/traefik.yml b/compose/production/traefik/traefik.yml deleted file mode 100644 index 3b6d06e9..00000000 --- a/compose/production/traefik/traefik.yml +++ /dev/null @@ -1,58 +0,0 @@ -log: - level: INFO - -entryPoints: - web: - # http - address: ":80" - http: - # https://docs.traefik.io/routing/entrypoints/#entrypoint - redirections: - entryPoint: - to: web-secure - - web-secure: - # https - address: ":443" - -certificatesResolvers: - letsencrypt: - # https://docs.traefik.io/master/https/acme/#lets-encrypt - acme: - email: "daniel.egger@iterativ.ch" - storage: /etc/traefik/acme/acme.json - # https://docs.traefik.io/master/https/acme/#httpchallenge - httpChallenge: - entryPoint: web - -http: - routers: - web-secure-router: - rule: "Host(`vbv-lernwelt.iterativ.ch`)" - entryPoints: - - web-secure - middlewares: - - csrf - service: django - tls: - # https://docs.traefik.io/master/routing/routers/#certresolver - certResolver: letsencrypt - - middlewares: - csrf: - # https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders - # https://docs.djangoproject.com/en/dev/ref/csrf/#ajax - headers: - hostsProxyHeaders: ["X-CSRFToken"] - - services: - django: - loadBalancer: - servers: - - url: http://django:5000 - -providers: - # https://docs.traefik.io/master/providers/file/ - file: - filename: /etc/traefik/traefik.yml - watch: true diff --git a/config/settings/base.py b/config/settings/base.py index 111c53c5..63630fdd 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -232,25 +232,6 @@ MANAGERS = ADMINS # https://docs.djangoproject.com/en/dev/ref/settings/#logging # See https://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. -LOGGING = { - "version": 1, - "disable_existing_loggers": False, - "formatters": { - "verbose": { - "format": "%(levelname)s %(asctime)s %(module)s " - "%(process)d %(thread)d %(message)s" - } - }, - "handlers": { - "console": { - "level": "DEBUG", - "class": "logging.StreamHandler", - "formatter": "verbose", - } - }, - "root": {"level": "INFO", "handlers": ["console"]}, -} - VBV_DJANGO_LOGGING_CONF = env("VBV_DJANGO_LOGGING_CONF", default="VBV_DJANGO_LOGGING_CONF_JSON_FILE") if VBV_DJANGO_LOGGING_CONF == "VBV_DJANGO_LOGGING_CONF_CONSOLE_COLOR": @@ -326,7 +307,7 @@ else: "console": { "level": "DEBUG", "class": "logging.StreamHandler", - "formatter": "verbose", + "formatter": "json", }, }, 'loggers': { diff --git a/docker-compose-local.yml b/docker-compose-local.yml new file mode 100644 index 00000000..6a56aa28 --- /dev/null +++ b/docker-compose-local.yml @@ -0,0 +1,29 @@ +version: '3' + +volumes: + vbv_lernwelt_local_postgres_data: {} + vbv_lernwelt_local_postgres_data_backups: {} + +services: + django: + build: + context: . + dockerfile: ./compose/django/Dockerfile + image: iterativ/vbv-lernwelt-django + depends_on: + - postgres + env_file: + - ./env/docker_local.env + ports: + - "8008:80" + command: /start + + postgres: + build: + context: . + image: postgres:14.1 + volumes: + - vbv_lernwelt_local_postgres_data:/var/lib/postgresql/data:Z + - vbv_lernwelt_local_postgres_data_backups:/backups:z + env_file: + - ./env/docker_local.env diff --git a/env/docker_local.env b/env/docker_local.env index 7f067c47..93a5c471 100644 --- a/env/docker_local.env +++ b/env/docker_local.env @@ -1,10 +1,10 @@ # PostgreSQL # ------------------------------------------------------------------------------ -VBV_POSTGRES_HOST=postgres -VBV_POSTGRES_PORT=5432 -VBV_POSTGRES_DB=vbv_lernwelt -VBV_POSTGRES_USER=MRsLOrFLFqmAnAxxWMsHXfUSqWHThtGQ -VBV_POSTGRES_PASSWORD=hNqfCdG6bwCLcnfboDtNM1L2Hiwp8GuKp1DJ6t2rcKl15Vls2QbByoIZ6IQlciKM +POSTGRES_HOST=postgres +POSTGRES_PORT=5432 +POSTGRES_DB=vbv_lernwelt +POSTGRES_USER=MRsLOrFLFqmAnAxxWMsHXfUSqWHThtGQ +POSTGRES_PASSWORD=hNqfCdG6bwCLcnfboDtNM1L2Hiwp8GuKp1DJ6t2rcKl15Vls2QbByoIZ6IQlciKM # General # ------------------------------------------------------------------------------ diff --git a/env_secrets/production.env b/env_secrets/production.env index bb79376375344acee136f7c1d8e4417a619c6f44..36afa78268aacdb77abfcc6e1becf2df15c5244a 100644 GIT binary patch literal 1379 zcmV-p1)TZ-M@dveQdv+`0A^Bp$~!LhC=^EW+Mq#4afIH}w21nE7m^1ktRim&p6z{z?y`MAHyTVcEA z9U$6n{36Cs>q>1g#Ylc`_L&U7lKhJEknD=bNc_|v#t5A8rq1w zkDr#M50B3AuHkwro^E-STU8T#Fx=$lA5>56+D4$wh}I9zAGR=WY~2}~y0guy7Xrio zgdhPgVWOymz#27VS?YZAm1ehV@YOo%Zm6QOLzl@uSj7@q@17R4MD++wYze z;VZgx3t(Q9Z2k5_2iy&p6TA|G%-x&*u54C_h zeYS|>jOD>}uKn7`TlH+O^)F-}0Ud1=6cXON0*k_Wv^D+Mhn7?qRS$|G+VZ7SfXYzG z)Cqt?;Qnry$3S3&pyBzinDU<%aYWsIO37|UixGxpMznA9aSiAMOOrR$hz+9%x~Fr6S7g569lNOb<)Fylh0)7A!n0e-t2UgHh4&YujV0>%>wjY6+8rd*-;aN|&vvQ#>EqbQ9 z7=m&@j+kzBXAh|N5Ab&i)+|UxPi#?^H}ofEMTRO-rFg>6kODk?!)`bs$yx>Hb0zAZ zqp;z*Y#r!m4}3p;?3^YIgy}Q~E7=Z2%l}(<7Las1qPGG6=$v78Yt{t`d2XQxQYqM4 zDhLzGMQ61&-!AzHCU5!id7IaCgtjud*k#0*mn#+28h`hWcCW2O-5~o8d*TJ@okKaF5YRRowdFPPh-M`_!X2q-3E@ZHQ8zMYXXbuSdPQURORP|ntYUOmE z(4}s&waqnA&r>au)rIZV)*b3!xQOE~l*U@`(E1a54G5cJclUumWY|OG_q&mlS7qtW z90APZ-CG`__q^tqKXA;Fpe#}3rxDy_|6rmkb5ezP;G?AKRn~y_aj?Qrjz0lBbYM)d zfXU|WQt`-frqfodh|q^u(jqfMjtMLULdU!)GdJ}jKuDEz@F20$S3+s`4rb^|t*^`N zpe9}!bTW{bQ^BuDt$D=;S~X9Jr=bL#rO5O}(hRT8P@8+*TngE*mT9Zkr%;NWt+?1G zgF|Vn*^~d@9Z)mQM<5F7#*(_iq_du8p8IQIn1!IHhZ_5`kb1BL7{ zeE!mciC-jmvP!qtl#z}KBtJEbIV??lJg^ie^M^}Q_3|if^6)u7oW?c0QQ9`LkR12b l`IW}3rL%0Z*tJ2a|IkIA)#2A8CgaF#om>2Eu!wi!OX{i7uJQl? literal 1399 zcmV--1&I0pM@dveQdv+`0BA;Y)x92x95+gqZ^JEk0>+|}bl(5oSEgK*8WG7os?e5X z!NeVeewXhaJ~F+Q`2hTQ6Rv`nAMha}?dg&TmwKm3F+t4z09umdLlKqyq!=End73_A zmEFWDI36K2sZAGb&8NoAsz(+kS&3OTJ>Z*7Mwz8$hX5h)6KSxZMp6M|VY6UAB+KZc zxvHQ|^O4vRc&kNcR8G+EUOe->=0QEzgpUKp_+nwLufn?vxk5iKN@w?^#5)quY1(bp zy6%m8J{Bo1G+I_ZJ#4dp<{*?IeS}c@dJp2ux$`woYpc&Jb9tG7zV)R?5#Nw{NVtXX zEM;HKA4(i4h@rW{qM{y2*gUc-d*x1(OL`PVp)I z6S=GR*@&HY35y3Vy6I`2_Re1csap8}HldDh9Cu%715NY2{`cm1Ox>ae!Zi&&`GKxd z*y}weq(X~vw_NLgo(!dnSgw-whNk?2fK>!K!{^>nad!blUL85YUq<1cp?N88k*uZP zbd9hHycxix^8n?p_SalauPKv=+#+jxcgcI!`fG6E*4R~P$kJsp8rLm+GmipUo!pmUu{%6I z&JEo3N&fOSGIqaOIOQ?Tv=6^1W*YV?E%`hDyDn1<xH=0<}j7g2;Kq+WfL4ORrS{^}Y|#-UUP~>#rZn>A5K&N7& zHE}S8199aBVdbN>qqi|+arFHfE7mkMRY`G)Q)QTFYZK&$@`3tCux(|b3S0b4=&Hge zG;(_*Tm(47FN#4kDR#vnCI8B*O|UrPxY)0301;iXHH>FSY5GW6Z!h>EV;VPfTgN zi)osLL~;!Uv+Gsu1Re<755Xv_J#g^Ni<=HnpEwr2%{j;}2qt(l8oml1{f|SV5<>}@ z2X@{2kGTazT1}m#f`qEae?~4JjqyQfS86F-Y+<&TdL1L_6}p%@O3}Mw4@@o=7QSdL z7pyK?cej69?&vC%BipF(R99&T4N|}hAn9u59e@J}(N)N0me-{H`Va?Uf2cOh{FDU~lXJ^+08}fn)81S&Wn!o9=y&kBO6Sohh<+Fwui4 z None: - with open(output_file_path, "w") as output_file: - for merged_file_path in merged_file_paths: - with open(merged_file_path, "r") as merged_file: - merged_file_content = merged_file.read() - output_file.write(merged_file_content) - if append_linesep: - output_file.write(os.linesep) - - -def main(): - merge(DOTENV_FILE_PATH, PRODUCTION_DOTENV_FILE_PATHS) - - -@pytest.mark.parametrize("merged_file_count", range(3)) -@pytest.mark.parametrize("append_linesep", [True, False]) -def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool): - tmp_dir_path = Path(str(tmpdir_factory.getbasetemp())) - - output_file_path = tmp_dir_path / ".env" - - expected_output_file_content = "" - merged_file_paths = [] - for i in range(merged_file_count): - merged_file_ord = i + 1 - - merged_filename = ".service{}".format(merged_file_ord) - merged_file_path = tmp_dir_path / merged_filename - - merged_file_content = merged_filename * merged_file_ord - - with open(merged_file_path, "w+") as file: - file.write(merged_file_content) - - expected_output_file_content += merged_file_content - if append_linesep: - expected_output_file_content += os.linesep - - merged_file_paths.append(merged_file_path) - - merge(output_file_path, merged_file_paths, append_linesep) - - with open(output_file_path, "r") as output_file: - actual_output_file_content = output_file.read() - - assert actual_output_file_content == expected_output_file_content - - -if __name__ == "__main__": - main() diff --git a/package.json b/package.json index 39d89bfb..4d1bc172 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ ], "scripts": { "dev": "gulp", - "tailwind": "tailwindcss -i ./vbv_lernwelt/static/tailwind/input.css -o ./vbv_lernwelt/static/css/output.css --watch", - "build": "gulp generate-assets" + "tailwind": "tailwindcss -i ./vbv_lernwelt/static/tailwind/input.css -o ./vbv_lernwelt/static/css/tailwind-output.css --watch", + "build": "tailwindcss -i ./vbv_lernwelt/static/tailwind/input.css -o ./vbv_lernwelt/static/css/tailwind-output.css && gulp generate-assets" } } diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 00000000..babe27ef --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,7 @@ +module.exports = { + content: ["./vbv_lernwelt/**/*.{html,js}"], + theme: { + extend: {}, + }, + plugins: [], +} diff --git a/vbv_lernwelt/templates/base.html b/vbv_lernwelt/templates/base.html index 56b4fd91..18ee129f 100644 --- a/vbv_lernwelt/templates/base.html +++ b/vbv_lernwelt/templates/base.html @@ -15,7 +15,7 @@ - + {% endblock %}