librelad 875a60f90f LibrePortal v0.1.0 — initial release
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.

Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-21 20:37:54 +01:00

248 lines
10 KiB
YAML
Executable File

# ╔══════════════════════════════════════════════════════════════╗
# ║ LibrePortal - Comprehensive Test Template ║
# ║ Tests All Tagging System Features ║
# ╚══════════════════════════════════════════════════════════════╝
#
# ⚠️ AUTOMATICALLY GENERATED - DO NOT EDIT MANUALLY ⚠️
# All configurations are managed by LibrePortal tagging system
#
# 🏷️ TAGGING SYSTEM EXPLANATIONS:
# =====================================
#
# 📋 SERVICE TAGS:
#
# - SERVICE_TAG_N: Identifies services for IP allocation
# - Format: #LIBREPORTAL|SERVICE_TAG_N|service_name
# - Services with IP_DATA_N tags get IP addresses allocated
# - Services without IP_DATA_N are skipped for IP allocation
#
# 🔌 PORT SYSTEM:
#
# - PORT_DATA_N: Port number placeholder (gets replaced with allocated port)
# - PORT_TAG_N: Port tracking tag (gets updated with same port number)
# - Used in: ports section, Traefik config, UFW labels
# - Global replacement: All PORT_DATA_N instances get same port
#
# 🔐 PASSWORD SYSTEM:
#
# - PASSWORD_DATA_N: Password placeholder (gets replaced with generated password)
# - PASSWORD_TAG_N: Password tracking tag (gets updated with same password)
# - Global replacement: All PASSWORD_DATA_N instances get same password
# - Shared passwords: Same PASSWORD_DATA_N used across multiple services
#
# 🌐 IP SYSTEM:
#
# - IP_DATA_N: IP address placeholder (gets replaced with allocated IP)
# - IP_TAG_N: IP tracking tag (gets updated with same IP address)
# - Only services with IP_DATA_N get IP addresses allocated
# - Database tracking: Service-to-IP mappings stored persistently
#
# 📋 STANDARD TAGS:
#
# - TIMEZONE_DATA/TIMEZONE_TAG: Timezone configuration
# - EMAIL_DATA/EMAIL_TAG: Email address configuration
# - CATEGORY_DATA/CATEGORY_TAG: App category for LibrePortal
# - TITLE_DATA/TITLE_TAG: App title for LibrePortal
# - DOMAINSUBNAME_DATA/DOMAINSUBNAME_TAG: Domain for Traefik routing
# - DOMAINNAME_DATA/DOMAINNAME_TAG: Full domain name
# - DOMAINPREFIX_DATA/DOMAINPREFIX_TAG: Domain prefix
# - PUBLICIP_DATA/PUBLICIP_TAG: Public IP address
# - SUBNET_DATA/SUBNET_TAG: Network subnet
# - GATEWAY_DATA/GATEWAY_TAG: Network gateway
# - DOCKERNETWORK_DATA/DOCKERNETWORK_TAG: Docker network name
# - MTU_DATA/MTU_TAG: Network MTU setting
#
# 🚦 TRAEFIK CONTROL:
#
# - TRAEFIK_ENABLE_DATA/TRAEFIK_ENABLE_TAG: Enable/disable Traefik
# - When false: All Traefik labels are ignored but remain valid
# - When true: Traefik processes all routing and SSL configuration
#
# ⚕️ HEALTHCHECK:
#
# - HEALTHCHECK_DATA/HEALTHCHECK_TAG: Enable/disable healthchecks
# - true: Healthcheck disabled, false: Healthcheck enabled
#
# 🔧 DOCKER INSTALLATION:
#
# - SOCKET_TAG/SOCKET_DATA: Docker socket path for rootless/rooted
# - UID_TAG/GID_TAG: User ID for rootless Docker installation
# - DOCKERINSTALLUSER_TAG: Docker installation user tracking
#
# 🌐 PORT BINDING:
#
# - PORT_BINDING tag: Controls 0.0.0.0 vs 127.0.0.1 binding
# - Private apps: 127.0.0.1 (localhost only)
# - Public apps: 0.0.0.0 (accessible externally)
#
# 🎯 EXAMPLES IN THIS TEMPLATE:
# ==========================
#
# 🔌 PORT USAGE:
#
# - PORT_DATA_1 used in 3 places: ports section, Traefik loadbalancer, UFW labels
# - All instances get replaced with same allocated port (e.g., 3123)
#
# 🔐 PASSWORD SHARING:
#
# - PASSWORD_DATA_1: Shared between webapp (ADMIN_PASSWORD) and worker (ADMIN_PASSWORD)
# - PASSWORD_DATA_2: Shared between webapp (DB_PASSWORD), database (POSTGRES_PASSWORD), worker (DB_PASSWORD)
# - PASSWORD_DATA_3: Shared between webapp (API_KEY) and redis (REDIS_PASSWORD)
#
# 🌐 IP ALLOCATION:
#
# - SERVICE_TAG_1 (webapp) → IP_DATA_1 → Gets IP allocated
# - SERVICE_TAG_2 (database) → IP_DATA_2 → Gets IP allocated
# - SERVICE_TAG_3 (redis) → IP_DATA_3 → Gets IP allocated
# - SERVICE_TAG_4 (worker) → No IP_DATA_N → No IP allocated (internal only)
#
# 🚦 TRAEFIK INTEGRATION:
#
# - TRAEFIK_ENABLE_DATA controls if webapp is accessible via domain
# - Domain routing uses DOMAINSUBNAME_DATA for SSL certificate
# - Load balancer uses PORT_DATA_1 for internal port mapping
networks:
vpn:
external: true
services:
# Main web application service
# SERVICE_TAG_1: This service needs IP allocation (has IP_DATA_1)
webapp: #LIBREPORTAL|SERVICE_TAG_1|webapp
container_name: test-webapp
image: nginx:alpine
ports:
# PORT_EXTERNAL_1: External port mapping (gets allocated port like 3123)
# Used in 3 places: here, Traefik loadbalancer, UFW labels
- "PORT_DATA_1:3000" #LIBREPORTAL|PORT_TAG_1|PORT_DATA_1
volumes:
- ./data:/app/data
- ./config:/app/config:ro
env_file:
- .env
environment:
# Standard LibrePortal configuration tags
TZ: TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
EMAIL: EMAIL_DATA #LIBREPORTAL|EMAIL_TAG|EMAIL_DATA
# Password placeholders for testing
# PASSWORD_DATA_1: Shared with worker service (same password everywhere)
ADMIN_PASSWORD: PASSWORD_DATA_1 #LIBREPORTAL|PASSWORD_TAG_1|PASSWORD_DATA_1
# PASSWORD_DATA_2: Shared with database and worker services
DB_PASSWORD: PASSWORD_DATA_2 #LIBREPORTAL|PASSWORD_TAG_2|PASSWORD_DATA_2
# PASSWORD_DATA_3: Shared with redis service
API_KEY: PASSWORD_DATA_3 #LIBREPORTAL|PASSWORD_TAG_3|PASSWORD_DATA_3
# Application configuration
APP_NAME: "Test Application"
DEBUG: "true"
LOG_LEVEL: "info"
labels:
# LibrePortal application metadata
libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA
libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA
# UFW integration uses same port as external mapping
libreportal.ufw-ports: "UFW_PORT_DATA_1" #LIBREPORTAL|UFW_PORTS_TAG|UFW_PORT_DATA_1
libreportal.description: "Comprehensive test template for LibrePortal tagging system"
# Traefik reverse proxy configuration
# TRAEFIK_ENABLE_DATA: Controls if this app is accessible via domain
traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA
traefik.http.routers.webapp.entrypoints: web,websecure
# DOMAINSUBNAME_DATA: Domain name for SSL certificate and routing
traefik.http.routers.webapp.rule: Host(`DOMAINSUBNAME_DATA`) #LIBREPORTAL|DOMAINSUBNAME_TAG|DOMAINSUBNAME_DATA
traefik.http.routers.webapp.tls: true
traefik.http.routers.webapp.tls.certresolver: production
# PORT_DATA_1: Internal port for Traefik load balancer (same as external)
traefik.http.services.webapp.loadbalancer.server.port: 3000
traefik.http.routers.webapp.middlewares:
# DOCKERNETWORK_DATA: Docker network for Traefik communication
traefik.docker.network: DOCKERNETWORK_DATA #LIBREPORTAL|DOCKERNETWORK_TAG|DOCKERNETWORK_DATA
healthcheck:
# HEALTHCHECK_DATA: Enable/disable healthcheck (true=disabled, false=enabled)
disable: HEALTHCHECK_DATA #LIBREPORTAL|HEALTHCHECK_TAG|HEALTHCHECK_DATA
networks:
vpn:
# IP_DATA_1: This service gets IP address allocated
ipv4_address: IP_DATA_1 #LIBREPORTAL|IP_TAG_1|IP_DATA_1
# Database service (no external ports, only internal communication)
# SERVICE_TAG_2: This service needs IP allocation (has IP_DATA_2)
database: #LIBREPORTAL|SERVICE_TAG_2|database
container_name: test-database
image: postgres:13
ports:
# No external port mapping - internal only communication
volumes:
- ./db_data:/var/lib/postgresql/data
environment:
# Database configuration
POSTGRES_DB: testdb
POSTGRES_USER: admin
# PASSWORD_DATA_2: Same password as webapp DB_PASSWORD and worker DB_PASSWORD
POSTGRES_PASSWORD: PASSWORD_DATA_2 #LIBREPORTAL|PASSWORD_TAG_2|PASSWORD_DATA_2
# TIMEZONE_DATA: Same timezone as all other services
TZ: TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
labels:
libreportal.category: "database"
libreportal.description: "PostgreSQL database service"
libreportal.internal: "true"
healthcheck:
disable: false
networks:
vpn:
# IP_DATA_2: This service gets IP address allocated
ipv4_address: IP_DATA_2 #LIBREPORTAL|IP_TAG_2|IP_DATA_2
# Redis cache service (no external ports, internal only)
# SERVICE_TAG_3: This service needs IP allocation (has IP_DATA_3)
redis: #LIBREPORTAL|SERVICE_TAG_3|redis
container_name: test-redis
image: redis:alpine
ports:
# No external port mapping - internal only communication
volumes:
- ./redis_data:/data
environment:
# Redis configuration
# PASSWORD_DATA_3: Same password as webapp API_KEY
REDIS_PASSWORD: PASSWORD_DATA_3 #LIBREPORTAL|PASSWORD_TAG_3|PASSWORD_DATA_3
# TIMEZONE_DATA: Same timezone as all other services
TZ: TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
# Redis uses environment variable for password
command: redis-server --requirepass $REDIS_PASSWORD
labels:
libreportal.category: "cache"
libreportal.description: "Redis cache service"
libreportal.internal: "true"
healthcheck:
disable: false
networks:
vpn:
# IP_DATA_3: This service gets IP address allocated
ipv4_address: IP_DATA_3 #LIBREPORTAL|IP_TAG_3|IP_DATA_3
# Background worker service (no IP needed, internal processing only)
# SERVICE_TAG_4: This service does NOT need IP allocation (no IP_DATA_N)
worker: #LIBREPORTAL|SERVICE_TAG_4|worker
container_name: test-worker
image: python:alpine
volumes:
- ./worker:/app
environment:
# Worker configuration with shared passwords
# PASSWORD_DATA_1: Same password as webapp ADMIN_PASSWORD
ADMIN_PASSWORD: PASSWORD_DATA_1 #LIBREPORTAL|PASSWORD_TAG_1|PASSWORD_DATA_1
# PASSWORD_DATA_2: Same password as webapp DB_PASSWORD and database POSTGRES_PASSWORD
DB_PASSWORD: PASSWORD_DATA_2 #LIBREPORTAL|PASSWORD_TAG_2|PASSWORD_DATA_2
# TIMEZONE_DATA: Same timezone as all other services
TZ: TIMEZONE_DATA #LIBREPORTAL|TIMEZONE_TAG|TIMEZONE_DATA
command: python /app/worker.py
labels:
libreportal.category: "worker"
libreportal.description: "Background worker service"
libreportal.internal: "true"
networks:
vpn:
# No IP allocation for worker service (internal only, no IP_DATA_N)