add cloudron packaging and auth refinements
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
.git
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.pytest_cache
|
||||||
|
.mypy_cache
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
data
|
||||||
|
instance
|
||||||
@@ -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": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
@@ -41,4 +41,4 @@ Beim Start führt Nouri das Schema erneut mit `CREATE ... IF NOT EXISTS` aus und
|
|||||||
|
|
||||||
## Cloudron-Hinweis
|
## 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`.
|
||||||
|
|||||||
@@ -452,6 +452,25 @@ h3 {
|
|||||||
grid-column: span 2;
|
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 {
|
.week-mini-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 0.4rem;
|
gap: 0.4rem;
|
||||||
@@ -881,6 +900,14 @@ legend {
|
|||||||
.planner-entry-form .wide {
|
.planner-entry-form .wide {
|
||||||
grid-column: auto;
|
grid-column: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.quick-food-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-food-grid .wide {
|
||||||
|
grid-column: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
@media (max-width: 720px) {
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
Flask==3.1.1
|
Flask==3.1.1
|
||||||
|
gunicorn==23.0.0
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user