diff --git a/._.gitignore b/._.gitignore new file mode 100644 index 0000000..714af7c Binary files /dev/null and b/._.gitignore differ diff --git a/.gitignore b/.gitignore index 5d381cc..39c62aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,162 +1,39 @@ -# ---> Python -# Byte-compiled / optimized / DLL files +# Python __pycache__/ -*.py[cod] -*$py.class +*.pyc +*.pyo -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments +# Env / secrets .env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ +.env.* +!.env.example -# Spyder project settings -.spyderproject -.spyproject +# Logs +*.log +logs/ +container-logs/ -# Rope project settings -.ropeproject +# macOS +.DS_Store -# mkdocs documentation -/site +# VS Code +.vscode/ -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json +# Runtime data +db/ +pgdata/ +assets/ +data/ +tmp/ -# Pyre type checker -.pyre/ +# OpenProject / Gitea persistent data +infra/openproject/pgdata/ +infra/openproject/assets/ +infra/gitea/data/ -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Flask runtime +app/flask-postgres/files/uploads/ +app/flask-postgres/files/runtime/ +# Synology +@eaDir/ \ No newline at end of file diff --git a/app/flask-postgres/._Kurzdoku.txt b/app/flask-postgres/._Kurzdoku.txt new file mode 100644 index 0000000..983e907 Binary files /dev/null and b/app/flask-postgres/._Kurzdoku.txt differ diff --git a/app/flask-postgres/Kurzdoku.txt b/app/flask-postgres/Kurzdoku.txt new file mode 100644 index 0000000..16b5050 --- /dev/null +++ b/app/flask-postgres/Kurzdoku.txt @@ -0,0 +1,16 @@ +Kurzdoku FLASK Certification Validation + +Postgres DB: + DB_HOST: db + DB_NAME: CertDB + DB_USER: CertUser + DB_PASSWORD: CertPWD + DB_PORT: 5432 + +app.py + +Postgres admin@kolb.cc +pwd DBadmin +Port 5051 +http://192.168.0.10:5051/browser/ + diff --git a/app/flask-postgres/app/._Dockerfile b/app/flask-postgres/app/._Dockerfile new file mode 100644 index 0000000..4445b4e Binary files /dev/null and b/app/flask-postgres/app/._Dockerfile differ diff --git a/app/flask-postgres/app/._app.py b/app/flask-postgres/app/._app.py new file mode 100644 index 0000000..198e7a5 Binary files /dev/null and b/app/flask-postgres/app/._app.py differ diff --git a/app/flask-postgres/app/._requirements.txt b/app/flask-postgres/app/._requirements.txt new file mode 100644 index 0000000..34e079e Binary files /dev/null and b/app/flask-postgres/app/._requirements.txt differ diff --git a/app/flask-postgres/app/._templates b/app/flask-postgres/app/._templates new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/app/._templates differ diff --git a/app/flask-postgres/app/Dockerfile b/app/flask-postgres/app/Dockerfile new file mode 100644 index 0000000..97a0d9b --- /dev/null +++ b/app/flask-postgres/app/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY app.py . + +EXPOSE 5000 + +CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--access-logfile", "/logs/gunicorn-access.log", "--error-logfile", "/logs/gunicorn-error.log", "app:app"] \ No newline at end of file diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py new file mode 100644 index 0000000..58b936d --- /dev/null +++ b/app/flask-postgres/app/app.py @@ -0,0 +1,327 @@ +import logging +import os +from datetime import datetime +from functools import wraps +from logging.handlers import RotatingFileHandler + +import psycopg2 +from flask import ( + Flask, + redirect, + render_template, + request, + send_from_directory, + session, + url_for, +) +from werkzeug.security import check_password_hash, generate_password_hash + +app = Flask(__name__) +app.secret_key = os.getenv("SECRET_KEY", "change-this-secret-key") + +DB_HOST = os.getenv("DB_HOST", "db") +DB_NAME = os.getenv("DB_NAME", "CertDB") +DB_USER = os.getenv("DB_USER", "CertUser") +DB_PASSWORD = os.getenv("DB_PASSWORD", "CertPWD") +DB_PORT = os.getenv("DB_PORT", "5432") + +LOG_DIR = os.getenv("LOG_DIR", "/logs") +os.makedirs(LOG_DIR, exist_ok=True) + +file_handler = RotatingFileHandler( + os.path.join(LOG_DIR, "flask-app.log"), + maxBytes=5 * 1024 * 1024, + backupCount=5 +) +file_handler.setLevel(logging.INFO) +file_handler.setFormatter( + logging.Formatter("%(asctime)s %(levelname)s %(message)s") +) + +app.logger.setLevel(logging.INFO) +app.logger.addHandler(file_handler) + + +def get_connection(): + return psycopg2.connect( + host=DB_HOST, + dbname=DB_NAME, + user=DB_USER, + password=DB_PASSWORD, + port=DB_PORT, + ) + + +def ensure_base_tables(): + conn = get_connection() + cur = conn.cursor() + + cur.execute(""" + CREATE TABLE IF NOT EXISTS visits ( + id SERIAL PRIMARY KEY, + route_name VARCHAR(100), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS mandant ( + id SERIAL PRIMARY KEY, + kuerzel VARCHAR(50) NOT NULL, + name VARCHAR(255) NOT NULL, + kontakt_email VARCHAR(255), + level INTEGER NOT NULL DEFAULT 0 + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS app_user ( + id SERIAL PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE, + name VARCHAR(255) NOT NULL, + mandant_id INTEGER NOT NULL, + password_hash VARCHAR(255) NOT NULL, + last_login TIMESTAMP NULL, + status INTEGER NOT NULL DEFAULT 0, + CONSTRAINT fk_app_user_mandant + FOREIGN KEY (mandant_id) + REFERENCES mandant(id) + ON DELETE RESTRICT + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS app_group ( + id SERIAL PRIMARY KEY, + mandant_id INTEGER NOT NULL, + group_name VARCHAR(255) NOT NULL, + CONSTRAINT fk_app_group_mandant + FOREIGN KEY (mandant_id) + REFERENCES mandant(id) + ON DELETE CASCADE + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS user_group ( + user_id INTEGER NOT NULL, + group_id INTEGER NOT NULL, + mandant_id INTEGER NOT NULL, + PRIMARY KEY (user_id, group_id), + CONSTRAINT fk_user_group_user + FOREIGN KEY (user_id) + REFERENCES app_user(id) + ON DELETE CASCADE, + CONSTRAINT fk_user_group_group + FOREIGN KEY (group_id) + REFERENCES app_group(id) + ON DELETE CASCADE, + CONSTRAINT fk_user_group_mandant + FOREIGN KEY (mandant_id) + REFERENCES mandant(id) + ON DELETE CASCADE + ) + """) + + conn.commit() + cur.close() + conn.close() + + +def ensure_default_admin(): + conn = get_connection() + cur = conn.cursor() + + cur.execute("SELECT id FROM mandant WHERE kuerzel = %s", ("KOLB",)) + row = cur.fetchone() + + if row: + mandant_id = row[0] + else: + cur.execute(""" + INSERT INTO mandant (kuerzel, name, kontakt_email, level) + VALUES (%s, %s, %s, %s) + RETURNING id + """, ("KOLB", "Kolb Compliance", "info@kolb.cc", 0)) + mandant_id = cur.fetchone()[0] + + cur.execute("SELECT id FROM app_user WHERE email = %s", ("admin@kolb.cc",)) + user_row = cur.fetchone() + + if not user_row: + password_hash = generate_password_hash("topsecret") + cur.execute(""" + INSERT INTO app_user (email, name, mandant_id, password_hash, status) + VALUES (%s, %s, %s, %s, %s) + """, ("admin@kolb.cc", "Admin", mandant_id, password_hash, 1)) + + conn.commit() + cur.close() + conn.close() + + +def register_visit(route_name: str) -> int: + conn = get_connection() + cur = conn.cursor() + + cur.execute( + "INSERT INTO visits (route_name) VALUES (%s)", + (route_name,) + ) + conn.commit() + + cur.execute("SELECT COUNT(*) FROM visits") + count = cur.fetchone()[0] + + cur.close() + conn.close() + return count + + +def get_current_user(): + return { + "user_id": session.get("user_id"), + "user_name": session.get("user_name"), + "user_email": session.get("user_email"), + "is_logged_in": bool(session.get("user_id")), + } + + +def login_required(view_func): + @wraps(view_func) + def wrapper(*args, **kwargs): + if not session.get("user_id"): + return redirect(url_for("login", next=request.path)) + return view_func(*args, **kwargs) + return wrapper + + +def render_page(active_page: str, title: str): + count = register_visit(active_page) + return render_template( + "index.html", + active_page=active_page, + page_title=title, + visit_count=count, + **get_current_user() + ) + + +@app.before_request +def startup_checks(): + ensure_base_tables() + ensure_default_admin() + + +@app.route("/") +@app.route("/home") +def home(): + return render_page("home", "Home") + + +@app.route("/preise") +@login_required +def preise(): + return render_page("preise", "Preise") + + +@app.route("/allgemein") +@login_required +def allgemein(): + return render_page("allgemein", "Allgemein") + + +@app.route("/login", methods=["GET", "POST"]) +def login(): + error_message = "" + next_url = request.args.get("next") or request.form.get("next") or url_for("preise") + + if request.method == "POST": + email = request.form.get("email", "").strip().lower() + password = request.form.get("password", "") + + conn = get_connection() + cur = conn.cursor() + + cur.execute(""" + SELECT id, email, name, password_hash, status + FROM app_user + WHERE lower(email) = %s + """, (email,)) + row = cur.fetchone() + + if not row: + error_message = "Benutzer nicht gefunden." + else: + user_id, user_email, user_name, password_hash, status = row + + if status == 0: + error_message = "Benutzer ist noch nicht aktiviert." + elif status == 2: + error_message = "Benutzer ist gesperrt." + elif status == 3: + error_message = "Benutzer ist deaktiviert." + elif not check_password_hash(password_hash, password): + error_message = "Passwort ist falsch." + else: + session["user_id"] = user_id + session["user_email"] = user_email + session["user_name"] = user_name + + cur.execute(""" + UPDATE app_user + SET last_login = %s + WHERE id = %s + """, (datetime.utcnow(), user_id)) + conn.commit() + + cur.close() + conn.close() + + app.logger.info("Login erfolgreich: %s", user_email) + return redirect(next_url) + + cur.close() + conn.close() + + return render_template( + "login.html", + page_title="Login", + active_page="login", + error_message=error_message, + next_url=next_url, + **get_current_user() + ) + + +@app.route("/logout") +def logout(): + user_email = session.get("user_email", "unknown") + session.clear() + app.logger.info("Logout: %s", user_email) + return redirect(url_for("home")) + + +@app.route("/health") +def health(): + try: + ensure_base_tables() + return "OK\n", 200 + except Exception as exc: + app.logger.exception("Healthcheck fehlgeschlagen: %s", exc) + return f"DB Fehler: {exc}\n", 500 + + +@app.route("/images/") +def serve_image(filename): + return send_from_directory("/app/images", filename) + + +@app.route("/styles/") +def serve_style(filename): + return send_from_directory("/app/styles", filename) + + +@app.route("/files/") +def serve_file(filename): + return send_from_directory("/app/files", filename) \ No newline at end of file diff --git a/app/flask-postgres/app/requirements.txt b/app/flask-postgres/app/requirements.txt new file mode 100644 index 0000000..cf790cb --- /dev/null +++ b/app/flask-postgres/app/requirements.txt @@ -0,0 +1,4 @@ +Flask==3.0.2 +gunicorn==22.0.0 +psycopg2-binary==2.9.9 +Werkzeug==3.0.1 \ No newline at end of file diff --git a/app/flask-postgres/app/templates/._.DS_Store b/app/flask-postgres/app/templates/._.DS_Store new file mode 100644 index 0000000..28c42fb Binary files /dev/null and b/app/flask-postgres/app/templates/._.DS_Store differ diff --git a/app/flask-postgres/app/templates/._index.html b/app/flask-postgres/app/templates/._index.html new file mode 100644 index 0000000..853a3da Binary files /dev/null and b/app/flask-postgres/app/templates/._index.html differ diff --git a/app/flask-postgres/app/templates/._login.html b/app/flask-postgres/app/templates/._login.html new file mode 100644 index 0000000..3ba273f Binary files /dev/null and b/app/flask-postgres/app/templates/._login.html differ diff --git a/app/flask-postgres/app/templates/._preise.html b/app/flask-postgres/app/templates/._preise.html new file mode 100644 index 0000000..979b72e Binary files /dev/null and b/app/flask-postgres/app/templates/._preise.html differ diff --git a/app/flask-postgres/app/templates/index.html b/app/flask-postgres/app/templates/index.html new file mode 100644 index 0000000..7808cc1 --- /dev/null +++ b/app/flask-postgres/app/templates/index.html @@ -0,0 +1,45 @@ + + + + + + {{ page_title }} + + + + + +
+
+ {% if active_page == "home" %} + {% include "partials/home_content.html" %} + {% elif active_page == "preise" %} + {% include "partials/preise_content.html" %} + {% elif active_page == "allgemein" %} + {% include "partials/allgemein_content.html" %} + {% endif %} +
+
+ + \ No newline at end of file diff --git a/app/flask-postgres/app/templates/login.html b/app/flask-postgres/app/templates/login.html new file mode 100644 index 0000000..7fcac3d --- /dev/null +++ b/app/flask-postgres/app/templates/login.html @@ -0,0 +1,62 @@ + + + + + + {{ page_title }} + + + + + +
+ +
+ + \ No newline at end of file diff --git a/app/flask-postgres/app/templates/partials/._allgemein_content.html b/app/flask-postgres/app/templates/partials/._allgemein_content.html new file mode 100644 index 0000000..6216161 Binary files /dev/null and b/app/flask-postgres/app/templates/partials/._allgemein_content.html differ diff --git a/app/flask-postgres/app/templates/partials/._home_content.html b/app/flask-postgres/app/templates/partials/._home_content.html new file mode 100644 index 0000000..e830530 Binary files /dev/null and b/app/flask-postgres/app/templates/partials/._home_content.html differ diff --git a/app/flask-postgres/app/templates/partials/._preise_content.html b/app/flask-postgres/app/templates/partials/._preise_content.html new file mode 100644 index 0000000..6740473 Binary files /dev/null and b/app/flask-postgres/app/templates/partials/._preise_content.html differ diff --git a/app/flask-postgres/app/templates/partials/allgemein_content.html b/app/flask-postgres/app/templates/partials/allgemein_content.html new file mode 100644 index 0000000..79848f6 --- /dev/null +++ b/app/flask-postgres/app/templates/partials/allgemein_content.html @@ -0,0 +1,80 @@ +
+

