feat: homelab deployment - NPM + IONOS DNS + monitoring + NAS backup

- Restructured docker-compose for Nginx Proxy Manager (no custom nginx)
- Added domain wordly.art configuration
- Added Prometheus + Grafana monitoring stack with pre-configured dashboards
- Added PostgreSQL backup script to NAS (daily/weekly/monthly rotation)
- Added alert rules for backend, system, and Docker metrics
- Updated deployment guide for NPM + IONOS DNS homelab setup
- Added marketing plan document
- PDF translator and watermark support
- Enhanced middleware, routes, and translator modules

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 11:43:28 +02:00
parent 16ac7ca2b9
commit ce8e150a61
110 changed files with 6935 additions and 4301 deletions

View File

@@ -26,11 +26,15 @@ FROM python:3.12-slim AS production
WORKDIR /app
# Install runtime dependencies only
# Install runtime dependencies + LibreOffice headless (required for DOCX→PDF)
RUN apt-get update && apt-get install -y --no-install-recommends \
libmagic1 \
libpq5 \
curl \
fonts-noto \
fonts-noto-cjk \
fonts-noto-cjk-extra \
libreoffice-writer-nogui \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
@@ -38,8 +42,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Create non-root user for security
RUN groupadd -r translator && useradd -r -g translator translator
# Create non-root user with a proper home directory (LibreOffice needs it)
RUN groupadd -r translator && \
useradd -r -g translator -m -d /home/translator translator && \
mkdir -p /home/translator/.cache && \
chown -R translator:translator /home/translator
# Create necessary directories
RUN mkdir -p /app/uploads /app/outputs /app/logs /app/temp \

View File

@@ -6,19 +6,28 @@ echo "🚀 Starting Document Translation API..."
# Wait for database to be ready (if DATABASE_URL is set)
if [ -n "$DATABASE_URL" ]; then
echo "⏳ Waiting for database to be ready..."
# Extract host and port from DATABASE_URL
# postgresql://user:pass@host:port/db
DB_HOST=$(echo $DATABASE_URL | sed -e 's/.*@\([^:]*\):.*/\1/')
DB_PORT=$(echo $DATABASE_URL | sed -e 's/.*:\([0-9]*\)\/.*/\1/')
# Extract host and port from DATABASE_URL (handles postgresql+asyncpg:// and postgresql://)
DB_HOST=$(python -c "
import re
m = re.search(r'@([^:/]+)', '$DATABASE_URL')
print(m.group(1) if m else 'postgres')
")
DB_PORT=$(python -c "
import re
m = re.search(r'@[^:]+:(\d+)', '$DATABASE_URL')
print(m.group(1) if m else '5432')
")
echo " Connecting to ${DB_HOST}:${DB_PORT}..."
# Wait up to 30 seconds for database
for i in {1..30}; do
for i in $(seq 1 30); do
if python -c "
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('$DB_HOST', $DB_PORT))
s.connect(('$DB_HOST', int('$DB_PORT')))
s.close()
exit(0)
except:
@@ -30,7 +39,7 @@ except:
echo " Waiting for database... ($i/30)"
sleep 1
done
# Run database migrations
echo "📦 Running database migrations..."
alembic upgrade head || echo "⚠️ Migration skipped (may already be up to date)"
@@ -39,15 +48,23 @@ fi
# Wait for Redis if configured
if [ -n "$REDIS_URL" ]; then
echo "⏳ Waiting for Redis..."
REDIS_HOST=$(echo $REDIS_URL | sed -e 's/redis:\/\/\([^:]*\):.*/\1/')
REDIS_PORT=$(echo $REDIS_URL | sed -e 's/.*:\([0-9]*\)\/.*/\1/')
for i in {1..10}; do
REDIS_HOST=$(python -c "
import re
m = re.search(r'://([^:/]+)', '$REDIS_URL')
print(m.group(1) if m else 'redis')
")
REDIS_PORT=$(python -c "
import re
m = re.search(r'://[^:]+:(\d+)', '$REDIS_URL')
print(m.group(1) if m else '6379')
")
for i in $(seq 1 10); do
if python -c "
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('$REDIS_HOST', $REDIS_PORT))
s.connect(('$REDIS_HOST', int('$REDIS_PORT')))
s.close()
exit(0)
except: