From 24ebb26ffded3c5b64088b40945dd846ce05f020 Mon Sep 17 00:00:00 2001 From: Florian Heinz Date: Sun, 12 Apr 2026 12:12:39 +0200 Subject: [PATCH] add cloudron packaging and auth refinements --- .dockerignore | 14 ++++++++++++++ CloudronManifest.json | 15 +++++++++++++++ Dockerfile.cloudron | 23 +++++++++++++++++++++++ README.md | 2 +- nouri/static/css/styles.css | 27 +++++++++++++++++++++++++++ requirements.txt | 1 + start.sh | 16 ++++++++++++++++ 7 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 CloudronManifest.json create mode 100644 Dockerfile.cloudron create mode 100755 start.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..2f95a59 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.git +.venv +venv +__pycache__ +*.pyc +*.pyo +*.pyd +.pytest_cache +.mypy_cache +node_modules +dist +build +data +instance diff --git a/CloudronManifest.json b/CloudronManifest.json new file mode 100644 index 0000000..bc51647 --- /dev/null +++ b/CloudronManifest.json @@ -0,0 +1,15 @@ +{ + "id": "io.hnz.nouri", + "title": "Nouri", + "author": "Florian Heinz", + "description": "Private Flask app for meals, shopping and gentle food planning", + "tagline": "einfach essen planen", + "version": "0.2.0", + "upstreamVersion": "0.2.0", + "healthCheckPath": "/", + "httpPort": 8000, + "manifestVersion": 2, + "addons": { + "localstorage": {} + } +} diff --git a/Dockerfile.cloudron b/Dockerfile.cloudron new file mode 100644 index 0000000..aa01694 --- /dev/null +++ b/Dockerfile.cloudron @@ -0,0 +1,23 @@ +FROM python:3.13-slim + +WORKDIR /app/code + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PIP_NO_CACHE_DIR=1 + +RUN useradd -r -m -d /home/cloudron -s /usr/sbin/nologin cloudron + +COPY requirements.txt /app/code/ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . /app/code + +RUN chown -R cloudron:cloudron /app/code \ + && chmod +x /app/code/start.sh + +USER cloudron + +EXPOSE 8000 + +CMD ["/app/code/start.sh"] diff --git a/README.md b/README.md index d1a626e..0bbba08 100644 --- a/README.md +++ b/README.md @@ -41,4 +41,4 @@ Beim Start führt Nouri das Schema erneut mit `CREATE ... IF NOT EXISTS` aus und ## Cloudron-Hinweis -Für Cloudron später `NOURI_DATA_DIR=/app/data` setzen, damit Datenbank und Uploads persistent liegen. +Für Cloudron ist die App jetzt so vorbereitet, dass Datenbank und Uploads unter `/app/data` liegen können. Das Startskript setzt `NOURI_DATA_DIR=/app/data` und startet die App per `gunicorn`. diff --git a/nouri/static/css/styles.css b/nouri/static/css/styles.css index 859be49..12c8989 100644 --- a/nouri/static/css/styles.css +++ b/nouri/static/css/styles.css @@ -452,6 +452,25 @@ h3 { grid-column: span 2; } +.quick-food-panel { + margin-top: 1rem; + padding: 1rem; + border-radius: 18px; + background: rgba(255, 255, 255, 0.5); + border: 1px solid var(--line); +} + +.quick-food-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 0.8rem; + align-items: end; +} + +.quick-food-grid .wide { + grid-column: span 2; +} + .week-mini-card { display: grid; gap: 0.4rem; @@ -881,6 +900,14 @@ legend { .planner-entry-form .wide { grid-column: auto; } + + .quick-food-grid { + grid-template-columns: 1fr; + } + + .quick-food-grid .wide { + grid-column: auto; + } } @media (max-width: 720px) { diff --git a/requirements.txt b/requirements.txt index aa4b129..d3e0775 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ Flask==3.1.1 +gunicorn==23.0.0 diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..8def23e --- /dev/null +++ b/start.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -eu + +export NOURI_DATA_DIR="${NOURI_DATA_DIR:-/app/data}" +mkdir -p "${NOURI_DATA_DIR}/uploads" + +if [ -z "${NOURI_SECRET_KEY:-}" ]; then + export NOURI_SECRET_KEY="cloudron-dev-secret" +fi + +exec gunicorn \ + --bind 0.0.0.0:8000 \ + --workers 2 \ + --threads 4 \ + --timeout 60 \ + wsgi:app