Compliance Verification

+

+ KI sicher, rechtskonform und verantwortungsvoll im Unternehmen einsetzen. +

+
+ +
+

Warum Compliance Verification?

+ +

+ Der Einsatz von Künstlicher Intelligenz bringt enorme Chancen – aber auch + rechtliche und organisatorische Risiken. +

+ +

+ Mit unserem Ansatz stellen Sie sicher, dass Ihre Organisation die Anforderungen + des EU AI Act erfüllt und gleichzeitig effizient und sicher arbeitet. +

+
+ +
+

Was wir bieten

+ +
    +
  • Rechtssichere Schulungen für Mitarbeitende
  • +
  • Strukturierte KI-Governance
  • +
  • Dokumentation und Audit-Fähigkeit
  • +
  • Risikobewertung und Kontrolle
  • +
  • Praxisnahe Umsetzung im Unternehmen
  • +
+
+ +
+

Für wen ist das relevant?

+ +

+ Unsere Lösungen richten sich an Unternehmen jeder Größe, die KI einsetzen oder + dies planen. +

+ +
    +
  • Geschäftsführung und Management
  • +
  • IT- und Compliance-Abteilungen
  • +
  • HR und Fachbereiche
  • +
  • Organisationen mit regulatorischen Anforderungen
  • +
