File size: 4,269 Bytes
7daa90b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e42dd8b
 
7daa90b
2c4da6c
 
 
 
 
7daa90b
 
 
 
 
 
 
 
2c4da6c
7daa90b
 
 
 
 
 
e42dd8b
 
 
 
 
7daa90b
 
e42dd8b
 
7daa90b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bbcafae
7daa90b
 
 
 
 
 
 
 
 
 
 
 
 
e42dd8b
 
7daa90b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# MoBaz Hugging Face Space — observability edition.
#
# A single container fans one public port (7860) out to four processes via
# nginx, so the Space serves BOTH the live app/API and a Grafana metrics UI:
#
#   /                 -> 302 -> /grafana/      (Grafana is the landing UI)
#   /grafana/         -> Grafana      (dashboards, reverse-proxied)
#   /api/*  /data/*   -> server.py    (UNCHANGED paths — the iOS/Android apps
#   /metrics /status  -> server.py     depend on these, so no app rebuild)
#   /app/   (+ rest)  -> server.py    (the web PWA)
#
# Grafana lives under /grafana/ (not literally "/") on purpose: Grafana has its
# own /api/* endpoints that would collide with MoBaz's /api/*. The root simply
# redirects in. Prometheus scrapes server.py's /metrics; Grafana reads Prometheus.
#
# NOTE: HF Space storage is ephemeral and the Space sleeps when idle, so the
# Prometheus TSDB resets on rebuild/restart — dashboards show history since the
# last boot, not forever. The built-in /status page is a no-dependency fallback.
FROM python:3.11-slim

ARG PROM_VERSION=2.54.1
# Pin Grafana so a rebuild can't silently pull a newer release that crash-loops
# (an unpinned `grafana` once drifted onto a build whose container never passed
# HF's health check). Bump deliberately; supervisord expects the unified
# `grafana server` binary at /usr/share/grafana/bin/grafana (Grafana 11+).
ARG GF_VERSION=13.0.2

# Base tools + nginx + supervisor, then Grafana (apt repo) and Prometheus (release tarball).
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl ca-certificates wget gnupg nginx supervisor \
    && mkdir -p /etc/apt/keyrings \
    && wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor > /etc/apt/keyrings/grafana.gpg \
    && echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" \
        > /etc/apt/sources.list.d/grafana.list \
    && apt-get update && apt-get install -y --no-install-recommends grafana="${GF_VERSION}" \
    && wget -q "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz" \
    && tar xzf prometheus-${PROM_VERSION}.linux-amd64.tar.gz \
    && mv prometheus-${PROM_VERSION}.linux-amd64/prometheus /usr/local/bin/ \
    && mv prometheus-${PROM_VERSION}.linux-amd64/promtool /usr/local/bin/ \
    && rm -rf prometheus-${PROM_VERSION}.linux-amd64* \
    && apt-get purge -y wget gnupg && apt-get autoremove -y \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# App code (server.py, modules, public/, bundled data) — copied by deploy_hf.sh.
COPY . .

# Observability config.
COPY hf_space/nginx.conf        /etc/nginx/nginx.conf
COPY hf_space/prometheus.yml    /etc/prometheus/prometheus.yml
COPY hf_space/supervisord.conf  /etc/supervisor/conf.d/mobaz.conf
COPY hf_space/grafana/provisioning /etc/grafana/provisioning
COPY hf_space/grafana/dashboards   /etc/grafana/dashboards

# Writable runtime dirs (HF storage is ephemeral; everything transient -> /tmp).
RUN mkdir -p data /tmp/grafana/logs /tmp/grafana/plugins /tmp/prometheus \
        /tmp/nginx /var/log/supervisor \
    && chmod -R 777 data /tmp/grafana /tmp/prometheus /tmp/nginx

# Grafana served from the /grafana/ sub-path; anonymous Viewer so the public can
# see dashboards without logging in. Set GF_SECURITY_ADMIN_PASSWORD as an HF
# Space secret to lock the admin account (defaults to a placeholder otherwise).
ENV GF_SERVER_ROOT_URL="https://samdnx-mobis-mru.hf.space/grafana/" \
    GF_SERVER_SERVE_FROM_SUB_PATH="true" \
    GF_PATHS_DATA="/tmp/grafana" \
    GF_PATHS_LOGS="/tmp/grafana/logs" \
    GF_PATHS_PLUGINS="/tmp/grafana/plugins" \
    GF_PATHS_PROVISIONING="/etc/grafana/provisioning" \
    GF_AUTH_ANONYMOUS_ENABLED="true" \
    GF_AUTH_ANONYMOUS_ORG_ROLE="Viewer" \
    GF_USERS_ALLOW_SIGN_UP="false" \
    GF_ANALYTICS_REPORTING_ENABLED="false" \
    GF_ANALYTICS_CHECK_FOR_UPDATES="false" \
    GF_SECURITY_ADMIN_PASSWORD="mobaz-change-me" \
    GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH="/etc/grafana/dashboards/mobaz.json" \
    PORT=7860

EXPOSE 7860
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/mobaz.conf"]