From bcaa0664688857b180bb908a6ea1b71080c56a45 Mon Sep 17 00:00:00 2001
From: Athanasios Lakes <atla8167@dsv.su.se>
Date: Thu, 12 Dec 2024 14:09:51 +0100
Subject: [PATCH] Dockerization

---
 docker-compose-deploy.yml              |  26 +++
 {extremum_web => extremum}/__init__.py |   0
 {extremum_web => extremum}/asgi.py     |   0
 {extremum_web => extremum}/pyvenv.cfg  |   0
 {extremum_web => extremum}/routing.py  |   0
 {extremum_web => extremum}/settings.py |  26 +--
 {extremum_web => extremum}/urls.py     |   0
 {extremum_web => extremum}/wsgi.py     |   2 +-
 proxy/default.conf                     |  12 ++
 proxy/uwsgi_params                     |  13 ++
 requirements.txt                       | 252 +++++++++++++++----------
 scripts/entrypoint.sh                  |  10 +
 12 files changed, 223 insertions(+), 118 deletions(-)
 create mode 100644 docker-compose-deploy.yml
 rename {extremum_web => extremum}/__init__.py (100%)
 rename {extremum_web => extremum}/asgi.py (100%)
 rename {extremum_web => extremum}/pyvenv.cfg (100%)
 rename {extremum_web => extremum}/routing.py (100%)
 rename {extremum_web => extremum}/settings.py (85%)
 rename {extremum_web => extremum}/urls.py (100%)
 rename {extremum_web => extremum}/wsgi.py (81%)
 create mode 100644 proxy/default.conf
 create mode 100644 proxy/uwsgi_params
 create mode 100644 scripts/entrypoint.sh

diff --git a/docker-compose-deploy.yml b/docker-compose-deploy.yml
new file mode 100644
index 000000000..edd4e208a
--- /dev/null
+++ b/docker-compose-deploy.yml
@@ -0,0 +1,26 @@
+version: '3.8'
+
+services:
+  app:
+    build:
+      context: .
+    volumes:
+      - static_data/vol/web
+    env_file:
+      - .env
+    environment:
+      - SECRET_KEY=${SECRET_KEY}
+      - ALLOWED_HOSTS=${ALLOWED_HOSTS}
+
+  proxy:
+    build:
+      context: ./proxy
+    volumes:
+      - static_data:/vol/static
+    ports:
+      - "8080:8080"
+    depends_on:
+      - extremum
+
+volumes:
+  static_data:
diff --git a/extremum_web/__init__.py b/extremum/__init__.py
similarity index 100%
rename from extremum_web/__init__.py
rename to extremum/__init__.py
diff --git a/extremum_web/asgi.py b/extremum/asgi.py
similarity index 100%
rename from extremum_web/asgi.py
rename to extremum/asgi.py
diff --git a/extremum_web/pyvenv.cfg b/extremum/pyvenv.cfg
similarity index 100%
rename from extremum_web/pyvenv.cfg
rename to extremum/pyvenv.cfg
diff --git a/extremum_web/routing.py b/extremum/routing.py
similarity index 100%
rename from extremum_web/routing.py
rename to extremum/routing.py
diff --git a/extremum_web/settings.py b/extremum/settings.py
similarity index 85%
rename from extremum_web/settings.py
rename to extremum/settings.py
index 0de4f113e..69b2ada44 100755
--- a/extremum_web/settings.py
+++ b/extremum/settings.py
@@ -20,20 +20,17 @@ BASE_DIR = Path(__file__).resolve().parent.parent
 # Quick-start development settings - unsuitable for production
 # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
 
-from dotenv import load_dotenv
-env_path = load_dotenv(os.path.join(BASE_DIR, '.env'))
-load_dotenv(env_path)
-
-SECRET_KEY = os.getenv('SECRET_KEY', "django-insecure-0w^ybt_7vclag#rrutc_eo)m+l^@ml)t%jsg6n06siu)xyls+-")
+SECRET_KEY = os.environ.get('SECRET_KEY', "changeme")
 
 # DEBUG setting