+
+ +
+

Ihr Vorteil

+ +
+
+
    +
  • Rechtssicherheit
  • +
  • Reduziertes Risiko
  • +
  • Strukturierte Prozesse
  • +
  • Nachweisbare Compliance
  • +
+
+ +
+ Compliance Schulung +
+
+
+ +
+

Jetzt starten

+ +

+ Beginnen Sie mit einer fundierten Grundlage und entwickeln Sie Ihre Organisation + Schritt für Schritt zur vollständigen KI-Compliance. +

+ + + Zu den Preisen + +
\ No newline at end of file diff --git a/app/flask-postgres/app/templates/partials/home_content.html b/app/flask-postgres/app/templates/partials/home_content.html new file mode 100644 index 0000000..14b6e66 --- /dev/null +++ b/app/flask-postgres/app/templates/partials/home_content.html @@ -0,0 +1,6 @@ +
+

Compliance Verification

+

Willkommen auf der Startseite Ihrer Flask-Anwendung im Kolb-Layout.

+

Besuche insgesamt: {{ visit_count }}

+

Für die Seiten Preise und Allgemein ist eine Anmeldung erforderlich.

+
\ No newline at end of file diff --git a/app/flask-postgres/app/templates/partials/preise_content.html b/app/flask-postgres/app/templates/partials/preise_content.html new file mode 100644 index 0000000..32e321c --- /dev/null +++ b/app/flask-postgres/app/templates/partials/preise_content.html @@ -0,0 +1,123 @@ +
+

