From c8fd8aab7702cabac3588787dd9f09749e726c7a Mon Sep 17 00:00:00 2001
From: Bryan Brancotte <bryan.brancotte@pasteur.fr>
Date: Fri, 18 Mar 2022 13:19:29 +0100
Subject: [PATCH] multistage container

---
 .gitlab-ci.yml                       | 29 +++++++++++++++++++++-------
 docker-compose.yaml                  |  4 ++--
 ippisite/Dockerfile                  | 29 +++++++++++++++++++++++++---
 ippisite/docker-celery-entrypoint.sh | 26 +++++++++++++++++++++++++
 ippisite/notes.md                    |  2 +-
 5 files changed, 77 insertions(+), 13 deletions(-)
 create mode 100644 ippisite/docker-celery-entrypoint.sh

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7f6a67b5..be117712 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -31,7 +31,7 @@ test-style:
       -e POSTGRES_DB=$POSTGRES_DB
       -e POSTGRES_USER=$POSTGRES_USER
       -v  $(pwd)/persistent:/code/persistent
-      "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"
+      "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/web-container:$CI_COMMIT_SHA"
       test
     - mv persistent/htmlcov htmlcov
     - mv persistent/tests_http_cache.sqlite tests_http_cache.sqlite
@@ -94,17 +94,32 @@ pages:
     - docker pull "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest" || true
     # build the image while passing commit SHA and tagging the image with it
     - docker build
+      --target web-container
       --build-arg CI_COMMIT_REF_SLUG
       --build-arg CI_COMMIT_SHA
-      --cache-from "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
-      --cache-from "$CI_REGISTRY_IMAGE/master:latest"
-      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"
-      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
+      --cache-from "$CI_REGISTRY_IMAGE/web-container/$CI_COMMIT_REF_SLUG:latest"
+      --cache-from "$CI_REGISTRY_IMAGE/web-container/master:latest"
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/web-container:$CI_COMMIT_SHA"
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/web-container:latest"
       .
     # push image as latest for the current branch
-    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:latest"
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/web-container:latest"
     # push image tagged with its sha
-    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA"
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/web-container:$CI_COMMIT_SHA"
+    # build the image while passing commit SHA and tagging the image with it
+    - docker build
+      --target celery-container
+      --build-arg CI_COMMIT_REF_SLUG
+      --build-arg CI_COMMIT_SHA
+      --cache-from "$CI_REGISTRY_IMAGE/celery-container/$CI_COMMIT_REF_SLUG:latest"
+      --cache-from "$CI_REGISTRY_IMAGE/celery-container/master:latest"
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/celery-container:$CI_COMMIT_SHA"
+      --tag "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/celery-container:latest"
+      .
+    # push image as latest for the current branch
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/celery-container:latest"
+    # push image tagged with its sha
+    - docker push "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG/celery-container:$CI_COMMIT_SHA"
 
 
 build-ippisite:
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 53e34572..c034881c 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,4 +1,4 @@
-version: "3"
+version: "3.4"
 
 services:
   db-local:
@@ -15,9 +15,9 @@ services:
   django:
     build:
       context: ./ippisite
+      target: web-container
     env_file:
       - ./ippisite/ippisite/settings.example.ini
-    entrypoint: /docker-entrypoint.sh
     command: gunicorn --reload --reload-engine inotify ippisite.wsgi -b 0.0.0.0:8000
     volumes:
       - ./ippisite:/code # for dev purpose only !!!
diff --git a/ippisite/Dockerfile b/ippisite/Dockerfile
index fc424188..a6c8509e 100644
--- a/ippisite/Dockerfile
+++ b/ippisite/Dockerfile
@@ -1,4 +1,7 @@
-FROM python:3.9
+###############################################################################
+# BAse image containing libs, dependencies and code
+###############################################################################
+FROM python:3.9 AS base-container
 
 EXPOSE 8000
 ENV PYTHONPATH "${PYTHONPATH}:/usr/lib/python3/dist-packages"
@@ -25,14 +28,34 @@ RUN pip install -r requirements.txt
 COPY ./*-entrypoint.sh /
 RUN chmod a+x /*-entrypoint.sh
 
+COPY . /code/
+
+
+###############################################################################
+# django web app
+###############################################################################
+FROM base-container AS web-container
+
 ENTRYPOINT ["/docker-entrypoint.sh"]
 
-COPY . /code/
+CMD ["gunicorn", "--bind", ":8000", "ippisite.wsgi:application"]
 
 ENV STATIC_ROOT /static_root
 ENV STATIC_ROOT_ON_STARTUP_COPY="/tmp${STATIC_ROOT}_on_startup_copy"
 RUN python manage.py collectstatic --noinput
 
-CMD ["gunicorn", "--bind", ":8000", "ippisite.wsgi:application"]
+USER kiwi
+
+
+###############################################################################
+# celery worker
+###############################################################################
+FROM base-container AS celery-container
+
+ENTRYPOINT ["/docker-celery-entrypoint.sh"]
+
+CMD ["celery", "multi", "start", "worker", "-Q", "celery-80", "-A", "ippisite", "--pidfile=/ippidb-80-celery/celery.pid", "--logfile=/ippidb-80-celery/celery.log", "--loglevel=INFO", "--time-limit=172800", "--concurrency=1", "--max-tasks-per-child=1"]
+
+CMD ["celery", "-A", "ippisite", "worker", "-l", "info"]
 
 USER kiwi
\ No newline at end of file
diff --git a/ippisite/docker-celery-entrypoint.sh b/ippisite/docker-celery-entrypoint.sh
new file mode 100644
index 00000000..9c1d382c
--- /dev/null
+++ b/ippisite/docker-celery-entrypoint.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+function msg_info {
+   echo -e "\033[1;32m$1\033[0m"
+}
+
+function msg_warning {
+   echo -e "\033[1;33m$1\033[0m"
+}
+
+function msg_error {
+   echo -e "\033[1;31m$1\033[0m"
+}
+
+cd /code
+
+if [ "$1" == "hold_on" ]; then
+    msg_info "holding on util you delete /tmp/hold_on"
+    touch /tmp/hold_on
+    while [ -e "/tmp/hold_on" ]; do
+        sleep 1 ;
+        echo "holding on" ;
+    done
+fi
+
+exec "$@"
diff --git a/ippisite/notes.md b/ippisite/notes.md
index e8519eb6..5cc274ef 100755
--- a/ippisite/notes.md
+++ b/ippisite/notes.md
@@ -1,6 +1,6 @@
 How to build and run the app
 
 ```
-docker build . -t test_ippidb && docker run -it -e ALLOWED_HOSTS=localhost -e SECRET_KEY=a -e "STATIC_URL=/static" -e "POSTGRES_NAME=postgres" -e "POSTGRES
+docker build . -t test_ippidb --target web-container && docker run -it -e ALLOWED_HOSTS=localhost -e SECRET_KEY=a -e "STATIC_URL=/static" -e "POSTGRES_NAME=postgres" -e "POSTGRES
 _USER=postgres" -e "POSTGRES_PASSWORD=postgres" -e "POSTGRES_HOST=db" -e "USE_SQLITE_AS_DB=True" -v $(pwd):/code -p 8095:8000 test_ippidb
 ```
\ No newline at end of file
-- 
GitLab