-DEBUG = os.getenv('DEBUG', 'False') == 'True'
+DEBUG = bool(int(os.environ('DEBUG', 0)))
 
-ALLOWED_HOSTS = ['127.0.0.1']
+ALLOWED_HOSTS = []
+ALLOWED_HOSTS_ENV = os.environ.get('ALLOWED_HOSTS')
+if ALLOWED_HOSTS_ENV :
+    ALLOWED_HOSTS.extend(ALLOWED_HOSTS_ENV.split(','))
 
 DEBUG_PROPAGATE_EXCEPTIONS = True
-
-
 SECURE_HSTS_SECONDS = 31536000  # One year
 SECURE_HSTS_INCLUDE_SUBDOMAINS = True
 SECURE_HSTS_PRELOAD = True
@@ -66,7 +63,7 @@ MIDDLEWARE = [
     "django_htmx.middleware.HtmxMiddleware",
 ]
 
-ROOT_URLCONF = "extremum_web.urls"
+ROOT_URLCONF = "extremum.urls"
 
 TEMPLATES = [
     {
@@ -84,7 +81,7 @@ TEMPLATES = [
     },
 ]
 
-WSGI_APPLICATION = "extremum_web.wsgi.application"
+WSGI_APPLICATION = "extremum.wsgi.application"
 
 
 # Database
@@ -124,10 +121,13 @@ AUTH_PASSWORD_VALIDATORS = [
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/5.0/howto/static-files/
 
-STATIC_URL = "/static/"
+STATIC_URL = "/static/static"
 STATICFILES_DIRS = [BASE_DIR / "base/static"]
 
-STATIC_ROOT = BASE_DIR / 'staticfiles'  # Define where static files are collected
+MEDIA_URL = "/static/media"
+
+STATIC_ROOT = BASE_DIR / 'vol/web/static'  # Define where static files are collected
+MEDIA_ROOT = BASE_DIR / 'vol/web/media'  # Define where static files are collected
 
 # Default primary key field type
 # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
diff --git a/extremum_web/urls.py b/extremum/urls.py
similarity index 100%
rename from extremum_web/urls.py
rename to extremum/urls.py
diff --git a/extremum_web/wsgi.py b/extremum/wsgi.py
similarity index 81%
rename from extremum_web/wsgi.py
rename to extremum/wsgi.py
index 13482e386..3d2e2bdee 100755
--- a/extremum_web/wsgi.py
+++ b/extremum/wsgi.py
@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'extremum_web.settings')
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'extremum.settings')
 
 application = get_wsgi_application()
diff --git a/proxy/default.conf b/proxy/default.conf
new file mode 100644
index 000000000..91fe085b2
--- /dev/null
+++ b/proxy/default.conf
@@ -0,0 +1,12 @@
+server {
+    listen 8080;
+
+    location /static {
+        alias /vol/static;
+    }
+
+    location / {
+        uwsgi_pass app:8000;
+        include /etc/nginx/uwsgi_params;
+    }
+}
\ No newline at end of file
diff --git a/proxy/uwsgi_params b/proxy/uwsgi_params
new file mode 100644
index 000000000..4f3b520fe
--- /dev/null
+++ b/proxy/uwsgi_params
@@ -0,0 +1,13 @@
+uwsgi_param QUERY_STRING $query_string;
+uwsgi_param REQUEST_METHOD $request_method;
+uwsgi_param CONTENT_TYPE $content_type;
+uwsgi_param CONTENT_LENGTH $content_length;
+uwsgi_param REQUEST_URI $request_uri;
+uwsgi_param PATH_INFO $document_uri;
+uwsgi_param DOCUMENT_ROOT $document_root;
+uwsgi_param SERVER_PROTOCOL $server_protocol;
+uwsgi_param REMOTE_ADDR $remote_addr;
+uwsgi_param REMOTE_PORT $remote_port;
+uwsgi_param SERVER_ADDR $server_addr;
+uwsgi_param SERVER_PORT $server_port;
+uwsgi_param SERVER_NAME $server_name;
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 3ea681ec5..fe31face0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,193 +1,237 @@
+absl-py==2.1.0
+alembic==1.13.2
 anyio==4.4.0
 argon2-cffi==23.1.0
 argon2-cffi-bindings==21.2.0
