chore: upgrade logging stack - mirrors, Alloy, Loki, Grafana (#96, #97, #98, #99) #102

Merged
egullickson merged 8 commits from issue-96-update-mirror-base-images into main 2026-02-06 02:16:51 +00:00
14 changed files with 99 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
{
"version": "6.2.0",
"architecture": "simplified-5-container",
"architecture": "9-container",
"repository": {
"host": "gitea",
"owner": "egullickson",
@@ -51,7 +51,7 @@
"project_overview": {
"instruction": "Start with README.md for complete architecture context",
"files": ["README.md"],
"completeness": "100% - all navigation and 5-container architecture information"
"completeness": "100% - all navigation and 9-container architecture information"
},
"application_feature_work": {
"instruction": "Load entire application feature directory (features are modules within backend)",
@@ -104,6 +104,26 @@
"type": "cache",
"description": "Redis cache with AOF persistence",
"port": 6379
},
"mvp-ocr": {
"type": "ocr_service",
"description": "Python-based OCR for document text extraction",
"port": 8000
},
"mvp-loki": {
"type": "log_aggregation",
"description": "Grafana Loki for centralized log storage (30-day retention)",
"port": 3100
},
"mvp-alloy": {
"type": "log_collector",
"description": "Grafana Alloy for log collection and forwarding to Loki",
"port": 12345
},
"mvp-grafana": {
"type": "log_visualization",
"description": "Grafana for log querying and visualization",
"port": 3000
}
},
"application_features": {
@@ -290,6 +310,6 @@
"single_tenant_architecture": true,
"simplified_deployment": true,
"docker_first_development": true,
"container_count": 5
"container_count": 9
}
}

View File

@@ -171,7 +171,7 @@ jobs:
# Start shared infrastructure services (database, cache, logging)
# These persist across blue-green deployments
docker compose -f $COMPOSE_FILE -f $COMPOSE_BLUE_GREEN -f $COMPOSE_PROD up -d \
mvp-postgres mvp-redis mvp-loki mvp-promtail mvp-grafana
mvp-postgres mvp-redis mvp-loki mvp-alloy mvp-grafana
- name: Start target stack
run: |

View File

@@ -1,6 +1,6 @@
# MotoVaultPro
Single-tenant vehicle management application with 9-container architecture (6 application: Traefik, Frontend, Backend, OCR, PostgreSQL, Redis + 3 logging: Loki, Promtail, Grafana).
Single-tenant vehicle management application with 9-container architecture (6 application: Traefik, Frontend, Backend, OCR, PostgreSQL, Redis + 3 logging: Loki, Alloy, Grafana).
## Files
@@ -173,7 +173,7 @@ Issues are the source of truth. See `.ai/workflow-contract.json` for complete wo
## Architecture Context for AI
### 9-Container Architecture
**MotoVaultPro uses a unified architecture:** A single-tenant application with 9 containers - 6 application (Traefik, Frontend, Backend, OCR, PostgreSQL, Redis) + 3 logging (Loki, Promtail, Grafana). Application features in `backend/src/features/[name]/` are self-contained modules within the backend service, including the platform feature for vehicle data and VIN decoding. See `docs/LOGGING.md` for unified logging system documentation.
**MotoVaultPro uses a unified architecture:** A single-tenant application with 9 containers - 6 application (Traefik, Frontend, Backend, OCR, PostgreSQL, Redis) + 3 logging (Loki, Alloy, Grafana). Application features in `backend/src/features/[name]/` are self-contained modules within the backend service, including the platform feature for vehicle data and VIN decoding. See `docs/LOGGING.md` for unified logging system documentation.
### Key Principles for AI Understanding
- **Feature Capsule Organization**: Application features are self-contained modules within the backend

View File

@@ -1,6 +1,6 @@
# config/
Configuration files for the 5-container architecture.
Configuration files for the 9-container architecture (6 application + 3 logging).
## Subdirectories

29
config/alloy/config.alloy Normal file
View File

@@ -0,0 +1,29 @@
discovery.docker "containers" {
host = "unix:///var/run/docker.sock"
refresh_interval = "5s"
}
discovery.relabel "containers" {
targets = discovery.docker.containers.targets
rule {
source_labels = ["__meta_docker_container_name"]
regex = "/(.*)"
target_label = "container"
}
rule {
source_labels = ["__meta_docker_container_label_com_docker_compose_service"]
target_label = "service"
}
}
loki.source.docker "containers" {
host = "unix:///var/run/docker.sock"
targets = discovery.relabel.containers.output
forward_to = [loki.write.default.receiver]
}
loki.write "default" {
endpoint {
url = "http://mvp-loki:3100/loki/api/v1/push"
}
}

View File

@@ -15,24 +15,23 @@ ingester:
schema_config:
configs:
- from: 2020-01-01
store: boltdb-shipper
store: tsdb
object_store: filesystem
schema: v11
schema: v13
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/boltdb-shipper-active
cache_location: /loki/boltdb-shipper-cache
shared_store: filesystem
tsdb_shipper:
active_index_directory: /loki/tsdb-index
cache_location: /loki/tsdb-cache
filesystem:
directory: /loki/chunks
compactor:
working_directory: /loki/compactor
shared_store: filesystem
limits_config:
retention_period: 720h # 30 days
allow_structured_metadata: false

View File

@@ -1,21 +0,0 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://mvp-loki:3100/loki/api/v1/push
scrape_configs:
- job_name: containers
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
target_label: 'service'

View File

@@ -266,7 +266,7 @@ services:
# Log Aggregation - Loki
mvp-loki:
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/loki:2.9.0
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/loki:3.6.1
container_name: mvp-loki
restart: unless-stopped
volumes:
@@ -286,20 +286,29 @@ services:
max-size: "10m"
max-file: "3"
# Log Aggregation - Promtail
mvp-promtail:
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/promtail:2.9.0
container_name: mvp-promtail
# Log Aggregation - Alloy (replaces Promtail)
mvp-alloy:
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/alloy:v1.12.2
container_name: mvp-alloy
restart: unless-stopped
volumes:
- ./config/promtail/config.yml:/etc/promtail/config.yml:ro
- ./config/alloy/config.alloy:/etc/alloy/config.alloy
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
command: -config.file=/etc/promtail/config.yml
command:
- run
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
networks:
- backend
depends_on:
- mvp-loki
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://localhost:12345/ready || exit 1"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: json-file
options:
@@ -308,7 +317,7 @@ services:
# Log Aggregation - Grafana
mvp-grafana:
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/grafana:10.0.0
image: ${REGISTRY_MIRRORS:-git.motovaultpro.com/egullickson/mirrors}/grafana/grafana:12.4.0-21693836646
container_name: mvp-grafana
restart: unless-stopped
environment:

View File

@@ -2,14 +2,20 @@
## Architecture Summary
MotoVaultPro is a single-tenant vehicle management application built with a **5-container Docker-first architecture**. All development and deployment occurs in production-configured containers with no local installation dependencies.
MotoVaultPro is a single-tenant vehicle management application built with a **9-container Docker-first architecture** (6 application + 3 logging). All development and deployment occurs in production-configured containers with no local installation dependencies.
### Core Containers
### Application Containers (6)
1. **Traefik** - Reverse proxy and service discovery
2. **Frontend** - React SPA with Vite (Node.js 20 + nginx)
3. **Backend** - Node.js API with Fastify (Node.js 20) - includes platform feature module
4. **PostgreSQL** - Primary database (PostgreSQL 18)
5. **Redis** - Caching layer (Redis 8)
4. **OCR** - Python-based document text extraction
5. **PostgreSQL** - Primary database (PostgreSQL 18)
6. **Redis** - Caching layer (Redis 8)
### Logging Containers (3)
7. **Loki** - Centralized log storage (30-day retention)
8. **Alloy** - Log collection and forwarding
9. **Grafana** - Log querying and visualization
### Key Architectural Principles
- **Production-Only**: All services use production builds and configuration

View File

@@ -4,7 +4,7 @@
**Classification:** Internal/Confidential
**Audit Date:** December 13, 2025
**Application Version:** 1.0.0
**Architecture:** 5-Container Single-Tenant Docker Stack
**Architecture:** 9-Container Single-Tenant Docker Stack (6 application + 3 logging)
---
@@ -12,7 +12,7 @@
### 1.1 High-Level Assessment
**MotoVaultPro** is an automotive vehicle management platform built on a modern 5-container Docker architecture. The application demonstrates solid architectural foundations with proper authentication, modular feature design, and production-ready deployment configuration.
**MotoVaultPro** is an automotive vehicle management platform built on a modern 9-container Docker architecture (6 application + 3 logging). The application demonstrates solid architectural foundations with proper authentication, modular feature design, and production-ready deployment configuration.
### 1.2 Key Findings Summary

View File

@@ -1,6 +1,6 @@
# Database Schema Overview
Complete database schema for MotoVaultPro 5-container architecture with 15 feature capsules.
Complete database schema for MotoVaultPro 9-container architecture with 15 feature capsules.
## Migration System

View File

@@ -102,14 +102,14 @@ This creates `.env.logging` which is sourced by docker-compose.
+-----------------------------------------------------------------------+
|
v
Promtail --> Loki (30-day retention) --> Grafana
Alloy --> Loki (30-day retention) --> Grafana
```
## Troubleshooting
### Logs not appearing in Grafana
1. Check Promtail is running: `docker logs mvp-promtail`
1. Check Alloy is running: `docker logs mvp-alloy`
2. Check Loki is healthy: `curl http://localhost:3100/ready`
3. Verify log rotation is not too aggressive

View File

@@ -4,7 +4,7 @@
# Build argument for registry (defaults to Gitea mirrors, falls back to Docker Hub)
ARG REGISTRY_MIRRORS=git.motovaultpro.com/egullickson/mirrors
FROM ${REGISTRY_MIRRORS}/python:3.11-slim
FROM ${REGISTRY_MIRRORS}/python:3.13-slim
# System dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \

View File

@@ -14,12 +14,10 @@ IMAGES=(
"postgres:18-alpine"
"redis:8.4-alpine"
"traefik:v3.6"
"python:3.11-slim"
"docker:24.0"
"docker:24.0-dind"
"grafana/loki:2.9.0"
"grafana/promtail:2.9.0"
"grafana/grafana:10.0.0"
"python:3.13-slim"
"grafana/loki:3.6.1"
"grafana/alloy:v1.12.2"
"grafana/grafana:12.4.0-21693836646"
)
echo "========================================"