Klare Preise für Ihre KI-Compliance

+

Wählen Sie zwischen sofort buchbaren Modulen und individueller Unternehmenslösung.

+
+ +
+

Leistungen und Preise

+ +
+
+

Modul A – Essential

+

Für alle Mitarbeitenden – gesetzliche Mindestanforderung

+
€ 9,90 / jährlich pro Nutzer
+ +
    +
  • Erfüllt die gesetzliche Schulungspflicht
  • +
  • 5 Pflichtmodule
  • +
  • AI Governance Basics
  • +
  • Ethical AI & Non-Discrimination
  • +
  • AI Risk Awareness
  • +
  • Transparency & Disclosure
  • +
  • Documentation & Prozesse
  • +
+
+ + + +
+

Modul C – Governance

+

Für Unternehmen – vollständige Steuerung und Absicherung

+
€ 29,90 / jährlich pro Nutzer
+ +
    +
  • Alle Module aus A & B
  • +
  • 15 Module insgesamt
  • +
  • Advanced Copyright & IP Strategy
  • +
  • Security & Misuse Prevention
  • +
  • Vendor & Tool Governance
  • +
  • Risk Mapping
  • +
  • Individuelle Beratung
  • +
+
+
+
+ +
+

Welches Paket ist das richtige?

+
+ Paketübersicht +
+
+ +
+
+
+

Für ganze Unternehmen

+

Sie möchten Ihre gesamte Organisation rechtssicher aufstellen?

+
    +
  • individuelle Risikoanalyse
  • +
  • unternehmensweite Umsetzung
  • +
  • rechtssichere Dokumentation
  • +
  • kontinuierliche Begleitung
  • +
+
+
+ Schulung +
+
+
+ +
+

Module / geprüfte Bereiche

+ +
+
+

Basis-Level

+

AI-Safe Workforce

+
    +
  • AI Governance Basics
  • +
  • Ethical AI & Non-Discrimination
  • +
  • AI Risk & Impact Awareness
  • +
  • Transparency & Customer Disclosure
  • +
  • Documentation & Internal Processes
  • +
+
+ +
+

Compliance-Level

+

AI Compliance Ready

+
    +
  • Datenschutz & KI
  • +
  • KI-Nutzung & HR-Policies
  • +
  • Urheberrecht & Trainingsdaten
  • +
  • Erweiterte Dokumentation & Transparenz
  • +
+
+ +
+

Governance-Level

+

Full AI Governance

+
    +
  • Copyright Deep Dive
  • +
  • Security & Missbrauchsprävention
  • +
  • Vendor & Tool-Prüfung
  • +
  • Individuelle Risikoanalyse & Beratung
  • +
+
+
+
\ No newline at end of file diff --git a/app/flask-postgres/app/templates/preise.html b/app/flask-postgres/app/templates/preise.html new file mode 100644 index 0000000..9d4916b --- /dev/null +++ b/app/flask-postgres/app/templates/preise.html @@ -0,0 +1,190 @@ + + + + + + {{ page_title }} + + + + + +
+
+

Klare Preise für Ihre KI-Compliance

+

Wählen Sie zwischen sofort buchbaren Modulen und individueller Unternehmenslösung.

+
+ +
+

Leistungen und Preise

+ +
+
+

Modul A – Essential

+

Für alle Mitarbeitenden – gesetzliche Mindestanforderung

+
€ 9,90 / jährlich pro Nutzer
+ +
    +
  • Erfüllt die gesetzliche Schulungspflicht (EU AI Act)
  • +
  • 5 Pflichtmodule
  • +
  • AI Governance Basics
  • +
  • Ethical AI & Non-Discrimination
  • +
  • AI Risk Awareness
  • +
  • Transparency & Disclosure
  • +
  • Documentation & Prozesse (Basic)
  • +
+ + Jetzt buchen +
+ + + +
+

Modul C – Governance

+

Für Unternehmen – vollständige Steuerung, Kontrolle und Absicherung

+
€ 29,90 / jährlich pro Nutzer
+ +
    +
  • Alle Module aus A & B
  • +
  • 15 Module insgesamt
  • +
  • Advanced Copyright & IP Strategy
  • +
  • Security & Misuse Prevention
  • +
  • Vendor & Tool Governance
  • +
  • Risk Mapping & Governance Framework
  • +
  • Umsetzung & individuelle Beratung
  • +
+ + Jetzt buchen +
+
+ +

+ Alle Preise verstehen sich inklusive Mehrwertsteuer. +

+
+ +
+

Welches Paket ist das richtige für Ihr Unternehmen?

+
+ Paketübersicht +
+

+ Die meisten Unternehmen starten mit Modul A und erweitern anschließend auf Modul B oder C – je nach Einsatz von KI und Risikoprofil. +

+
+ +
+
+
+

Für ganze Unternehmen

+

Sie möchten nicht nur einzelne Mitarbeitende schulen, sondern Ihre gesamte Organisation rechtssicher aufstellen?

+
    +
  • individuelle Risikoanalyse
  • +
  • unternehmensweite Umsetzung
  • +
  • rechtssichere Dokumentation
  • +
  • kontinuierliche Begleitung
  • +
+ Individuelles Angebot anfragen +
+
+ Schulung +
+
+
+ +
+

Module / geprüfte Bereiche

+
+
+

Basis-Level

+

AI-Safe Workforce

+
    +
  • AI Governance Basics
  • +
  • Ethical AI & Non-Discrimination
  • +
  • AI Risk & Impact Awareness
  • +
  • Transparency & Customer Disclosure
  • +
  • Documentation & Internal Processes
  • +
+
+ +
+

Compliance-Level

+

AI Compliance Ready

+
    +
  • Datenschutz & KI
  • +
  • KI-Nutzung & HR-Policies
  • +
  • Urheberrecht & Trainingsdaten
  • +
  • Erweiterte Dokumentation & Transparenz
  • +
+
+ +
+

Governance-Level