+args==0.1.0
 arrow==1.3.0
 asgiref==3.8.1
 asttokens==2.4.1
+astunparse==1.6.3
 async-lru==2.0.4
+async-timeout==4.0.3
 attrs==23.2.0
+autobahn==23.6.2
+Automat==22.10.0
+autopage==0.5.2
 Babel==2.15.0
-backcall==0.2.0
 beautifulsoup4==4.12.3
-black==24.4.2
 bleach==6.1.0
-blinker==1.4
-cached-property==1.5.1
-certifi==2019.11.28
+blinker==1.8.2
+cachetools==5.4.0
+certifi==2024.6.2
 cffi==1.16.0
-chardet==3.0.4
+channels==4.1.0
+channels-redis==4.2.0
 charset-normalizer==3.3.2
 click==8.1.7
-cloud-init==24.3.1
-codecov==2.1.13
-collective.checkdocs==0.2
+cliff==4.7.0
+clint==0.5.1
+cmaes==0.10.0
+cmd2==2.4.3
+colorlog==6.8.2
 comm==0.2.2
-configobj==5.0.6
+constantly==23.10.4
 contourpy==1.2.1
-coverage==7.5.1
-crayons==0.4.0
-cryptography==2.8
+coverage==7.6.1
+cryptography==42.0.8
 cycler==0.12.1
-dbus-python==1.2.16
-debugpy==1.8.1
+Cython==3.0.10
+daphne==4.1.2
+dash==2.9.3
+dash-bootstrap-components==1.6.0
+dash-core-components==2.0.0
+dash-html-components==2.0.0
+dash-table==5.0.0
+debugpy==1.8.2
 decorator==5.1.1
 defusedxml==0.7.1
-distlib==0.3.8
-distro==1.4.0
-dj-database-url==2.3.0
-Django==5.0.6
-docker==4.1.0
-docker-compose==1.25.0
-dockerpty==0.4.1
-docopt==0.6.2
-docutils==0.21.2
+dice-ml==0.11
+dict-and-html==1.0.11
+diff-match-patch==20230430
+Django==4.2.13
+django-bootstrap-v5==1.0.11
+django-htmx==1.18.0
+django-import-export==4.0.3
+django-plotly-dash==2.3.1
+django-redis==5.4.0
+dpd_components==0.1.0
 et-xmlfile==1.1.0
 exceptiongroup==1.2.1
 executing==2.0.1
-fastjsonschema==2.19.1
-filelock==3.14.0
-flake8==7.0.0
-fonttools==4.53.0
+fastdtw==0.3.4
+fastjsonschema==2.20.0
+Flask==3.0.3
+flatbuffers==1.12
+fonttools==4.51.0
 fqdn==1.5.1
-fs==2.4.16
-gease==0.0.11
-gunicorn==23.0.0
+gast==0.4.0
+google-auth==2.32.0
+google-auth-oauthlib==0.4.6
+google-pasta==0.2.0
+greenlet==3.0.3
+grpcio==1.65.1
 h11==0.14.0
+h5py==3.11.0
+html-and-py==1.0.14
 httpcore==1.0.5
 httpx==0.27.0
-idna==2.8
-importlib-metadata==1.5.0
-ipykernel==6.29.4
-ipython==8.12.3
+hyperlink==21.0.0
+idna==3.7
+imbalanced-learn==0.12.3
+incremental==22.10.0
+ipykernel==6.29.5
+ipython==8.25.0
+ipywidgets==8.1.3
 isoduration==20.11.0
