From 7fad75fc088eeb53b24227ee56f74d1274cad6df Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 23:48:59 +0200 Subject: [PATCH 1/4] Dockerize the application --- Dockerfile | 22 +++++++++++++ app/config.example.py | 7 ++++- app/hlds/definitions.py | 7 +++-- app/migrations/versions/150252c1cdb1_.py | 4 +-- .../9159a6fed021_initial_haldis_support.py | 5 ++- app/wsgi.py | 16 ++++++++++ docker-compose.override.yml | 17 ++++++++++ docker-compose.yml | 31 +++++++++++++++++++ 8 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 app/wsgi.py create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..949823d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 +FROM python:3.9.2-slim AS development + +WORKDIR /src + +RUN pip install pymysql + +COPY requirements.txt . +RUN pip install -r requirements.txt + +COPY . . + +WORKDIR /src/app +CMD python app.py db upgrade && \ + python app.py runserver -h 0.0.0.0 -p 8000 + +FROM development AS production + +RUN pip install waitress + +CMD python app.py db upgrade && \ + python wsgi.py diff --git a/app/config.example.py b/app/config.example.py index 1b016a8..ae60a55 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -1,11 +1,16 @@ """An example for a Haldis config""" -# config +# import os class Configuration: "Haldis configuration object" # pylint: disable=too-few-public-methods SQLALCHEMY_DATABASE_URI = "sqlite:///haldis.db" + # MARIADB_HOST = os.environ.get("MARIADB_HOST") + # MARIADB_DB = os.environ.get("MARIADB_DATABASE") + # MARIADB_USER = os.environ.get("MARIADB_USER") + # MARIADB_PASS = os.environ.get("MARIADB_PASSWORD") + # SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MARIADB_USER}:{MARIADB_PASS}@{MARIADB_HOST}/{MARIADB_DB}" SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = True HALDIS_ADMINS = [] diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 7f6e0c1..1e540e7 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -17,5 +17,8 @@ DATA_DIR = ROOT_DIR / "menus" location_definitions: List[Location] = parse_all_directory(str(DATA_DIR)) location_definitions.sort(key=lambda l: l.name) -proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=str(ROOT_DIR), check=True) -location_definition_version = proc.stdout.decode().strip() +try: + proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=str(ROOT_DIR), check=True) + location_definition_version = proc.stdout.decode().strip() +except FileNotFoundError: + location_definition_version = "" diff --git a/app/migrations/versions/150252c1cdb1_.py b/app/migrations/versions/150252c1cdb1_.py index 927c101..77c7961 100644 --- a/app/migrations/versions/150252c1cdb1_.py +++ b/app/migrations/versions/150252c1cdb1_.py @@ -43,7 +43,7 @@ def upgrade(): sa.Column("starttime", sa.DateTime(), nullable=True), sa.Column("stoptime", sa.DateTime(), nullable=True), sa.Column("public", sa.Boolean(), nullable=True), - sa.ForeignKeyConstraint(["location_id"], ["location.id"]), + sa.ForeignKeyConstraint(["location_id"], ["location.id"], name="order_ibfk_1"), sa.PrimaryKeyConstraint("id"), ) op.create_table( @@ -65,7 +65,7 @@ def upgrade(): sa.Column("extra", sa.String(length=254), nullable=True), sa.Column("name", sa.String(length=120), nullable=True), sa.ForeignKeyConstraint(["order_id"], ["order.id"]), - sa.ForeignKeyConstraint(["product_id"], ["product.id"]), + sa.ForeignKeyConstraint(["product_id"], ["product.id"], name="order_item_ibfk_3"), sa.ForeignKeyConstraint(["user_id"], ["user.id"]), sa.PrimaryKeyConstraint("id"), ) diff --git a/app/migrations/versions/9159a6fed021_initial_haldis_support.py b/app/migrations/versions/9159a6fed021_initial_haldis_support.py index 710feb2..70ce1d7 100644 --- a/app/migrations/versions/9159a6fed021_initial_haldis_support.py +++ b/app/migrations/versions/9159a6fed021_initial_haldis_support.py @@ -112,14 +112,12 @@ def upgrade(): ) ) # Historical product data migrated, drop obsolete column and table - op.execute(text("ALTER TABLE order_item DROP FOREIGN KEY order_item_ibfk_3")) + op.drop_constraint("order_item_ibfk_3", "order_item", type_="foreignkey") op.drop_column("order_item", "product_id") op.drop_table("product") # ---------------------------------------------------------------------------------------------- # Migrate historical location data to orders - - op.execute(text("ALTER TABLE `order` DROP FOREIGN KEY order_ibfk_2")) op.alter_column( "order", "location_id", @@ -157,6 +155,7 @@ def upgrade(): for query in chain(new_location_id, [location_name_from_location]): op.execute(query) # Historical location data migrated, drop obsolete column and table + op.drop_constraint("order_ibfk_1", "order", type_="foreignkey") op.drop_column("order", "legacy_location_id") op.drop_table("location") diff --git a/app/wsgi.py b/app/wsgi.py new file mode 100644 index 0000000..d23f6f5 --- /dev/null +++ b/app/wsgi.py @@ -0,0 +1,16 @@ +import sentry_sdk +from sentry_sdk.integrations.flask import FlaskIntegration +from waitress import serve + +from app import create_app +from config import Configuration + +if __name__ == "__main__": + if Configuration.SENTRY_DSN: + sentry_sdk.init( + dsn=Configuration.SENTRY_DSN, + integrations=[FlaskIntegration()] + ) + + app, app_mgr = create_app() + serve(app_mgr, host="0.0.0.0", port=8000) diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..536e11b --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,17 @@ +version: "3.4" + +services: + app: + build: + target: "development" + environment: + - MARIADB_DATABASE=haldis + - MARIADB_USER=haldis + - MARIADB_PASSWORD=haldis + volumes: ["$PWD:/src"] + database: + environment: + - MARIADB_DATABASE=haldis + - MARIADB_ROOT_PASSWORD=mariadb + - MARIADB_USER=haldis + - MARIADB_PASSWORD=haldis \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..297cffd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: "3.4" + +services: + app: + build: + context: . + target: production + restart: on-failure + depends_on: [database] + ports: ["8000:8000"] + environment: + - MARIADB_HOST=database + - MARIADB_DATABASE + - MARIADB_USER + - MARIADB_PASSWORD + networks: [haldis] + database: + image: mariadb:10.8 + hostname: database + restart: on-failure + environment: + - MARIADB_DATABASE + - MARIADB_ROOT_PASSWORD + - MARIADB_USER + - MARIADB_PASSWORD + networks: [haldis] + volumes: [haldis_data:/var/lib/mysql] +networks: + haldis: +volumes: + haldis_data: \ No newline at end of file From a29d3a33be1959597fc3be666e0b894335f77e03 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 02:33:36 +0200 Subject: [PATCH 2/4] Use correct app when running with waitress --- Dockerfile | 2 +- app/{wsgi.py => waitress_wsgi.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/{wsgi.py => waitress_wsgi.py} (89%) diff --git a/Dockerfile b/Dockerfile index 949823d..c8381ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,4 +19,4 @@ FROM development AS production RUN pip install waitress CMD python app.py db upgrade && \ - python wsgi.py + python waitress_wsgi.py diff --git a/app/wsgi.py b/app/waitress_wsgi.py similarity index 89% rename from app/wsgi.py rename to app/waitress_wsgi.py index d23f6f5..579aa92 100644 --- a/app/wsgi.py +++ b/app/waitress_wsgi.py @@ -13,4 +13,4 @@ if __name__ == "__main__": ) app, app_mgr = create_app() - serve(app_mgr, host="0.0.0.0", port=8000) + serve(app, host="0.0.0.0", port=8000) From 7b78e7d8fff862534ac694dcc0650d0e9f9a1919 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 19:50:23 +0200 Subject: [PATCH 3/4] Add .dockerignore --- .dockerignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d10c610 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +# Ignore everything +* + +# Include source, config and scripts +!app +!etc +!menus +!*.md +!*.sh +!*.txt +!LICENSE From 45b49136578b2afde04f9527e4cbd7b36f109526 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 20:12:21 +0200 Subject: [PATCH 4/4] Add menus provided by Zeus WPI by default --- .dockerignore | 1 - Dockerfile | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index d10c610..9e692b1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,7 +4,6 @@ # Include source, config and scripts !app !etc -!menus !*.md !*.sh !*.txt diff --git a/Dockerfile b/Dockerfile index c8381ec..5c2add3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,10 @@ WORKDIR /src RUN pip install pymysql +ADD https://git.zeus.gent/haldis/menus/-/archive/master/menus-master.tar /tmp +RUN mkdir menus && \ + tar --directory=menus --extract --strip-components=1 --file=/tmp/menus-master.tar + COPY requirements.txt . RUN pip install -r requirements.txt