From c93d327cec8ead9907537bb2f6187464c4e52f20 Mon Sep 17 00:00:00 2001
From: janmax <mail-github@jmx.io>
Date: Mon, 30 Oct 2017 00:35:43 +0100
Subject: [PATCH] Got rid of docker in docker and streamlined Dockerfile with
 multi-stage-builds

---
 .dockerignore             | 19 +++++++++++++++++++
 .gitignore                |  1 +
 .gitlab-ci.yml            | 24 ++++++++++++++++-------
 Dockerfile                | 40 ++++++++++++++++++++++++---------------
 Makefile                  |  2 +-
 core/models.py            |  2 +-
 docker-compose.yml        | 12 ++++++++----
 grady/settings/default.py | 15 +++++++--------
 grady/settings/live.py    | 20 +++++++++++---------
 util/importer.py          |  2 +-
 10 files changed, 91 insertions(+), 46 deletions(-)
 create mode 100644 .dockerignore

diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..aaca40b6
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,19 @@
+.dockerignore
+Dockerfile
+db.sqlite3
+__pycache__
+*.pyc
+*.pyo
+*.pyd
+.Python
+env
+pip-log.txt
+pip-delete-this-directory.txt
+.tox
+.coverage
+.coverage.*
+.cache
+coverage.xml
+*,cover
+*.log
+.git
diff --git a/.gitignore b/.gitignore
index 01d0435e..1975c944 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ scripts/
 
 # yarn stuff
 node_modules
+.pylintrc
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7a9b1d10..880a1b3e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,8 +9,6 @@ variables:
 
 build:
         image: docker:latest
-        services:
-                - docker:dind
         stage: build
         script:
                 - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
@@ -28,12 +26,24 @@ test:
 
 staging:
         stage: staging
-        image: $IMAGE_TAG
-        services:
-                - postgres:9.5
+        image: docker:latest
         environment:
                 name: review/$CI_COMMIT_REF_NAME
                 url: https://staging.grady.janmax.org
+                on_stop: staging_stop
         script:
-                - python3 manage.py migrate --noinput
-                - python3 manage.py loaddata core/fixtures/testdata-groups.json
+                - apk add --update py-pip && pip install docker-compose
+                - docker-compose up -d
+
+staging_stop:
+        stage: staging
+        image: docker:latest
+        variables:
+                GIT_STRATEGY: none
+        script:
+                - apk add --update py-pip && pip install docker-compose
+                - docker-compose rm --force --stop
+        when: manual
+        environment:
+                name: review/$CI_COMMIT_REF_NAME
+                action: stop
diff --git a/Dockerfile b/Dockerfile
index d7368bbc..945d8944 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,23 +1,33 @@
+# Build Python files
+FROM python:3.6 as python
+COPY requirements.txt .
+RUN pip install -r requirements.txt
+RUN curl https://gitlab.gwdg.de/snippets/51/raw --output words
+
+# Retrieve noes files
+FROM node:latest as node
+COPY package.json .
+RUN yarn
+
+# Now fetch other files and build on small image
 FROM python:3.6-alpine
 
 ENV PYTHONUNBUFFERED 1
 
-RUN apk add --no-cache nodejs
-RUN apk add --no-cache postgresql-dev
-RUN apk add --no-cache gcc
-RUN apk add --no-cache musl-dev
-RUN apk add --no-cache libxslt-dev
-RUN apk add --no-cache bash
-RUN apk add --no-cache curl
-RUN npm install yarn -g
+# This set is need otherwise the postgres driver wont work
+RUN apk update \
+  && apk add --virtual build-deps gcc python3-dev musl-dev \
+  && apk add postgresql-dev \
+  && pip install psycopg2 \
+  && apk del build-deps
 
+RUN mkdir -p /usr/share/dict
 RUN mkdir /code
-ADD requirements.txt /code/
-ADD . /code/
-
 WORKDIR /code
-RUN pip install -r requirements.txt
-RUN yarn install --modules-folder core/static/node_modules
 
-RUN mkdir -p /usr/share/dict
-RUN curl https://gitlab.gwdg.de/snippets/51/raw --output /usr/share/dict/words
+COPY . /code
+COPY --from=python /root/.cache /root/.cache
+COPY --from=python /words /usr/share/dict/words
+COPY --from=node   /node_modules core/static/node_modules
+
+RUN pip install -r requirements.txt && rm -rf /root/.cache
diff --git a/Makefile b/Makefile
index ecdf60d6..f9c953e4 100644
--- a/Makefile
+++ b/Makefile
@@ -22,8 +22,8 @@ loaddata:
 	./manage.py loaddata core/fixtures/testdata-groups.json
 
 loadexamples:
-	./manage.py loaddata core/fixtures/testdata-core.json
 	./manage.py loaddata core/fixtures/testdata-user.json
