feat: complete dockerization architecture with data/logs persistence and prod export script v1.3.0

This commit is contained in:
Daniel Bedeleanu
2026-04-11 12:32:06 +03:00
parent c71a815792
commit 2e5ce8d153
15 changed files with 485 additions and 23 deletions

35
backend/Dockerfile Normal file
View File

@@ -0,0 +1,35 @@
FROM python:3.12-slim
# Install system dependencies required for python-ldap (needed by backend)
RUN apt-get update && apt-get install -y \
build-essential \
libldap2-dev \
libsasl2-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy requirements and install
COPY backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Create non-root user
RUN adduser --system --group appuser
# Copy application files
COPY backend ./backend
# We define the data dir explicitly for Docker
ENV DATA_DIR="/app/data"
ENV LOGS_DIR="/app/logs"
# Ensure the appuser can write to data and logs if we pre-create them,
# although Docker volumes will handle ownership context.
RUN mkdir -p /app/data /app/logs && chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
# Start Uvicorn pointing to the backend module
CMD ["python", "-m", "uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "8000"]

View File

@@ -4,9 +4,11 @@ import os
# Get absolute path for the backend directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, "data")
# Create data directory if it doesn't exist in the backend folder
# Use DATA_DIR from environment if running in Docker, otherwise fallback to local 'data' folder
DATA_DIR = os.environ.get("DATA_DIR", os.path.join(BASE_DIR, "data"))
# Create data directory if it doesn't exist
os.makedirs(DATA_DIR, exist_ok=True)
# Handle absolute path for SQLite (needs 4 slashes on Unix)

51
backend/logger.py Normal file
View File

@@ -0,0 +1,51 @@
import logging
import os
from logging.handlers import RotatingFileHandler
# Define paths
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# Fallback to local 'logs' dir if not overridden in Docker
LOGS_DIR = os.environ.get("LOGS_DIR", os.path.join(BASE_DIR, "logs"))
# Ensure directory exists
os.makedirs(LOGS_DIR, exist_ok=True)
LOG_FILE_PATH = os.path.join(LOGS_DIR, "backend.log")
def setup_logger():
logger = logging.getLogger("ainventory")
logger.setLevel(logging.INFO)
# Avoid duplicate handlers if setup multiple times
if logger.handlers:
return logger
formatter = logging.Formatter(
"[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
# Console Handler
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
# File Handler (10MB max, keep 5 backups)
file_handler = RotatingFileHandler(
LOG_FILE_PATH, maxBytes=10*1024*1024, backupCount=5
)
file_handler.setFormatter(formatter)
# Attach handlers
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# Special redirect for uvicorn logs to also go to file
uvicorn_logger = logging.getLogger("uvicorn")
uvicorn_logger.addHandler(file_handler)
uvicorn_access_logger = logging.getLogger("uvicorn.access")
uvicorn_access_logger.addHandler(file_handler)
return logger
log = setup_logger()

174
backend/logs/backend.log Normal file
View File

@@ -0,0 +1,174 @@
[2026-04-11 12:25:22] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:25:22] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:25:22] [INFO] [uvicorn.error] Started server process [87758]
[2026-04-11 12:25:22] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:25:22] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:25:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:25:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:26:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:26:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:27:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:27:39] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:27:39] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:27:39] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:27:39] [INFO] [uvicorn.error] Finished server process [87758]
[2026-04-11 12:27:40] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:27:40] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:27:40] [INFO] [uvicorn.error] Started server process [87911]
[2026-04-11 12:27:40] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:27:40] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:27:41] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:27:41] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:27:41] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:27:41] [INFO] [uvicorn.error] Finished server process [87911]
[2026-04-11 12:27:42] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:27:42] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:27:42] [INFO] [uvicorn.error] Started server process [87914]
[2026-04-11 12:27:42] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:27:42] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:27:43] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:27:43] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:27:43] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:27:43] [INFO] [uvicorn.error] Finished server process [87914]
[2026-04-11 12:27:44] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:27:44] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:27:44] [INFO] [uvicorn.error] Started server process [87922]
[2026-04-11 12:27:44] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:27:44] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Finished server process [87922]
[2026-04-11 12:27:46] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:27:46] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Started server process [87926]
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:27:46] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Finished server process [87926]
[2026-04-11 12:27:52] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:27:52] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Started server process [87933]
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:27:52] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:27:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:28:02] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:02] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:02] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:02] [INFO] [uvicorn.error] Finished server process [87933]
[2026-04-11 12:28:03] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:03] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:03] [INFO] [uvicorn.error] Started server process [87948]
[2026-04-11 12:28:03] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:03] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:04] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:04] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:04] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:04] [INFO] [uvicorn.error] Finished server process [87948]
[2026-04-11 12:28:05] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:05] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:05] [INFO] [uvicorn.error] Started server process [87957]
[2026-04-11 12:28:05] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:05] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:06] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Finished server process [87957]
[2026-04-11 12:28:07] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:07] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Started server process [87958]
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:07] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Finished server process [87958]
[2026-04-11 12:28:09] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:09] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Started server process [87960]
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:09] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:11] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:11] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:11] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:11] [INFO] [uvicorn.error] Finished server process [87960]
[2026-04-11 12:28:12] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:12] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:12] [INFO] [uvicorn.error] Started server process [87968]
[2026-04-11 12:28:12] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:12] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:13] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:13] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:13] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:13] [INFO] [uvicorn.error] Finished server process [87968]
[2026-04-11 12:28:14] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:14] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:14] [INFO] [uvicorn.error] Started server process [87971]
[2026-04-11 12:28:14] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:14] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Finished server process [87971]
[2026-04-11 12:28:20] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:20] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Started server process [87989]
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:20] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:28:36] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:28:36] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:28:36] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:28:36] [INFO] [uvicorn.error] Finished server process [87989]
[2026-04-11 12:28:37] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:28:37] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:28:37] [INFO] [uvicorn.error] Started server process [88059]
[2026-04-11 12:28:37] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:28:37] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:28:37] [WARNING] [uvicorn.error] Invalid HTTP request received.
[2026-04-11 12:28:37] [INFO] [uvicorn.access] ::ffff:127.0.0.1:0 - "POST /exa.language_server_pb.LanguageServerService/GetUnleashData HTTP/1.1" 404
[2026-04-11 12:28:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:29:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:29:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:30:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:30:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:31:24] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200
[2026-04-11 12:31:30] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:31:30] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:31:30] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:31:30] [INFO] [uvicorn.error] Finished server process [88059]
[2026-04-11 12:31:31] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:31:31] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Started server process [88476]
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Finished server process [88476]
[2026-04-11 12:31:31] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:31:31] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Started server process [88477]
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:31:31] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:31:32] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:31:32] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:31:32] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:31:32] [INFO] [uvicorn.error] Finished server process [88477]
[2026-04-11 12:31:33] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:31:33] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:31:33] [INFO] [uvicorn.error] Started server process [88478]
[2026-04-11 12:31:33] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:31:33] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:31:34] [INFO] [uvicorn.error] Shutting down
[2026-04-11 12:31:34] [INFO] [uvicorn.error] Waiting for application shutdown.
[2026-04-11 12:31:34] [INFO] [uvicorn.error] Application shutdown complete.
[2026-04-11 12:31:34] [INFO] [uvicorn.error] Finished server process [88478]
[2026-04-11 12:31:35] [INFO] [ainventory] Database tables verified.
[2026-04-11 12:31:35] [INFO] [ainventory] TFM aInventory API process started.
[2026-04-11 12:31:35] [INFO] [uvicorn.error] Started server process [88490]
[2026-04-11 12:31:35] [INFO] [uvicorn.error] Waiting for application startup.
[2026-04-11 12:31:35] [INFO] [uvicorn.error] Application startup complete.
[2026-04-11 12:31:54] [INFO] [uvicorn.access] ::ffff:192.168.84.140:0 - "GET /items/ HTTP/1.1" 200

View File

@@ -3,11 +3,14 @@ from fastapi.middleware.cors import CORSMiddleware
from . import models
from .database import engine
from .routers import items, operations, users, categories
from .logger import log
# Create the database tables
models.Base.metadata.create_all(bind=engine)
log.info("Database tables verified.")
app = FastAPI(title="TFM aInventory API", version="1.1.0")
log.info("TFM aInventory API process started.")
# Setup Cross-Origin for Client interaction (PWA)
app.add_middleware(

View File

@@ -11,7 +11,7 @@ router = APIRouter(prefix="/users", tags=["users"])
pwd_context = CryptContext(schemes=["pbkdf2_sha256"], deprecated="auto")
def get_ldap_config():
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "ldap_config.json")
config_path = os.path.join(database.DATA_DIR, "ldap_config.json")
if os.path.exists(config_path):
with open(config_path, "r") as f:
return json.load(f)
@@ -209,7 +209,7 @@ def get_ldap_settings():
@router.post("/ldap-config")
def update_ldap_settings(config: dict):
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "ldap_config.json")
config_path = os.path.join(database.DATA_DIR, "ldap_config.json")
with open(config_path, "w") as f:
json.dump(config, f)
return {"message": "Config saved"}