-isort==5.13.2
+itsdangerous==2.2.0
 jedi==0.19.1
 Jinja2==3.1.4
-jinja2-fsloader==0.3.0
 joblib==1.4.2
 json5==0.9.25
-jsonpatch==1.22
-jsonpointer==2.0
+jsonpointer==3.0.0
 jsonschema==4.22.0
 jsonschema-specifications==2023.12.1
+jupyter==1.0.0
+jupyter_client==8.6.2
+jupyter-console==6.6.3
+jupyter_core==5.7.2
 jupyter-events==0.10.0
 jupyter-lsp==2.2.5
-jupyter_client==8.6.1
-jupyter_core==5.7.2
-jupyter_server==2.14.1
+jupyter_server==2.14.2
 jupyter_server_terminals==0.5.3
-jupyterlab==4.2.1
+jupyterlab==4.2.4
 jupyterlab_pygments==0.3.0
-jupyterlab_server==2.27.2
+jupyterlab_server==2.27.3
+jupyterlab_widgets==3.0.11
+keract==4.5.1
+keras==2.9.0
+Keras-Preprocessing==1.1.2
 kiwisolver==1.4.5
+libclang==18.1.1
 llvmlite==0.43.0
-lml==0.1.0
-lxml==5.2.2
+Mako==1.3.5
+mamba==0.11.3
+Markdown==3.6
 MarkupSafe==2.1.5
 matplotlib==3.9.0
 matplotlib-inline==0.1.7
-mccabe==0.7.0
 mistune==3.0.2
-moban==0.8.2
-moban-jinja2-github==0.0.4
-more-itertools==4.2.0
-mypy-extensions==1.0.0
+ml-dtypes==0.4.0
+mlxtend==0.23.1
+msgpack==1.0.8
 nbclient==0.10.0
 nbconvert==7.16.4
+nbeats-keras==1.8.0
 nbformat==5.10.4
 nest-asyncio==1.6.0
-netifaces==0.10.4
-nose==1.3.7
+ngrok==1.4.0
+notebook==7.2.1
 notebook_shim==0.2.4
+npx==0.1.6
 numba==0.60.0
-numpy==1.26.4
-oauthlib==3.1.0
+numpy==1.23.5
+nvidia-cublas-cu11==11.11.3.6
+oauthlib==3.2.2
 openpyxl==3.1.2
+opt-einsum==3.3.0
+optuna==2.10.1
 overrides==7.7.0
-packaging==24.0
-pandas==2.2.2
+packaging==24.2
+pandas==1.5.3
 pandocfilters==1.5.1
 parso==0.8.4
-pathspec==0.12.1
-pexpect==4.6.0
-pickleshare==0.7.5
+patsy==0.5.6
+pbr==6.0.0
+pexpect==4.9.0
 pillow==10.3.0
-pip-chill==1.0.3
-pipenv==2023.12.1
-pipreqs==0.5.0
+pip==24.3.1
+pipdeptree==2.24.0
 platformdirs==4.2.2
+plotly==5.22.0
+prettytable==3.10.2
 prometheus_client==0.20.0
-prompt-toolkit==3.0.43
-psutil==5.9.8
-psycopg2-binary==2.9.10
+prompt_toolkit==3.0.47
+protobuf==3.19.6
+psutil==6.0.0
 ptyprocess==0.7.0
 pure-eval==0.2.2
-pycairo==1.16.2
-pycodestyle==2.11.1
+pyasn1==0.6.0
+pyasn1_modules==0.4.0
 pycparser==2.22