+	./manage.py loaddata core/fixtures/testdata-core.json
 
 install:
 	pip install -r requirements.txt
diff --git a/core/models.py b/core/models.py
index f9f2bcb0..8e8f10a8 100644
--- a/core/models.py
+++ b/core/models.py
@@ -2,7 +2,7 @@
 Grady Model Description
 -----------------------
 
-See docstrings of the individual models for information on the setup of the
+See docstring of the individual models for information on the setup of the
 database.
 '''
 
diff --git a/docker-compose.yml b/docker-compose.yml
index 8af15b4d..db46564a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -6,15 +6,19 @@ services:
   web:
     build: .
     command:
-      - bash
+      - /bin/sh
       - -c
       - |
+        python3 manage.py compress
+        python3 manage.py collectstatic
         python3 manage.py migrate --noinput
         python3 manage.py loaddata core/fixtures/testdata-groups.json
-        gunicorn --bind 0.0.0.0:8000 grady.wsgi
-    volumes:
-      - .:/code
+        python3 manage.py loaddata core/fixtures/testdata-user.json
+        python3 manage.py loaddata core/fixtures/testdata-core.json
+        gunicorn --bind 0.0.0.0:8000 grady.wsgi:application
     ports:
       - "8000:8000"
+    volumes:
+      - /var/www/static:/code/static
     depends_on:
       - postgres
diff --git a/grady/settings/default.py b/grady/settings/default.py
index d96dd4d2..758f7102 100644
--- a/grady/settings/default.py
+++ b/grady/settings/default.py
@@ -79,12 +79,12 @@ WSGI_APPLICATION = 'grady.wsgi.application'
 
 DATABASES = {
     'default': {
-       'ENGINE': 'django.db.backends.postgresql_psycopg2',
-       'NAME': 'postgres',
-       'USER': 'postgres',
-       'PASSWORD': 'postgres',
-       'HOST': '0.0.0.0',
-       'PORT': '5432',
+        'ENGINE': 'django.db.backends.postgresql_psycopg2',
+        'NAME': 'postgres',
+        'USER': 'postgres',
+        'PASSWORD': 'postgres',
+        'HOST': 'localhost',
+        'PORT': '5432',
     },
 }
 
@@ -139,9 +139,8 @@ MESSAGE_TAGS = {
     messages.ERROR: 'alert-danger',
 }
 
-COMPRESS_ENABLED = not DEBUG
+COMPRESS_ENABLED = False
 COMPRESS_OFFLINE = True
-COMPRESS_ROOT    = '/compress/'
 
 STATICFILES_FINDERS = (
     'django.contrib.staticfiles.finders.FileSystemFinder',
diff --git a/grady/settings/live.py b/grady/settings/live.py
index fcd378e4..c0e2938c 100644
--- a/grady/settings/live.py
+++ b/grady/settings/live.py
@@ -1,4 +1,4 @@
-# Some deploy settings to enhance security
+""" A live configuration for enhanced security """
 CSRF_COOKIE_SECURE = True
 CSRF_COOKIE_HTTPONLY = True
 SESSION_COOKIE_SECURE = True
@@ -6,20 +6,22 @@ SECURE_CONTENT_TYPE_NOSNIFF = True
 SECURE_BROWSER_XSS_FILTER = True
 X_FRAME_OPTIONS = 'DENY'
 
+
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = False
+COMPRESS_ENABLED = not DEBUG
 
 # adjust this setting to your needs
-ALLOWED_HOSTS = ['localhost', 'grady.janmax.org']
+ALLOWED_HOSTS = ['localhost', '.janmax.org']
 
-# sample postgre sql database configuration
+# sample postgres sql database configuration
 DATABASES = {
     'default': {
-       'ENGINE': 'django.db.backends.postgresql_psycopg2',
-       'NAME': 'postgres',
-       'USER': 'postgres',
-       'PASSWORD': 'postgres',
-       'HOST': 'postgres',
-       'PORT': '5432',
+        'ENGINE': 'django.db.backends.postgresql_psycopg2',
+        'NAME': 'postgres',
+        'USER': 'postgres',
+        'PASSWORD': 'postgres',
+        'HOST': 'postgres',
+        'PORT': '5432',
     },
 }
diff --git a/util/importer.py b/util/importer.py
index b20b0b51..8e341e63 100644
--- a/util/importer.py
+++ b/util/importer.py
@@ -12,7 +12,7 @@ import util.convert
 import util.processing
 from core.models import (ExamType, Feedback, Student, Submission,
                          SubmissionType, Test)
-from util.messages import *
+from util.messages import info, warn
 from util.processing import EmptyTest
 
 STUDENTS  = 'Students'
-- 
GitLab