From 20d4ad736a4317bfff5f34e804c02cd3eb3832d5 Mon Sep 17 00:00:00 2001 From: Jakub Nowak Date: Fri, 7 May 2021 01:31:43 +0200 Subject: [PATCH 1/3] Configure docker for development Configured docker image to be usable for development. Also fixed the image and locked base images versions to prevent future errors. --- .github/workflows/test-and-deploy.yml | 6 +- Dockerfile | 100 ++++++++++++++++---------- README.md | 1 + docker-compose.yml | 5 +- entrypoint.sh | 26 +++++-- requirements-test.txt | 6 ++ requirements.txt | 26 +++---- 7 files changed, 102 insertions(+), 68 deletions(-) create mode 100644 requirements-test.txt diff --git a/.github/workflows/test-and-deploy.yml b/.github/workflows/test-and-deploy.yml index 0b024b27..dbc62c18 100644 --- a/.github/workflows/test-and-deploy.yml +++ b/.github/workflows/test-and-deploy.yml @@ -1,6 +1,6 @@ name: Test than deploy -on: +on: push: branches: [master] pull_request: @@ -24,7 +24,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt + pip install -r requirements.txt -r requirements-test.txt - name: Install JS/CSS dependencies run: npm install - name: Build JS/CSS with webpack @@ -51,7 +51,7 @@ jobs: fail_ci_if_error: true verbose: true if: matrix.python-version == 3.8 - + deploy: if: github.ref == 'refs/heads/master' runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index e5e5de27..8a467d66 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,39 +1,61 @@ -FROM node:current-alpine AS build_frontend -WORKDIR /app - -COPY package.json package-lock.json ./ -RUN npm ci -COPY webpack.config.js . -COPY frontend ./frontend -RUN npm run build - - - -FROM python:alpine -WORKDIR /usr/src/app -ENV PYTHONDONTWRITEBYTECODE 1 -ENV PYTHONUNBUFFERED 1 - -RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev libffi-dev zlib-dev jpeg-dev - -RUN pip install --upgrade pip -COPY requirements.txt . -RUN pip install -r requirements.txt -RUN pip install gunicorn - -COPY . . -COPY --from=build_frontend /app/static/dist static/dist - -RUN echo "import os" > wwwapp/local_settings.py -RUN echo "SECRET_KEY = os.environ['SECRET_KEY']" >> wwwapp/local_settings.py -RUN echo "ALLOWED_HOSTS = ['*']" >> wwwapp/local_settings.py -RUN echo "DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'HOST': 'db', 'NAME': 'aplikacjawww', 'USER': 'app', 'PASSWORD': 'app'}}" >> wwwapp/local_settings.py -RUN echo "GOOGLE_ANALYTICS_KEY = None" >> wwwapp/local_settings.py -RUN echo "MEDIA_ROOT = os.environ['MEDIA_ROOT']" >> wwwapp/local_settings.py -RUN echo "SENDFILE_ROOT = os.environ['SENDFILE_ROOT']" >> wwwapp/local_settings.py -RUN echo "USE_X_FORWARDED_HOST = True" >> wwwapp/local_settings.py -RUN echo "SESSION_COOKIE_SECURE = False" >> wwwapp/local_settings.py -RUN echo "CSRF_COOKIE_SECURE = False" >> wwwapp/local_settings.py - -CMD gunicorn wwwapp.wsgi:application --bind 0.0.0.0:8000 -ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file +FROM node:16-alpine3.13 AS build-frontend +WORKDIR /app + +COPY package.json \ + package-lock.json \ + ./ +RUN npm clean-install + +COPY webpack.config.js . +COPY frontend ./frontend +RUN npm run build + + +FROM python:3.9-alpine3.13 AS runner +WORKDIR /usr/src/app + + +# RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev libffi-dev zlib-dev jpeg-dev +RUN apk update \ +&& apk add \ + cargo \ + gcc \ + jpeg-dev \ + libffi-dev \ + musl-dev \ + openssl-dev \ + postgresql-dev \ + python3-dev \ + zlib-dev \ +; + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +RUN pip install --upgrade pip setuptools +COPY requirements.txt . +RUN pip install gunicorn -r requirements.txt + +COPY --from=build-frontend \ + /app/static/dist \ + static/dist +COPY . . + +RUN echo "import os" >>wwwapp/local_settings.py \ +&& echo "DEBUG = True" >>wwwapp/local_settings.py \ +&& echo "SECRET_KEY = os.environ['SECRET_KEY']" >>wwwapp/local_settings.py \ +&& echo "ALLOWED_HOSTS = ['*']" >>wwwapp/local_settings.py \ +&& echo "class Anything: __contains__ = lambda *args: True" >>wwwapp/local_settings.py \ +&& echo "INTERNAL_IPS = Anything()" >>wwwapp/local_settings.py \ +&& echo "DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'HOST': 'db', 'NAME': 'aplikacjawww', 'USER': 'app', 'PASSWORD': 'app'}}" >>wwwapp/local_settings.py \ +&& echo "GOOGLE_ANALYTICS_KEY = None" >>wwwapp/local_settings.py \ +&& echo "MEDIA_ROOT = os.environ['MEDIA_ROOT']" >>wwwapp/local_settings.py \ +&& echo "SENDFILE_ROOT = os.environ['SENDFILE_ROOT']" >>wwwapp/local_settings.py \ +&& echo "USE_X_FORWARDED_HOST = True" >>wwwapp/local_settings.py \ +&& echo "SESSION_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ +&& echo "CSRF_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ +; + + +EXPOSE 8000 +CMD ./entrypoint.sh diff --git a/README.md b/README.md index 9c4bdf6b..886b5be6 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Django-based application to manage registration of people for [scientific summer - `./manage.py populate_with_test_data` - script to populate the database with data for development ### Run: +- install postgresql - activate virtualenv (if not yet activated) - `pip install -r requirements.txt` - `./manage.py runserver` diff --git a/docker-compose.yml b/docker-compose.yml index 81d552a6..ba34f1a0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,13 @@ version: '3.7' services: + django: build: . volumes: - static_volume:/usr/src/static - media_volume:/usr/src/media - uploads_volume:/usr/src/uploads - expose: - - 8000 environment: - DJANGO_SETTINGS_MODULE=wwwapp.settings_prod - MEDIA_ROOT=/usr/src/media @@ -20,6 +19,7 @@ services: - SOCIAL_AUTH_FACEBOOK_SECRET=${SOCIAL_AUTH_FACEBOOK_SECRET} depends_on: - db + db: image: postgres:alpine volumes: @@ -28,6 +28,7 @@ services: - POSTGRES_DB=aplikacjawww - POSTGRES_USER=app - POSTGRES_PASSWORD=app + nginx: image: nginx:alpine volumes: diff --git a/entrypoint.sh b/entrypoint.sh index 5fc54272..7c7e8c22 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,14 +1,26 @@ #!/bin/sh -echo "Collecting static files" +set -o pipefail -o nounset + + +echo >&2 "Collecting static files." rm -rf /usr/src/static/* -python manage.py collectstatic +python3 manage.py collectstatic -echo "Waiting for postgres..." +echo >&2 "Waiting for postgres..." while ! nc -z db 5432; do - sleep 0.1 + sleep 0.1 done -echo "PostgreSQL started" -python manage.py migrate +echo >&2 "PostgreSQL started." + +echo >&2 "Migrating database." +python3 manage.py migrate + +echo >&2 "Creating admin user (username: admin, password: admin)." +export DJANGO_SUPERUSER_EMAIL=admin@admin.admin +export DJANGO_SUPERUSER_PASSWORD=admin \ +export DJANGO_SUPERUSER_USERNAME=admin +# This will fail if admin user already exists. +python3 manage.py createsuperuser --noinput || true -exec "$@" \ No newline at end of file +exec gunicorn wwwapp.wsgi:application --bind 0.0.0.0:8000 diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 00000000..f124858b --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,6 @@ +coverage==5.5 +django-coverage-plugin==1.8.0 +django-stubs==1.7.0 +freezegun==1.1.0 +mock==4.0.3 +mypy==0.812 diff --git a/requirements.txt b/requirements.txt index 3c17050f..02fac19b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,23 +1,15 @@ -Django==3.1.8 -django-crispy-forms==1.11.1 -django-tinymce==3.2.0 +django-admin-sortable2==0.7.8 django-bleach==0.6.1 django-cleanup==5.1.0 -django-sendfile2==0.6.0 +django-crispy-forms==1.11.1 django-debug-toolbar==3.2 -django-select2==7.6.2 -social-auth-app-django==4.0.0 -django-admin-sortable2==0.7.8 django-imagekit==4.0.2 -Pillow==8.1.2 -python-dateutil==2.8.1 +django-select2==7.6.2 +django-sendfile2==0.6.0 +django-tinymce==3.2.0 +Django==3.1.8 Faker==6.6.2 +Pillow==8.1.2 psycopg2==2.8.6 - -mock==4.0.3 -freezegun==1.1.0 -coverage==5.5 -django-coverage-plugin==1.8.0 - -mypy==0.812 -django-stubs==1.7.0 +python-dateutil==2.8.1 +social-auth-app-django==4.0.0 From 9c6cec3c50b96c344e0be9df403f4a5ae5d6215e Mon Sep 17 00:00:00 2001 From: Jakub Nowak Date: Fri, 7 May 2021 01:47:41 +0200 Subject: [PATCH 2/3] Replace tabs with spaces in Dockerfile I've realized it looks poorly with tab width shorter than 5. --- Dockerfile | 92 +++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8a467d66..704b5ba8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,61 +1,61 @@ -FROM node:16-alpine3.13 AS build-frontend -WORKDIR /app +FROM node:16-alpine3.13 AS build-frontend +WORKDIR /app -COPY package.json \ - package-lock.json \ - ./ -RUN npm clean-install +COPY package.json \ + package-lock.json \ + ./ +RUN npm clean-install -COPY webpack.config.js . -COPY frontend ./frontend -RUN npm run build +COPY webpack.config.js . +COPY frontend ./frontend +RUN npm run build -FROM python:3.9-alpine3.13 AS runner -WORKDIR /usr/src/app +FROM python:3.9-alpine3.13 AS runner +WORKDIR /usr/src/app # RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev libffi-dev zlib-dev jpeg-dev -RUN apk update \ -&& apk add \ - cargo \ - gcc \ - jpeg-dev \ - libffi-dev \ - musl-dev \ - openssl-dev \ - postgresql-dev \ - python3-dev \ - zlib-dev \ +RUN apk update \ +&& apk add \ + cargo \ + gcc \ + jpeg-dev \ + libffi-dev \ + musl-dev \ + openssl-dev \ + postgresql-dev \ + python3-dev \ + zlib-dev \ ; -ENV PYTHONDONTWRITEBYTECODE=1 \ - PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 -RUN pip install --upgrade pip setuptools -COPY requirements.txt . -RUN pip install gunicorn -r requirements.txt +RUN pip install --upgrade pip setuptools +COPY requirements.txt . +RUN pip install gunicorn -r requirements.txt COPY --from=build-frontend \ - /app/static/dist \ - static/dist -COPY . . - -RUN echo "import os" >>wwwapp/local_settings.py \ -&& echo "DEBUG = True" >>wwwapp/local_settings.py \ -&& echo "SECRET_KEY = os.environ['SECRET_KEY']" >>wwwapp/local_settings.py \ -&& echo "ALLOWED_HOSTS = ['*']" >>wwwapp/local_settings.py \ -&& echo "class Anything: __contains__ = lambda *args: True" >>wwwapp/local_settings.py \ -&& echo "INTERNAL_IPS = Anything()" >>wwwapp/local_settings.py \ -&& echo "DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'HOST': 'db', 'NAME': 'aplikacjawww', 'USER': 'app', 'PASSWORD': 'app'}}" >>wwwapp/local_settings.py \ -&& echo "GOOGLE_ANALYTICS_KEY = None" >>wwwapp/local_settings.py \ -&& echo "MEDIA_ROOT = os.environ['MEDIA_ROOT']" >>wwwapp/local_settings.py \ -&& echo "SENDFILE_ROOT = os.environ['SENDFILE_ROOT']" >>wwwapp/local_settings.py \ -&& echo "USE_X_FORWARDED_HOST = True" >>wwwapp/local_settings.py \ -&& echo "SESSION_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ -&& echo "CSRF_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ + /app/static/dist \ + static/dist +COPY . . + +RUN echo "import os" >>wwwapp/local_settings.py \ +&& echo "DEBUG = True" >>wwwapp/local_settings.py \ +&& echo "SECRET_KEY = os.environ['SECRET_KEY']" >>wwwapp/local_settings.py \ +&& echo "ALLOWED_HOSTS = ['*']" >>wwwapp/local_settings.py \ +&& echo "class Anything: __contains__ = lambda *args: True" >>wwwapp/local_settings.py \ +&& echo "INTERNAL_IPS = Anything()" >>wwwapp/local_settings.py \ +&& echo "DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'HOST': 'db', 'NAME': 'aplikacjawww', 'USER': 'app', 'PASSWORD': 'app'}}" >>wwwapp/local_settings.py \ +&& echo "GOOGLE_ANALYTICS_KEY = None" >>wwwapp/local_settings.py \ +&& echo "MEDIA_ROOT = os.environ['MEDIA_ROOT']" >>wwwapp/local_settings.py \ +&& echo "SENDFILE_ROOT = os.environ['SENDFILE_ROOT']" >>wwwapp/local_settings.py \ +&& echo "USE_X_FORWARDED_HOST = True" >>wwwapp/local_settings.py \ +&& echo "SESSION_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ +&& echo "CSRF_COOKIE_SECURE = False" >>wwwapp/local_settings.py \ ; -EXPOSE 8000 -CMD ./entrypoint.sh +EXPOSE 8000 +CMD ./entrypoint.sh From 39f6e86a60abd6862dde8a0b2b4075b9571613d4 Mon Sep 17 00:00:00 2001 From: Jakub Nowak Date: Fri, 7 May 2021 01:49:42 +0200 Subject: [PATCH 3/3] Remove leftover comment --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 704b5ba8..1e39be69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,6 @@ FROM python:3.9-alpine3.13 AS runner WORKDIR /usr/src/app -# RUN apk update && apk add postgresql-dev gcc python3-dev musl-dev libffi-dev zlib-dev jpeg-dev RUN apk update \ && apk add \ cargo \