-pyecharts-jupyter-installer==0.0.3
-pyexcel==0.7.0
-pyexcel-ezodf==0.3.4
-pyexcel-handsontable==0.0.2
-pyexcel-io==0.6.6
-pyexcel-ods3==0.6.1
-pyexcel-pygal==0.0.2
-pyexcel-webio==0.1.4
-pyexcel-xls==0.7.0
-pyexcel-xlsx==0.6.0
-pyflakes==3.2.0
-pygal==3.0.4
 Pygments==2.18.0
-PyGObject==3.36.0
-PyJWT==1.7.1
-pyOpenSSL==19.0.0
+pyOpenSSL==24.1.0
 pyparsing==3.1.2
-pyrsistent==0.15.5
-pyserial==3.4
-python-apt==2.0.1+ubuntu0.20.4.1
+pyperclip==1.9.0
 python-dateutil==2.9.0.post0
 python-dotenv==1.0.1
 python-json-logger==2.0.7
 pytz==2024.1
-PyYAML==5.3.1
+PyWavelets==1.6.0
+PyYAML==6.0.1
 pyzmq==26.0.3
+qtconsole==5.5.2
+QtPy==2.4.1
+raiutils==0.4.2
+redis==5.0.6
 referencing==0.35.1
 requests==2.32.3
+requests-oauthlib==2.0.0
 rfc3339-validator==0.1.4
 rfc3986-validator==0.1.1
 rpds-py==0.18.1
-scikit-learn==1.5.0
-scipy==1.13.1
+rsa==4.9
+scikit-base==0.8.2
+scikit-learn==1.5.1
+scipy==1.13.0
+seaborn==0.13.2
 Send2Trash==1.8.3
-six==1.14.0
+service-identity==24.1.0
+setuptools==65.5.0
+six==1.16.0
+sktime==0.31.0
 sniffio==1.3.1
-sos==4.7.2
 soupsieve==2.5
+SQLAlchemy==2.0.31
 sqlparse==0.5.0
-ssh-import-id==5.10
 stack-data==0.6.3
+statsmodels==0.14.2
+stevedore==5.2.0
 stumpy==1.13.0
+tablib==3.5.0
+tenacity==8.3.0
+tensorboard==2.9.1
+tensorboard-data-server==0.6.1
+tensorboard-plugin-wit==1.8.1
+tensorflow==2.9.1
+tensorflow-estimator==2.9.0
+tensorflow-io-gcs-filesystem==0.37.1
+termcolor==2.4.0
 terminado==0.18.1
-texttable==1.6.2
+tfts==0.0.5
 threadpoolctl==3.5.0
 tinycss2==1.3.0
 tomli==2.0.1
-tornado==6.4
+tornado==6.4.1
+tqdm==4.66.4
 traitlets==5.14.3
+Twisted==24.3.0
+txaio==23.1.1
 types-python-dateutil==2.9.0.20240316
 typing_extensions==4.11.0
-tzdata==2024.1
-ufw==0.36
 uri-template==1.3.0
-urllib3==1.25.8
-virtualenv==20.26.2
-virtualenv-clone==0.5.7
+urllib3==2.2.1
+uWSGI==2.0.28
 wcwidth==0.2.13
-webcolors==24.6.0
+webcolors==24.8.0
 webencodings==0.5.1
 websocket-client==1.8.0
+Werkzeug==3.0.3
+wheel==0.44.0
+whitenoise==6.8.2
+widgetsnbextension==4.0.11
 wildboar==1.2.0
-xlrd==2.0.1
-xlwt==1.3.0
-yarg==0.1.9
-zipp==1.0.0
+wrapt==1.16.0
+xgboost==2.0.3
+XlsxWriter==3.2.0
+zope.interface==6.4.post2
\ No newline at end of file
diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh
new file mode 100644
index 000000000..c6c76f3cc
--- /dev/null
+++ b/scripts/entrypoint.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+python manage.py collectstatic --soinput
+
+uwsgi --socket :8000 --master --enable-threads --module extremum.wsgi #TCP
+
+# Start Apache
+exec apachectl -D FOREGROUND
\ No newline at end of file