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>
248 lines
10 KiB
YAML
Executable File
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) |