Compare commits

..

2 Commits

Author SHA1 Message Date
Sönke Domröas
ce169a7512 recent changes 2026-01-29 07:12:47 +01:00
Sönke Domröas
f8a24defd8 rm homarr 2025-10-24 06:14:55 +02:00
9 changed files with 532 additions and 38 deletions

View File

@@ -0,0 +1,16 @@
services:
beszel-agent:
image: henrygd/beszel-agent
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /home/soenke/docker-data/beszel-agent/beszel_agent_data:/var/lib/beszel-agent
# monitor other disks / partitions by mounting a folder in /extra-filesystems
# - /mnt/disk/.beszel:/extra-filesystems/sda1:ro
environment:
LISTEN: 45876
KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVA2+hStjbFgCmiZl80+JFDZZxePZ4fRV8hEwLj3/o5'
TOKEN: b608d327-43be-4a2c-a4fb-7e6606639fab
HUB_URL: https://beszel.domr.ovh

View File

@@ -143,12 +143,6 @@ haus.home.domroese.eu {
reverse_proxy 192.168.1.65:8472 reverse_proxy 192.168.1.65:8472
} }
homarr.domr.ovh,
homarr.home.domroese.eu:443 {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:7575
}
homebox.domr.ovh, homebox.domr.ovh,
homebox.home.domroese.eu:443 { homebox.home.domroese.eu:443 {
tls soenke@domroese.eu tls soenke@domroese.eu
@@ -182,6 +176,12 @@ jenkins.home.domroese.eu {
reverse_proxy 192.168.1.65:8040 reverse_proxy 192.168.1.65:8040
} }
journal.domr.ovh,
journiv.domr.ovh {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:8198
}
kopia.domr.ovh, kopia.domr.ovh,
kopia.home.domroese.eu { kopia.home.domroese.eu {
tls soenke@domroese.eu tls soenke@domroese.eu
@@ -189,6 +189,7 @@ kopia.home.domroese.eu {
} }
mealie.domr.ovh, mealie.domr.ovh,
mealie.home.domroese.eu:443 { mealie.home.domroese.eu:443 {
tls soenke@domroese.eu tls soenke@domroese.eu

View File

@@ -9,7 +9,17 @@ auth.home.domroese.eu {
beszel.domr.ovh,
beszel.home.domroese.eu {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:7090
}
bit.domr.ovh,
bit.home.domroese.eu {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:4489
}
bookstack.domr.ovh, bookstack.domr.ovh,
bookstack.home.domroese.eu { bookstack.home.domroese.eu {
@@ -127,11 +137,10 @@ guac.home.domroese.eu {
reverse_proxy 192.168.1.65:6080 reverse_proxy 192.168.1.65:6080
} }
haus.domr.ovh,
homarr.domr.ovh, haus.home.domroese.eu {
homarr.home.domroese.eu:443 {
tls soenke@domroese.eu tls soenke@domroese.eu
reverse_proxy 192.168.1.65:7575 reverse_proxy 192.168.1.65:8472
} }
homebox.domr.ovh, homebox.domr.ovh,
@@ -147,6 +156,11 @@ homepage.home.domroese.eu:443 {
reverse_proxy 192.168.1.65:3891 reverse_proxy 192.168.1.65:3891
} }
huly.domr.ovh,
huly.home.domroese.eu {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:8087
}
ittools.domr.ovh:443, ittools.domr.ovh:443,
ittools.home.domroese.eu:443, ittools.home.domroese.eu:443,
@@ -169,6 +183,7 @@ kopia.home.domroese.eu {
} }
mealie.domr.ovh, mealie.domr.ovh,
mealie.home.domroese.eu:443 { mealie.home.domroese.eu:443 {
tls soenke@domroese.eu tls soenke@domroese.eu
@@ -243,6 +258,11 @@ api.plantit.home.domroese.eu:443 {
reverse_proxy 192.168.1.65:8632 reverse_proxy 192.168.1.65:8632
} }
portracker.domr.ovh,
portracker.home.domroese.eu:443 {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:4999
}

View File

@@ -1,5 +0,0 @@
homarr.domr.ovh,
homarr.home.domroese.eu:443 {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:7575
}

View File

@@ -1,22 +0,0 @@
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:latest
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
- /home/soenke/docker-data/homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=c99349e72b4267a0ba7a19fa2de53cfdbd73708974338d2abe36f1379fe8ba7c
ports:
- '7575:7575'
labels:
kuma.tools.tag.name: 'Tools'
kuma.tools.tag.color: '#FF9900'
kuma.homelab.tag.name: 'Homelab'
kuma.homelab.tag.color: '#FF9955'
kuma.organization.tag.name: 'Organization'
kuma.organization.tag.color: '#FF99AA'
kuma.homarr.http.name: 'homarr'
kuma.homarr.http.url: 'https://homarr.domr.ovh/'
kuma.homarr.http.tag_names: '[{"name": "tools", "value": "" }, {"name": "organization", "value": "" }]'

297
journiv/.env Normal file
View File

@@ -0,0 +1,297 @@
# ============================================================================
# Journiv Environment Configuration Template
# Copy this file to .env and customize for your deployment.
#
# Usage:
# cp env.template .env
# nano .env
# Required settings:
# - SECRET_KEY
# - DOMAIN_NAME
#
# If using PostgreSQL (DB_DRIVER=postgres), also set:
# - Either POSTGRES_PASSWORD (with optional components), OR
# - DATABASE_URL with a PostgreSQL URL (postgresql:// or postgres://)
# NOT BOTH - specifying both will cause startup to fail
#
# All other settings are optional.
# ============================================================================
# ============================================================================
# REQUIRED SETTINGS
# ============================================================================
# Secret key for JWT token signing and encryption
# Generate with:
# python -c "import secrets; print(secrets.token_urlsafe(32))"
# Or:
# openssl rand -base64 32
SECRET_KEY=gjQ/6282Fdf3p4hK61nx/OHmLJCluIQauz/mm5idPls
# ============================================================================
# DOMAIN CONFIGURATION
# ============================================================================
# Public domain name where Journiv is accessible.
# DO NOT include http:// or https://.
# DO NOT include trailing slashes.
#
# Examples:
DOMAIN_NAME=journiv.domr.ovh
DOMAIN_NAME=journal.domr.ovh
# DOMAIN_NAME=192.168.1.10
#
# WRONG:
# DOMAIN_NAME=https://journiv.example.com
# DOMAIN_NAME=journiv.example.com/
# Protocol scheme for public URLs: http or https
# IMPORTANT: Set to "https" for production deployments, especially when behind a reverse proxy (Traefik, Caddy, Nginx, etc.).
# - Default: "http" (for local development only)
# - Production: "https" (REQUIRED when behind reverse proxy or using SSL/TLS)
#
# Journiv uses this to generate correct public redirect URLs:
# {DOMAIN_SCHEME}://{DOMAIN_NAME}/#/oidc-finish
# {DOMAIN_SCHEME}://{DOMAIN_NAME}/#/login?logout=success
#
DOMAIN_SCHEME=https
# ============================================================================
# DATABASE CONFIGURATION
# ============================================================================
# Database driver selection: "sqlite" (default) or "postgres"
DB_DRIVER=sqlite
# Primary database URL (defaults to SQLite)
# For SQLite: sqlite:////data/journiv.db
# For PostgreSQL: postgresql://user:password@host:5432/dbname
DATABASE_URL=sqlite:////data/journiv.db
# When DB_DRIVER=postgres, you must specify EITHER:
# Option 1: POSTGRES_PASSWORD (with optional components below)
# Option 2: DATABASE_URL with a PostgreSQL URL (postgresql:// or postgres://)
# NOT BOTH - specifying both will cause startup to fail
# PostgreSQL password (required when DB_DRIVER=postgres and using Option 1)
POSTGRES_PASSWORD=oUPnKDY3stjREg7ctUYWrbnn4wNs0Yy3
# (Optional) PostgreSQL components for Docker deployments (used with POSTGRES_PASSWORD)
# Defaults are used if not specified:
# POSTGRES_HOST=postgres
# POSTGRES_USER=journiv
# POSTGRES_DB=journiv_prod (production) or journiv_dev (development)
# POSTGRES_PORT=5432
# POSTGRES_HOST=
#POSTGRES_USER=journiv
#POSTGRES_DB=journiv_prod
#POSTGRES_PORT=5432
# ============================================================================
# APPLICATION SETTINGS
# ============================================================================
APP_NAME=Journiv
# APP_VERSION=latest # Pin to a specific version for production if needed
# DEBUG=false
ENVIRONMENT=production
APP_PORT=8198
# ============================================================================
# API CONFIGURATION
# ============================================================================
# API_V1_PREFIX=/api/v1
# Enable CORS only when the frontend runs on a different origin.
# ENABLE_CORS=false
# Required when ENABLE_CORS=true.
# Example:
# CORS_ORIGINS=https://journiv.example.com,https://myapp.example.net
# CORS_ORIGINS=
# ============================================================================
# SECURITY SETTINGS
# ============================================================================
# ALGORITHM=HS256
# ACCESS_TOKEN_EXPIRE_MINUTES=15
# REFRESH_TOKEN_EXPIRE_DAYS=7
# Disable user signup
# DISABLE_SIGNUP=false
# ============================================================================
# OIDC CONFIGURATION
# ============================================================================
# Enable OIDC login (Pocket-ID, Keycloak, Authentik, etc.)
OIDC_ENABLED=true
# OIDC provider issuer
# Example: https://id.example.com or https://auth.example.com/realms/default
OIDC_ISSUER=https://auth.domr.ovh/application/o/journiv
# OIDC client credentials
OIDC_CLIENT_ID="L1wmsh8BqoGlQRO6ZULMkTCRGOhu9M0L3Im7tiGd"
OIDC_CLIENT_SECRET=MPhUBLM8p4soNCfpfbp0pgAxoaqRHj36EvTzALVicoVy7Tf1UrVh2ckXJtciGYNscuQpQ78c8j8MXb1a1pn3bvOcnGERSYC2uT9s4AXhchD5yTKBBfFEz4l15OMZNqvG
# OIDC redirect URI
# Must match provider configuration EXACTLY.
# Example:
# OIDC_REDIRECT_URI=https://journiv.example.com/api/v1/auth/oidc/callback
OIDC_REDIRECT_URI=https://journal.domr.ovh/api/v1/auth/oidc/callback
# OIDC scopes to request
# OIDC_SCOPES="openid email profile"
# Automatically create users from OIDC claims
# OIDC_AUTO_PROVISION=true
# Disable SSL verification (ONLY for local development with self-signed certs)
# OIDC_DISABLE_SSL_VERIFY=false
# Allow OIDC over HTTP (INSECURE). Recommended only for advanced users in isolated homelabs.
# Default: false
# OIDC_ALLOW_INSECURE_PROD=false
# ============================================================================
# REDIS CONFIGURATION (Optional)
# ============================================================================
# Optional Redis URL for OIDC state caching, rate-limit persistence, and Celery
# Example: redis://localhost:6379/0
# REDIS_URL=
# ============================================================================
# CELERY CONFIGURATION (For Import/Export)
# ============================================================================
# Celery broker and result backend
# If not set, defaults to REDIS_URL
# Examples:
# CELERY_BROKER_URL=redis://localhost:6379/0
# CELERY_RESULT_BACKEND=redis://localhost:6379/0
# CELERY_BROKER_URL=
# CELERY_RESULT_BACKEND=
# Celery task serialization (default: json)
# CELERY_TASK_SERIALIZER=json
# CELERY_RESULT_SERIALIZER=json
# CELERY_TIMEZONE=UTC
# CELERY_ENABLE_UTC=true
# ============================================================================
# IMPORT/EXPORT CONFIGURATION
# ============================================================================
# Maximum file size for import/export operations (in MB)
# IMPORT_EXPORT_MAX_FILE_SIZE_MB=500
# Days to keep export files before automatic cleanup
# Set to -1 to disable automatic cleanup.
# EXPORT_CLEANUP_DAYS=7
# Directories for import/export operations
# IMPORT_TEMP_DIR=/data/imports/temp
# EXPORT_DIR=/data/exports
# ============================================================================
# INTEGRATIONS (IMMICH)
# ============================================================================
# Default Immich base URL for all users on the instance.
# If set, users can leave the Immich URL field empty in the UI.
# Immich URL specified per user level in settting screens can be used to override this.
# Example: IMMICH_BASE_URL=https://immich.example.com
# Example: IMMICH_BASE_URL=http://192.168.1.1:2283
# IMMICH_BASE_URL=
# ============================================================================
# CONTENT SECURITY POLICY (CSP)
# ============================================================================
# ENABLE_CSP=true
# ENABLE_HSTS=true
# ENABLE_CSP_REPORTING=true
# Where browsers should POST CSP violation reports
# CSP_REPORT_URI=/api/v1/security/csp-report
# ============================================================================
# FILE STORAGE
# ============================================================================
# Directory for user-uploaded files and media
# MEDIA_ROOT=/data/media
# Maximum allowed upload size in MB
# MAX_FILE_SIZE_MB=50
# Allowed media MIME types (comma-separated)
# ALLOWED_MEDIA_TYPES=image/jpeg,image/png,image/gif,image/webp,image/heic,video/mp4,video/avi,video/mov,video/webm,video/x-m4v,audio/mpeg,audio/wav,audio/ogg,audio/m4a,audio/aac
# Allowed file extensions (comma-separated)
# ALLOWED_FILE_EXTENSIONS=.jpg,.jpeg,.png,.gif,.webp,.heic,.mp4,.avi,.mov,.webm,.m4v,.mp3,.wav,.ogg,.m4a,.aac
# Signed media URL TTL in seconds (for images and general media)
# Default 5 minutes
# MEDIA_SIGNED_URL_TTL_SECONDS=300
# Signed video URL TTL in seconds (for video streaming, longer to support playback of large files)
# Default 20 mins
# MEDIA_SIGNED_URL_VIDEO_TTL_SECONDS=1200
# Signed thumbnail URL TTL in seconds (used for caching thumbnails)
# Default 24 hours
# MEDIA_THUMBNAIL_SIGNED_URL_TTL_SECONDS=86400
# Grace period in seconds for signed media URL expiration checks
# MEDIA_SIGNED_URL_GRACE_SECONDS=60
# ============================================================================
# LOGGING
# ============================================================================
# LOG_LEVEL=INFO
# LOG_FILE=
# LOG_DIR=/data/logs
# ============================================================================
# EXTERNAL API CONFIGURATION
# ============================================================================
# OpenWeather API keys for weather data fetching
# Get your free API key at: https://openweathermap.org/api
# Weather service is optional - if not configured, weather features will be disabled
# OPEN_WEATHER_API_KEY_25=your-openweather-2-5-api-key-here
# OPEN_WEATHER_API_KEY_30=your-openweather-3-0-api-key-here
# ============================================================================
# RATE LIMITING
# ============================================================================
# Enable rate limiting (protects login endpoints)
# RATE_LIMITING_ENABLED=true
# Backend for rate-limit storage (default: in-memory)
# Example for Redis: redis://localhost:6379/1
# RATE_LIMIT_STORAGE_URI=memory://

5
journiv/Caddyfilepart Normal file
View File

@@ -0,0 +1,5 @@
journal.domr.ovh,
journiv.domr.ovh {
tls soenke@domroese.eu
reverse_proxy 192.168.1.65:8198
}

181
journiv/docker-compose.yml Normal file
View File

@@ -0,0 +1,181 @@
# Journiv Production Docker Compose (PostgreSQL).
# Journiv recommends using PostgreSQL based deployment over SQLite.
#
# Usage:
# docker compose up -d
#
# Required Environment Variables:
# SECRET_KEY - Generate with: python -c "import secrets; print(secrets.token_urlsafe(32))"
# DOMAIN_NAME - Needed when running in same-origin SPA mode (ENABLE_CORS=false).
# POSTGRES_PASSWORD - Must be provided in .env file.
x-base-env: &base-env
REDIS_URL: redis://valkey:6379/0
CELERY_BROKER_URL: redis://valkey:6379/0
CELERY_RESULT_BACKEND: redis://valkey:6379/0
DB_DRIVER: sqlite
# POSTGRES_HOST: postgres
x-celery-common: &celery-common
image: swalabtech/journiv-app:${APP_VERSION:-latest}
env_file: .env
volumes:
- /home/soenke/docker-data/journiv/app_data:/data
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
networks:
- backend
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
deploy:
resources:
limits:
cpus: "1.0"
memory: 1g
reservations:
memory: 256m
x-app-common: &app-common
image: swalabtech/journiv-app:${APP_VERSION:-latest}
env_file: .env
volumes:
- /home/soenke/docker-data/journiv/app_data:/data
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
networks:
- backend
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
x-celery-healthcheck: &celery-healthcheck
interval: 30s
timeout: 10s
retries: 5
start_period: 40s
services:
postgres:
image: postgres:18.1
container_name: journiv-postgres-db
environment:
- POSTGRES_USER=${POSTGRES_USER:-journiv}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD} # must provide a password in .env file
- POSTGRES_DB=${POSTGRES_DB:-journiv_prod}
volumes:
- /home/soenke/docker-data/journiv/postgres_data:/var/lib/postgresql
networks:
- backend
restart: unless-stopped
deploy:
resources:
limits:
cpus: "1.0"
memory: 1g
reservations:
memory: 256m
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "5"
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER:-journiv} -d ${POSTGRES_DB:-journiv_prod}",
]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
valkey:
# Journiv uses Valkey which is similar to Redis for cache.
image: valkey/valkey:9.0-alpine
container_name: journiv-valkey-cache
restart: unless-stopped
volumes:
- /home/soenke/docker-data/journiv/valkey_data:/data
networks:
- backend
healthcheck:
test: ["CMD", "valkey-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
celery-worker:
<<: *celery-common
container_name: journiv-celery-worker
command: celery -A app.core.celery_app worker --loglevel=info
environment:
<<: *base-env
SERVICE_ROLE: celery-worker
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
<<: *celery-healthcheck
celery-beat:
<<: *celery-common
container_name: journiv-celery-beat
command: celery -A app.core.celery_app beat --loglevel=info --scheduler redbeat.RedBeatScheduler --pidfile=/tmp/celerybeat.pid
environment:
<<: *base-env
SERVICE_ROLE: celery-beat
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
REDBEAT_REDIS_URL: redis://valkey:6379/2
healthcheck:
<<: *celery-healthcheck
app:
<<: *app-common
container_name: journiv-postgres-app
ports:
- "${APP_PORT:-8000}:8000"
environment:
<<: *base-env
SERVICE_ROLE: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ENVIRONMENT: production
RATE_LIMIT_STORAGE_URI: redis://valkey:6379/1
networks:
- backend
- frontend
healthcheck:
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: "2.0"
memory: 2g
reservations:
memory: 512m
#volumes:
# app_data:
# postgres_data:
# valkey_data:
networks:
backend:
driver: bridge
frontend:
driver: bridge

View File

@@ -3,6 +3,7 @@ for dir in *; do
if [[ "$dir" != "caddy" ]]; then if [[ "$dir" != "caddy" ]]; then
if [[ "$dir" != "pihole" ]]; then if [[ "$dir" != "pihole" ]]; then
( cd "$dir" && docker compose pull && docker compose down && docker compose up -d ) ( cd "$dir" && docker compose pull && docker compose down && docker compose up -d )
sleep 2s
fi fi
fi fi
fi fi