feat: Enhance Docker setup and application status reporting with build date and container info
This commit is contained in:
+14
-17
@@ -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"]
|
||||
|
||||
+16
-4
@@ -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
|
||||
}
|
||||
|
||||
+67
-1
@@ -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
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+2
-3
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -14,10 +14,20 @@
|
||||
</p>
|
||||
<div class="bg-blue-100 border-l-4 border-blue-500 text-blue-700 p-4 my-4" role="alert">
|
||||
<p><strong>App Version:</strong> {{ app_version }}</p>
|
||||
<p><strong>Build Date:</strong> {{ build_date }}</p>
|
||||
<p><strong>Debug Mode:</strong> {{ "Enabled" if debug_enabled else "Disabled" }}</p>
|
||||
{% if last_check %}
|
||||
<p><strong>Last Check:</strong> {{ last_check }}</p>
|
||||
{% endif %}
|
||||
{% if container_info.is_docker %}
|
||||
<p><strong>Container ID:</strong> {{ container_info.id }}</p>
|
||||
{% endif %}
|
||||
{% if container_info.git_sha and container_info.git_sha != 'Unknown' %}
|
||||
<p><strong>Git Commit:</strong> {{ container_info.git_sha }}</p>
|
||||
{% endif %}
|
||||
{% if container_info.runtime_info %}
|
||||
<p><strong>Container Started:</strong> {{ container_info.runtime_info }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user