+

Full AI Governance

+
    +
  • Copyright Deep Dive
  • +
  • Security & Missbrauchsprävention
  • +
  • Vendor & Tool-Prüfung
  • +
  • Individuelle Risikoanalyse & Beratung
  • +
+
+
+
+ +
+

So funktioniert Compliance Verification

+
+
+

Schritt 1

+

Sie wählen Module und starten sofort.

+
+
+

Schritt 2

+

Ihre Mitarbeitenden absolvieren Schulung und Prüfung.

+
+
+

Schritt 3

+

Sie erhalten ein belastbares Compliance-Zertifikat.

+
+
+
+
+ + \ No newline at end of file diff --git a/app/flask-postgres/images/._.DS_Store b/app/flask-postgres/images/._.DS_Store new file mode 100644 index 0000000..28c42fb Binary files /dev/null and b/app/flask-postgres/images/._.DS_Store differ diff --git a/app/flask-postgres/images/._142815-780943566_small.mp4 b/app/flask-postgres/images/._142815-780943566_small.mp4 new file mode 100644 index 0000000..431c7bb Binary files /dev/null and b/app/flask-postgres/images/._142815-780943566_small.mp4 differ diff --git a/app/flask-postgres/images/._TabelleUebersicht.png b/app/flask-postgres/images/._TabelleUebersicht.png new file mode 100644 index 0000000..2a3409b Binary files /dev/null and b/app/flask-postgres/images/._TabelleUebersicht.png differ diff --git a/app/flask-postgres/images/._ai-governance.png b/app/flask-postgres/images/._ai-governance.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._ai-governance.png differ diff --git a/app/flask-postgres/images/._cloud-security.png b/app/flask-postgres/images/._cloud-security.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._cloud-security.png differ diff --git a/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-192x192.png b/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-192x192.png new file mode 100644 index 0000000..fa0c71b Binary files /dev/null and b/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-192x192.png differ diff --git a/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-32x32.png b/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-32x32.png new file mode 100644 index 0000000..632105d Binary files /dev/null and b/app/flask-postgres/images/._cropped-Logo-Compliance-Verification-bg-1-32x32.png differ diff --git a/app/flask-postgres/images/._hero-legal-ai.png b/app/flask-postgres/images/._hero-legal-ai.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._hero-legal-ai.png differ diff --git a/app/flask-postgres/images/._logo-compliance.png b/app/flask-postgres/images/._logo-compliance.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._logo-compliance.png differ diff --git a/app/flask-postgres/images/._schulung.png b/app/flask-postgres/images/._schulung.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._schulung.png differ diff --git a/app/flask-postgres/images/._security-shield.png b/app/flask-postgres/images/._security-shield.png new file mode 100644 index 0000000..2b41b1e Binary files /dev/null and b/app/flask-postgres/images/._security-shield.png differ diff --git a/app/flask-postgres/images/142815-780943566_small.mp4 b/app/flask-postgres/images/142815-780943566_small.mp4 new file mode 100644 index 0000000..2ca572a Binary files /dev/null and b/app/flask-postgres/images/142815-780943566_small.mp4 differ diff --git a/app/flask-postgres/images/Logo-Compliance-Verification-bg-1.png b/app/flask-postgres/images/Logo-Compliance-Verification-bg-1.png new file mode 100644 index 0000000..5d988a6 Binary files /dev/null and b/app/flask-postgres/images/Logo-Compliance-Verification-bg-1.png differ diff --git a/app/flask-postgres/images/TabelleUebersicht.png b/app/flask-postgres/images/TabelleUebersicht.png new file mode 100644 index 0000000..668369a Binary files /dev/null and b/app/flask-postgres/images/TabelleUebersicht.png differ diff --git a/app/flask-postgres/images/ai-governance.png b/app/flask-postgres/images/ai-governance.png new file mode 100644 index 0000000..9d9a4f3 Binary files /dev/null and b/app/flask-postgres/images/ai-governance.png differ diff --git a/app/flask-postgres/images/cloud-security.png b/app/flask-postgres/images/cloud-security.png new file mode 100644 index 0000000..8c51def Binary files /dev/null and b/app/flask-postgres/images/cloud-security.png differ diff --git a/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-192x192.png b/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-192x192.png new file mode 100644 index 0000000..c717570 Binary files /dev/null and b/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-192x192.png differ diff --git a/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-32x32.png b/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-32x32.png new file mode 100644 index 0000000..7236368 Binary files /dev/null and b/app/flask-postgres/images/cropped-Logo-Compliance-Verification-bg-1-32x32.png differ diff --git a/app/flask-postgres/images/hero-legal-ai.png b/app/flask-postgres/images/hero-legal-ai.png new file mode 100644 index 0000000..d802f1e Binary files /dev/null and b/app/flask-postgres/images/hero-legal-ai.png differ diff --git a/app/flask-postgres/images/logo-compliance.png b/app/flask-postgres/images/logo-compliance.png new file mode 100644 index 0000000..5d988a6 Binary files /dev/null and b/app/flask-postgres/images/logo-compliance.png differ diff --git a/app/flask-postgres/images/schulung.png b/app/flask-postgres/images/schulung.png new file mode 100644 index 0000000..ce55af1 Binary files /dev/null and b/app/flask-postgres/images/schulung.png differ diff --git a/app/flask-postgres/images/security-shield.png b/app/flask-postgres/images/security-shield.png new file mode 100644 index 0000000..17fd877 Binary files /dev/null and b/app/flask-postgres/images/security-shield.png differ diff --git a/app/flask-postgres/images/videos/._A1 AI Governance.mp4 b/app/flask-postgres/images/videos/._A1 AI Governance.mp4 new file mode 100644 index 0000000..e5624fe Binary files /dev/null and b/app/flask-postgres/images/videos/._A1 AI Governance.mp4 differ diff --git a/app/flask-postgres/images/videos/._A2 ethical AI.mp4 b/app/flask-postgres/images/videos/._A2 ethical AI.mp4 new file mode 100644 index 0000000..6846eb8 Binary files /dev/null and b/app/flask-postgres/images/videos/._A2 ethical AI.mp4 differ diff --git a/app/flask-postgres/images/videos/._A3 Risk awareness.mp4 b/app/flask-postgres/images/videos/._A3 Risk awareness.mp4 new file mode 100644 index 0000000..7d7f627 Binary files /dev/null and b/app/flask-postgres/images/videos/._A3 Risk awareness.mp4 differ diff --git a/app/flask-postgres/images/videos/._A4 Transparency.mp4 b/app/flask-postgres/images/videos/._A4 Transparency.mp4 new file mode 100644 index 0000000..1df3a7a Binary files /dev/null and b/app/flask-postgres/images/videos/._A4 Transparency.mp4 differ diff --git a/app/flask-postgres/images/videos/._A5 internal Processes.mp4 b/app/flask-postgres/images/videos/._A5 internal Processes.mp4 new file mode 100644 index 0000000..6a1f59c Binary files /dev/null and b/app/flask-postgres/images/videos/._A5 internal Processes.mp4 differ diff --git a/app/flask-postgres/images/videos/._B1 Privacy.mp4 b/app/flask-postgres/images/videos/._B1 Privacy.mp4 new file mode 100644 index 0000000..202e705 Binary files /dev/null and b/app/flask-postgres/images/videos/._B1 Privacy.mp4 differ diff --git a/app/flask-postgres/images/videos/._B2 Policies.mp4 b/app/flask-postgres/images/videos/._B2 Policies.mp4 new file mode 100644 index 0000000..2711d46 Binary files /dev/null and b/app/flask-postgres/images/videos/._B2 Policies.mp4 differ diff --git a/app/flask-postgres/images/videos/._B3 Copyright.mp4 b/app/flask-postgres/images/videos/._B3 Copyright.mp4 new file mode 100644 index 0000000..53b4a3a Binary files /dev/null and b/app/flask-postgres/images/videos/._B3 Copyright.mp4 differ diff --git a/app/flask-postgres/images/videos/._B4 Documentation.mp4 b/app/flask-postgres/images/videos/._B4 Documentation.mp4 new file mode 100644 index 0000000..dcab858 Binary files /dev/null and b/app/flask-postgres/images/videos/._B4 Documentation.mp4 differ diff --git a/app/flask-postgres/images/videos/._B5 organisation.mp4 b/app/flask-postgres/images/videos/._B5 organisation.mp4 new file mode 100644 index 0000000..3a45481 Binary files /dev/null and b/app/flask-postgres/images/videos/._B5 organisation.mp4 differ diff --git a/app/flask-postgres/images/videos/._C1 Advanced Copyright.mp4 b/app/flask-postgres/images/videos/._C1 Advanced Copyright.mp4 new file mode 100644 index 0000000..c7eca49 Binary files /dev/null and b/app/flask-postgres/images/videos/._C1 Advanced Copyright.mp4 differ diff --git a/app/flask-postgres/images/videos/._C2 misuse.mp4 b/app/flask-postgres/images/videos/._C2 misuse.mp4 new file mode 100644 index 0000000..ec3272a Binary files /dev/null and b/app/flask-postgres/images/videos/._C2 misuse.mp4 differ diff --git a/app/flask-postgres/images/videos/A1 AI Governance.mp4 b/app/flask-postgres/images/videos/A1 AI Governance.mp4 new file mode 100644 index 0000000..9cef954 Binary files /dev/null and b/app/flask-postgres/images/videos/A1 AI Governance.mp4 differ diff --git a/app/flask-postgres/images/videos/A2 ethical AI.mp4 b/app/flask-postgres/images/videos/A2 ethical AI.mp4 new file mode 100644 index 0000000..e241657 Binary files /dev/null and b/app/flask-postgres/images/videos/A2 ethical AI.mp4 differ diff --git a/app/flask-postgres/images/videos/A3 Risk awareness.mp4 b/app/flask-postgres/images/videos/A3 Risk awareness.mp4 new file mode 100644 index 0000000..0976e8c Binary files /dev/null and b/app/flask-postgres/images/videos/A3 Risk awareness.mp4 differ diff --git a/app/flask-postgres/images/videos/A4 Transparency.mp4 b/app/flask-postgres/images/videos/A4 Transparency.mp4 new file mode 100644 index 0000000..149042a Binary files /dev/null and b/app/flask-postgres/images/videos/A4 Transparency.mp4 differ diff --git a/app/flask-postgres/images/videos/A5 internal Processes.mp4 b/app/flask-postgres/images/videos/A5 internal Processes.mp4 new file mode 100644 index 0000000..2789e18 Binary files /dev/null and b/app/flask-postgres/images/videos/A5 internal Processes.mp4 differ diff --git a/app/flask-postgres/images/videos/B1 Privacy.mp4 b/app/flask-postgres/images/videos/B1 Privacy.mp4 new file mode 100644 index 0000000..3fd0b36 Binary files /dev/null and b/app/flask-postgres/images/videos/B1 Privacy.mp4 differ diff --git a/app/flask-postgres/images/videos/B2 Policies.mp4 b/app/flask-postgres/images/videos/B2 Policies.mp4 new file mode 100644 index 0000000..bc0e530 Binary files /dev/null and b/app/flask-postgres/images/videos/B2 Policies.mp4 differ diff --git a/app/flask-postgres/images/videos/B3 Copyright.mp4 b/app/flask-postgres/images/videos/B3 Copyright.mp4 new file mode 100644 index 0000000..a1717fd Binary files /dev/null and b/app/flask-postgres/images/videos/B3 Copyright.mp4 differ diff --git a/app/flask-postgres/images/videos/B4 Documentation.mp4 b/app/flask-postgres/images/videos/B4 Documentation.mp4 new file mode 100644 index 0000000..6ed5360 Binary files /dev/null and b/app/flask-postgres/images/videos/B4 Documentation.mp4 differ diff --git a/app/flask-postgres/images/videos/B5 organisation.mp4 b/app/flask-postgres/images/videos/B5 organisation.mp4 new file mode 100644 index 0000000..dc94f15 Binary files /dev/null and b/app/flask-postgres/images/videos/B5 organisation.mp4 differ diff --git a/app/flask-postgres/images/videos/C1 Advanced Copyright.mp4 b/app/flask-postgres/images/videos/C1 Advanced Copyright.mp4 new file mode 100644 index 0000000..6dbb546 Binary files /dev/null and b/app/flask-postgres/images/videos/C1 Advanced Copyright.mp4 differ diff --git a/app/flask-postgres/images/videos/C2 misuse.mp4 b/app/flask-postgres/images/videos/C2 misuse.mp4 new file mode 100644 index 0000000..799ef3b Binary files /dev/null and b/app/flask-postgres/images/videos/C2 misuse.mp4 differ diff --git a/app/flask-postgres/styles/._site.css b/app/flask-postgres/styles/._site.css new file mode 100644 index 0000000..853a3da Binary files /dev/null and b/app/flask-postgres/styles/._site.css differ diff --git a/app/flask-postgres/styles/site.css b/app/flask-postgres/styles/site.css new file mode 100644 index 0000000..09642b6 --- /dev/null +++ b/app/flask-postgres/styles/site.css @@ -0,0 +1,326 @@ +/* ========================= + RESET & BASE +========================= */ + +* { + box-sizing: border-box; +} + +html, body { + margin: 0; + padding: 0; + font-family: Arial, Helvetica, sans-serif; +} + +body { + background: linear-gradient(180deg, #07192d 0%, #102a45 100%); + color: #ffffff; + min-height: 100vh; +} + +/* ========================= + HEADER +========================= */ + +.site-header { + background: rgba(4, 18, 33, 0.96); + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + position: sticky; + top: 0; + z-index: 100; +} + +.header-inner { + max-width: 1320px; + margin: 0 auto; + padding: 14px 24px; + display: flex; + align-items: center; + justify-content: space-between; +} + +/* ========================= + LOGO +========================= */ + +.site-logo { + height: 60px; + width: auto; + display: block; +} + +/* ========================= + NAVIGATION +========================= */ + +.top-nav { + display: flex; + align-items: center; + gap: 8px; +} + +.top-nav a { + color: #ffffff; + text-decoration: none; + font-weight: 600; + + padding: 10px 18px; + border-radius: 999px; + display: inline-block; + + min-width: 110px; /* verhindert Springen */ + text-align: center; + + transition: background 0.2s ease; +} + +.top-nav a:hover, +.top-nav a.active { + background: #376da6; +} + +.user-box { + font-weight: 700; + padding: 10px 12px; +} + +/* ========================= + MAIN CONTENT +========================= */ + +.content-area { + padding: 40px 20px; +} + +.content-box { + max-width: 1200px; + margin: 0 auto; + + background: #ffffff; + color: #1b2430; + + border-radius: 16px; + padding: 32px; + + box-shadow: 0 18px 48px rgba(0, 0, 0, 0.2); +} + +/* ========================= + HEADINGS +========================= */ + +h1, h2, h3 { + color: #0d2f57; + margin-top: 0; +} + +p { + color: #2f3b4a; +} + +/* ========================= + HERO +========================= */ + +.hero-box { + margin-bottom: 30px; +} + +/* ========================= + PRICING +========================= */ + +.pricing-section { + margin-bottom: 30px; +} + +.pricing-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.price-card { + background: #ffffff; + border: 1px solid #dce3ea; + border-radius: 16px; + padding: 24px; + + box-shadow: 0 6px 16px rgba(0, 0, 0, 0.05); +} + +.price-card.featured { + border: 2px solid #1d66b2; + background: #f5f9ff; +} + +.price-card h3 { + color: #0d2f57; +} + +.price-subline { + color: #526172; + min-height: 48px; +} + +.price-value { + font-size: 30px; + font-weight: 800; + color: #125eb0; + margin: 18px 0; +} + +.price-value span { + font-size: 14px; + color: #526172; +} + +.price-card ul { + padding-left: 20px; +} + +.price-card li { + margin-bottom: 8px; + color: #2f3b4a; +} + +/* ========================= + BUTTONS +========================= */ + +.btn-primary { + display: inline-block; + margin-top: 12px; + + padding: 10px 16px; + border-radius: 8px; + + background: #125eb0; + color: #ffffff; + + text-decoration: none; + font-weight: 600; +} + +/* ========================= + IMAGE PANEL +========================= */ + +.image-panel img { + width: 100%; + border-radius: 12px; +} + +/* ========================= + TWO COLUMN LAYOUT +========================= */ + +.two-col { + display: grid; + grid-template-columns: 1.2fr 1fr; + gap: 24px; + align-items: center; +} + +/* ========================= + MODULES +========================= */ + +.module-blocks { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; +} + +.module-block { + background: #f8fbff; + border: 1px solid #dce3ea; + border-radius: 16px; + padding: 24px; +} + +.module-block h3 { + color: #7f9cc0; +} + +.module-result { + font-weight: 800; + color: #125eb0; + margin-bottom: 10px; +} + +.module-block li { + color: #2f3b4a; +} + +/* ========================= + LOGIN +========================= */ + +.login-box { + max-width: 600px; +} + +.intro-text { + color: #526172; +} + +.login-form .form-row { + margin-bottom: 16px; +} + +.login-form label { + display: block; + margin-bottom: 6px; + font-weight: 600; + color: #0d2f57; +} + +.login-form input { + width: 100%; + padding: 10px; + border-radius: 8px; + border: 1px solid #c9d2db; +} + +.error-box { + background: #ffe7e7; + color: #8d1d1d; + padding: 12px; + border-radius: 8px; + margin-bottom: 16px; +} + +/* ========================= + RESPONSIVE +========================= */ + +@media (max-width: 900px) { + + .pricing-grid, + .module-blocks, + .two-col { + grid-template-columns: 1fr; + } + + .top-nav a { + min-width: auto; + } + + .header-inner { + flex-direction: column; + align-items: flex-start; + } +} + +.info-section { + margin-bottom: 30px; +} + +.check-list { + padding-left: 20px; +} + +.check-list li { + margin-bottom: 8px; +} \ No newline at end of file diff --git a/infra/flask-postgres/._docker-compose.yaml b/infra/flask-postgres/._docker-compose.yaml new file mode 100644 index 0000000..1b6fd5a Binary files /dev/null and b/infra/flask-postgres/._docker-compose.yaml differ diff --git a/infra/flask-postgres/docker-compose.yaml b/infra/flask-postgres/docker-compose.yaml new file mode 100644 index 0000000..1ac342f --- /dev/null +++ b/infra/flask-postgres/docker-compose.yaml @@ -0,0 +1,43 @@ +services: + web: + build: ./app + container_name: flask_web + restart: unless-stopped + ports: + - "5050:5000" + environment: + DB_HOST: db + DB_NAME: CertDB + DB_USER: CertUser + DB_PASSWORD: CertPWD + DB_PORT: 5432 + LOG_DIR: /logs + depends_on: + - db + volumes: + - /volume2/container-logs/flask:/logs + - /volume1/docker/flask-postgres/app:/app + - /volume1/docker/flask-postgres/images:/app/images + - /volume1/docker/flask-postgres/styles:/app/styles + - /volume1/docker/flask-postgres/files:/app/files + + db: + image: postgres:16 + container_name: flask_db + restart: unless-stopped + environment: + POSTGRES_DB: CertDB + POSTGRES_USER: CertUser + POSTGRES_PASSWORD: CertPWD + volumes: + - /volume1/docker/flask-postgres/db:/var/lib/postgresql/data + + pgadmin: + image: dpage/pgadmin4 + container_name: flask_pgadmin + restart: unless-stopped + environment: + PGADMIN_DEFAULT_EMAIL: admin@kolb.cc + PGADMIN_DEFAULT_PASSWORD: DBadmin + ports: + - "5051:80" \ No newline at end of file diff --git a/infra/gitea/._docker-compose.yaml b/infra/gitea/._docker-compose.yaml new file mode 100644 index 0000000..122ae26 Binary files /dev/null and b/infra/gitea/._docker-compose.yaml differ diff --git a/infra/gitea/docker-compose.yaml b/infra/gitea/docker-compose.yaml new file mode 100644 index 0000000..2210923 --- /dev/null +++ b/infra/gitea/docker-compose.yaml @@ -0,0 +1,21 @@ +services: + gitea: + image: gitea/gitea:1.22 + container_name: gitea-rd + restart: unless-stopped + ports: + - "8088:3000" + - "2222:22" + environment: + USER_UID: 1000 + USER_GID: 1000 + + GITEA__server__DOMAIN: "git.kolb.cc" + GITEA__server__ROOT_URL: "https://git.kolb.cc/" + GITEA__server__SSH_DOMAIN: "git.kolb.cc" + GITEA__server__SSH_PORT: "2222" + GITEA__server__PROTOCOL: "http" + + volumes: + - /volume1/docker/gitea/data:/data + - /volume2/container-logs/gitea:/data/log \ No newline at end of file diff --git a/infra/openproject/._docker-compose.yaml b/infra/openproject/._docker-compose.yaml new file mode 100644 index 0000000..b15e599 Binary files /dev/null and b/infra/openproject/._docker-compose.yaml differ diff --git a/infra/openproject/docker-compose.yaml b/infra/openproject/docker-compose.yaml new file mode 100644 index 0000000..174b7e4 --- /dev/null +++ b/infra/openproject/docker-compose.yaml @@ -0,0 +1,29 @@ +services: + openproject-db: + image: postgres:17 + container_name: openproject-db + restart: unless-stopped + environment: + POSTGRES_DB: openproject + POSTGRES_USER: openproject + POSTGRES_PASSWORD: change-me-openproject-db + volumes: + - /volume1/docker/openproject/pgdata:/var/lib/postgresql/data + + openproject: + image: openproject/openproject:17 + container_name: openproject-rd + restart: unless-stopped + depends_on: + - openproject-db + ports: + - "8087:80" + environment: + OPENPROJECT_HOST__NAME: "project.kolb.cc" + OPENPROJECT_HTTPS: "true" + OPENPROJECT_PROTOCOL: "https" + OPENPROJECT_SECRET_KEY_BASE: "change-me-long-random-secret" + DATABASE_URL: "postgres://openproject:change-me-openproject-db@openproject-db:5432/openproject" + volumes: + - /volume1/docker/openproject/assets:/var/openproject/assets + - /volume2/container-logs/openproject:/app/log \ No newline at end of file diff --git a/infra/synology-config/._Netzwerk Konfig.docx b/infra/synology-config/._Netzwerk Konfig.docx new file mode 100644 index 0000000..984ca76 Binary files /dev/null and b/infra/synology-config/._Netzwerk Konfig.docx differ diff --git a/infra/synology-config/._kolb.cc.cert.zip b/infra/synology-config/._kolb.cc.cert.zip new file mode 100644 index 0000000..811fdb2 Binary files /dev/null and b/infra/synology-config/._kolb.cc.cert.zip differ diff --git a/infra/synology-config/Netzwerk Konfig.docx b/infra/synology-config/Netzwerk Konfig.docx new file mode 100644 index 0000000..065cf6d Binary files /dev/null and b/infra/synology-config/Netzwerk Konfig.docx differ diff --git a/infra/synology-config/kolb.cc.cert.zip b/infra/synology-config/kolb.cc.cert.zip new file mode 100644 index 0000000..2b5f164 Binary files /dev/null and b/infra/synology-config/kolb.cc.cert.zip differ