From d66fef7ad49fe5185ec98862d1f37155f529edf8 Mon Sep 17 00:00:00 2001
From: Christian Krakau-Louis
Date: Mon, 7 Apr 2025 00:43:14 +0200
Subject: [PATCH] feat: Enhance Docker setup and application status reporting
with build date and container info
---
Dockerfile | 31 +++++------
app/views/general.py | 20 +++++--
app/views/status.py | 68 +++++++++++++++++++++++-
docker-compose.yaml | 5 +-
docker/build-scripts/save-build-date.sh | 11 ----
frontend/templates/status_dashboard.html | 10 ++++
6 files changed, 109 insertions(+), 36 deletions(-)
delete mode 100644 docker/build-scripts/save-build-date.sh
diff --git a/Dockerfile b/Dockerfile
index 9f58d8f6..d16c09a6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,41 +1,38 @@
-# Stage 1: Build dependencies
+# Use multi-stage build for a smaller final image
FROM python:3.13 AS builder
WORKDIR /app
+# Copy requirements first for better layer caching
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
-# Stage 2: Final image
+# Second stage for the actual runtime
FROM python:3.13.2-slim
WORKDIR /app
-# Copy installed dependencies
+# Copy installed packages from builder stage
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
-# Copy application files correctly
+# Copy application code
COPY ./app /app/app
-COPY ./frontend /app/frontend
COPY ./VERSION /app/VERSION
-COPY ./LICENSE /app/LICENSE
+COPY ./frontend /app/frontend
-# Copy build script and generate build date
-COPY ./docker/build-scripts/save-build-date.sh /tmp/
-RUN mkdir -p /app/docker/build-scripts/ && \
- cp /tmp/save-build-date.sh /app/docker/build-scripts/ && \
- chmod +x /tmp/save-build-date.sh && \
- /tmp/save-build-date.sh
+# Create runtime_info directory
+RUN mkdir -p /app/runtime_info
-# Set build date as environment variable
-#ENV BUILD_DATE=$(cat /app/BUILD_DATE)
+# Create necessary directories
+RUN mkdir -p /workdir
-# Set Python path explicitly
+# Set environment variables
ENV PYTHONPATH=/app
+ENV PYTHONUNBUFFERED=1
-# Expose API port
+# Expose the port the app runs on
EXPOSE 8000
-WORKDIR /app
+# Default command
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
diff --git a/app/views/general.py b/app/views/general.py
index ed51af7d..5b010a3f 100644
--- a/app/views/general.py
+++ b/app/views/general.py
@@ -1,18 +1,19 @@
"""
General routes for the application homepage and basic pages.
"""
-from fastapi import Request, HTTPException
+from fastapi import Request, HTTPException, Depends
from fastapi.responses import FileResponse
from pathlib import Path
from datetime import date
+from sqlalchemy.orm import Session
-from app.views.base import APIRouter, templates, require_login
+from app.views.base import APIRouter, templates, require_login, get_db
from app.utils.config_validator import get_provider_status, validate_storage_configs
router = APIRouter()
@router.get("/", include_in_schema=False)
-async def serve_index(request: Request):
+async def serve_index(request: Request, db: Session = Depends(get_db)):
"""Serve the index/home page."""
# Get provider information from config validator
providers = get_provider_status()
@@ -27,9 +28,20 @@ async def serve_index(request: Request):
's3', 'ftp', 'webdav',
'google_drive', 'onedrive'])
+ # Query the actual file count from the database
+ processed_files = 0
+ try:
+ # Import the model here to avoid circular imports
+ from app.models import FileRecord
+ processed_files = db.query(FileRecord).count()
+ except Exception as e:
+ # Log error but continue (don't break the page if DB query fails)
+ from app.views.base import logger
+ logger.error(f"Error counting files: {str(e)}")
+
# Create stats object to pass to the template
stats = {
- "processed_files": 0, # Placeholder - would need actual DB query
+ "processed_files": processed_files,
"active_integrations": configured_providers,
"storage_targets": configured_storage_targets
}
diff --git a/app/views/status.py b/app/views/status.py
index a1a93cc9..a7297d34 100644
--- a/app/views/status.py
+++ b/app/views/status.py
@@ -3,6 +3,8 @@ Status and configuration views for the application.
"""
from fastapi import Request
from datetime import datetime
+import os
+import subprocess
from app.views.base import APIRouter, templates, require_login, settings
@@ -19,14 +21,78 @@ async def status_dashboard(request: Request):
# Get provider status
providers = get_provider_status()
+ # Get build date from settings
+ build_date = getattr(settings, 'build_date', 'Unknown')
+
+ # Try to get container information
+ container_info = {}
+ try:
+ # Check for Docker environment
+ if os.path.exists('/.dockerenv'):
+ # We're inside a Docker container
+ container_info['is_docker'] = True
+
+ # Try to get container ID
+ try:
+ with open('/proc/self/cgroup', 'r') as f:
+ for line in f:
+ if 'docker' in line:
+ container_id = line.split('/')[-1].strip()
+ container_info['id'] = container_id[:12] # Short ID format
+ break
+ except Exception:
+ container_info['id'] = 'Unknown'
+
+ # Try to get Git commit SHA from runtime info
+ try:
+ # First check runtime info directory
+ if os.path.exists('/app/runtime_info/GIT_SHA'):
+ with open('/app/runtime_info/GIT_SHA', 'r') as f:
+ git_sha = f.read().strip()
+ # Then try environment variable
+ else:
+ git_sha = os.environ.get('GIT_COMMIT_SHA', '')
+
+ # If still not found, try the original file location
+ if not git_sha and os.path.exists('/.git-commit-sha'):
+ with open('/.git-commit-sha', 'r') as f:
+ git_sha = f.read().strip()
+
+ container_info['git_sha'] = git_sha[:7] if git_sha and git_sha != 'unknown' else 'Unknown'
+ except Exception:
+ container_info['git_sha'] = 'Unknown'
+
+ # Try to get runtime information
+ try:
+ if os.path.exists('/app/runtime_info/RUNTIME_INFO'):
+ with open('/app/runtime_info/RUNTIME_INFO', 'r') as f:
+ container_info['runtime_info'] = f.read().strip()
+ except Exception:
+ pass
+ else:
+ container_info['is_docker'] = False
+
+ # If not in Docker, try to get Git info directly
+ try:
+ git_sha = subprocess.check_output(['git', 'rev-parse', 'HEAD'],
+ stderr=subprocess.DEVNULL,
+ text=True).strip()[:7]
+ container_info['git_sha'] = git_sha
+ except (subprocess.SubprocessError, FileNotFoundError):
+ container_info['git_sha'] = 'Unknown'
+ except Exception:
+ container_info = {'is_docker': False, 'id': 'Unknown', 'git_sha': 'Unknown'}
+
return templates.TemplateResponse(
"status_dashboard.html",
{
"request": request,
"providers": providers,
"app_version": settings.version,
+ "build_date": build_date,
"debug_enabled": getattr(settings, 'debug', False),
- "last_check": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ "last_check": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+ "container_info": container_info
}
)
diff --git a/docker-compose.yaml b/docker-compose.yaml
index d7faf546..e09c5b23 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -10,7 +10,7 @@ services:
working_dir: /workdir
# We'll run uvicorn from the container's /app code
- command: ["sh", "-c", "cd /app && uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers"]
+ command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--proxy-headers"]
# Environment variables
environment:
@@ -50,7 +50,7 @@ services:
- redis
- gotenberg
- # Mount the shared directory (and optionally your code if you want dev mode)
+ # Mount the shared directory
volumes:
- /var/docparse/workdir:/workdir
@@ -59,7 +59,6 @@ services:
container_name: gotenberg
restart: always
-
redis:
image: redis:alpine
container_name: document_redis
diff --git a/docker/build-scripts/save-build-date.sh b/docker/build-scripts/save-build-date.sh
deleted file mode 100644
index 3a459f50..00000000
--- a/docker/build-scripts/save-build-date.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# Get current date in Month DD, YYYY format (e.g., May 15, 2024)
-BUILD_DATE=$(date +"%B %d, %Y")
-
-# Save it to the BUILD_DATE file
-echo $BUILD_DATE > /app/BUILD_DATE
-
-# Also set it as an environment variable
-echo "Setting BUILD_DATE=$BUILD_DATE"
-export BUILD_DATE
diff --git a/frontend/templates/status_dashboard.html b/frontend/templates/status_dashboard.html
index 7ebdc987..66baea96 100644
--- a/frontend/templates/status_dashboard.html
+++ b/frontend/templates/status_dashboard.html
@@ -14,10 +14,20 @@
App Version: {{ app_version }}
+
Build Date: {{ build_date }}
Debug Mode: {{ "Enabled" if debug_enabled else "Disabled" }}
{% if last_check %}
Last Check: {{ last_check }}
{% endif %}
+ {% if container_info.is_docker %}
+
Container ID: {{ container_info.id }}
+ {% endif %}
+ {% if container_info.git_sha and container_info.git_sha != 'Unknown' %}
+
Git Commit: {{ container_info.git_sha }}
+ {% endif %}
+ {% if container_info.runtime_info %}
+
Container Started: {{ container_info.runtime_info }}
+ {% endif %}