runner

Ansible role that deployes services on my runner machine

16.3 KBYML
main.yml
16.3 KB440 lines • yaml
1---
2# Runner Services Role Defaults
3# Multi-service container deployment with NFS integration
4
5# ==============================================================================
6# GENERAL SETTINGS
7# ==============================================================================
8runner_enabled: true
9# Legacy variables - no longer used with consolidated structure
10# runner_docker_dir: "/docker/runner"  # Now each service uses /docker/[service]
11# runner_data_dir: "/docker/runner-data"  # Now consolidated into each service directory
12runner_nfs_mount_dir: "/mnt/docker"
13runner_user: "{{ ansible_user }}"
14runner_group: "users"
15runner_uid: 1000
16runner_gid: 1000
17
18# Timezone configuration
19runner_timezone: "Europe/Amsterdam"
20
21# Docker network for runner services
22runner_docker_network: "runner-network"
23runner_network_subnet: "172.20.0.0/16"
24
25# NFS Configuration
26runner_nfs_enabled: true
27runner_nas_host: "{{ vault_storage.nas_host | default('storage.home') }}"
28runner_nfs_options: "nfsvers=4.1,proto=tcp,hard,timeo=600,retrans=2,rsize=16777216,wsize=16777216,nconnect=8,noatime,_netdev"
29
30# ==============================================================================
31# NFS MOUNT CONFIGURATION
32# ==============================================================================
33runner_nfs_mounts:
34  - name: "frigate"
35    local_path: "{{ runner_nfs_mount_dir }}/frigate"
36    nfs_path: "/mnt/rstorage/cctv-data"
37    host: "{{ runner_nas_host }}"
38    options: "{{ runner_nfs_options }}"
39    
40  - name: "immich" 
41    local_path: "{{ runner_nfs_mount_dir }}/immich"
42    nfs_path: "/mnt/rstorage/media/pictures"
43    host: "{{ runner_nas_host }}"
44    options: "{{ runner_nfs_options }}"
45    
46  - name: "forgejo"
47    local_path: "{{ runner_nfs_mount_dir }}/forgejo"
48    nfs_path: "/mnt/rstorage/code-repo"
49    host: "{{ runner_nas_host }}"
50    options: "{{ runner_nfs_options }}"
51    
52  - name: "harbor"
53    local_path: "{{ runner_nfs_mount_dir }}/harbor"
54    nfs_path: "/mnt/rstorage/registry-data"  
55    host: "{{ runner_nas_host }}"
56    options: "{{ runner_nfs_options }}"
57
58  - name: "cvat"
59    local_path: "{{ runner_nfs_mount_dir }}/cvat"
60    nfs_path: "/mnt/rstorage/cvat-datasets"  
61    host: "{{ runner_nas_host }}"
62    options: "{{ runner_nfs_options }}"
63
64# ==============================================================================
65# SERVICE CONFIGURATIONS
66# ==============================================================================
67
68# LLM Stack - Unified Local AI Infrastructure
69llm_stack_enabled: true
70llm_stack_config_dir: "/docker/llm-stack"
71
72# Unified LLM Stack Configuration
73llm_stack_ollama_port: 9000
74llm_stack_openwebui_port: 9001
75llm_stack_litellm_port: 9002
76
77# Ollama - Local LLM Server
78llm_stack_ollama_data_dir: "{{ llm_stack_config_dir }}/ollama/data"
79# GPU configuration uses global gpu_enabled parameter
80llm_stack_ollama_default_model: "tinyllama"
81llm_stack_ollama_log_level: "info"
82
83# OpenWebUI - Web Interface for Ollama
84llm_stack_openwebui_data_dir: "{{ llm_stack_config_dir }}/openwebui/data"
85llm_stack_openwebui_name: "Local AI Assistant"
86llm_stack_openwebui_description: "Self-hosted AI chat interface"
87llm_stack_openwebui_author: "Home Assistant"
88llm_stack_openwebui_default_models: "tinyllama"
89llm_stack_openwebui_log_level: "info"
90llm_stack_openwebui_tavily_api_key: "{{ vault_storage.tavily_api_key | default('') }}"
91
92# LiteLLM - Unified LLM Proxy
93llm_stack_litellm_data_dir: "{{ llm_stack_config_dir }}/litellm/data"
94llm_stack_litellm_model_list: "tinyllama"
95llm_stack_litellm_completion_model: "ollama/tinyllama"
96llm_stack_litellm_streaming_enabled: true
97llm_stack_litellm_log_level: "info"
98
99# Frigate - AI NVR System
100frigate_enabled: true
101frigate_port: 5000
102frigate_rtmp_port: 1935
103frigate_rtsp_port: 8554
104frigate_go2rtc_port: 1984
105frigate_config_dir: "/docker/frigate"
106frigate_data_dir: "{{ runner_nfs_mount_dir }}/frigate"
107frigate_mqtt_enabled: true
108frigate_mqtt_host: "{{ vault_runner.frigate_mqtt_host | default('192.168.34.94') }}"
109frigate_mqtt_port: "{{ vault_runner.frigate_mqtt_port | default(1883) }}"
110frigate_hardware_acceleration: "vaapi"  # vaapi, nvdec, nvenc, qsv, or none
111
112# Frigate cameras configuration (from vault)
113frigate_cameras:
114  - name: "dining-room"
115    host: "{{ vault_runner.dining_room_camera_host | default('') }}"
116    username: "{{ vault_runner.dining_room_camera_user | default('') }}"
117    password: "{{ vault_runner.dining_room_camera_pass | default('') }}"
118    path: "/live0"
119    enabled: true
120    
121  - name: "living-room"
122    host: "{{ vault_runner.living_room_camera_host | default('') }}"
123    username: "{{ vault_runner.living_room_camera_user | default('') }}"
124    password: "{{ vault_runner.living_room_camera_pass | default('') }}"
125    path: "/live0"
126    enabled: true
127    
128  - name: "bed-room"
129    host: "{{ vault_runner.bed_room_camera_host | default('') }}"
130    username: "{{ vault_runner.bed_room_camera_user | default('') }}"
131    password: "{{ vault_runner.bed_room_camera_pass | default('') }}"
132    path: "/live0"
133    enabled: true
134    
135  - name: "alina-office"
136    host: "{{ vault_runner.alina_office_camera_host | default('') }}"
137    username: "{{ vault_runner.alina_office_camera_user | default('') }}"
138    password: "{{ vault_runner.alina_office_camera_pass | default('') }}"
139    path: "/live0"
140    enabled: true
141    
142  - name: "tapo-cam"
143    host: "{{ vault_runner.tapocam_host | default('') }}"
144    username: "{{ vault_runner.tapocam_user | default('') }}"
145    password: "{{ vault_runner.tapocam_pass | default('') }}"
146    path: "/stream1"
147    port: 554
148    enabled: true
149
150# Immich - Photo Management
151immich_enabled: true
152immich_server_port: 2283
153immich_ml_port: 3003
154immich_config_dir: "/docker/immich"
155immich_data_dir: "/docker/immich"
156immich_upload_dir: "{{ runner_nfs_mount_dir }}/immich"
157immich_db_name: "{{ vault_runner.postgres_db | default('') }}"
158immich_db_user: "{{ vault_runner.postgres_user | default('') }}"
159immich_redis_enabled: true
160immich_ml_enabled: true
161immich_facial_recognition: true
162immich_hardware_acceleration: "none"  # none, vaapi, nvdec, nvenc, or qsv
163
164# Forgejo - Git Server  
165forgejo_enabled: true
166forgejo_http_port: 3010
167forgejo_ssh_port: 2222
168forgejo_config_dir: "/docker/forgejo"
169forgejo_data_dir: "{{ runner_nfs_mount_dir }}/forgejo"
170forgejo_db_type: "sqlite3"
171forgejo_app_name: "Forgejo Git Service"
172forgejo_domain: "forgejo.home"
173forgejo_ssh_domain: "{{ ansible_default_ipv4.address }}"
174
175# Forgejo Runner Configuration
176forgejo_runner_enabled: true
177forgejo_runner_token: "AWPjaLooCGjNn6aOuDj6pFrMsp9vE7XLCW4PFIeF"
178forgejo_runner_name: "default-runner"
179forgejo_runner_capacity: 2
180forgejo_runner_loglevel: info
181forgejo_runner_base_image: ubuntu:22.04
182forgejo_runner_user: runner
183forgejo_runner_uid: 1000
184forgejo_runner_version: 9.1.1
185
186# Stirling-PDF - PDF Processing
187stirling_pdf_enabled: true
188stirling_pdf_port: 8080
189stirling_pdf_config_dir: "/docker/stirling-pdf"
190stirling_pdf_data_dir: "/docker/stirling-pdf"
191
192# Tandoor - Recipe Manager
193tandoor_enabled: true
194tandoor_port: 8010
195tandoor_config_dir: "/docker/tandoor"
196tandoor_data_dir: "/docker/tandoor"
197tandoor_media_dir: "{{ tandoor_data_dir }}/media"
198tandoor_static_dir: "{{ tandoor_data_dir }}/static"
199tandoor_db_engine: "django.db.backends.postgresql"
200
201# Ghost CMS - Headless CMS
202ghost_enabled: true
203ghost_port: 2368
204ghost_config_dir: "/docker/ghost"
205ghost_data_dir: "/docker/ghost"
206ghost_content_dir: "{{ ghost_data_dir }}/content"
207ghost_db_client: "mysql"
208ghost_db_host: "ghost-mysql"
209ghost_db_name: "ghost"
210ghost_db_user: "ghost"
211ghost_url: "http://ghost.home"
212
213cvat_config_dir: "/docker/cvat"
214# CVAT - Data labeling
215cvat_enabled: true
216
217cvat_repo_url: "https://github.com/cvat-ai/cvat.git"
218cvat_repo_version: "{{ cvat_image_tag }}"
219
220cvat_admin_username: admin
221cvat_admin_password: "{{ vault_runner.cvat_admin_password | default('change-me') }}"
222cvat_admin_email: "{{ vault_runner.cvat_admin_email | default('change-me') }}"
223
224# Networking / access
225cvat_domain: "cvat.home"        # used by Traefik routing in CVAT compose
226cvat_http_port: 8990             # Traefik "web" entrypoint in the default compose
227cvat_https_enabled: false        # add CVAT's https overlay when true
228
229cvat_share_dir: >-
230  {{ (runner_nfs_mounts
231      | selectattr('name','equalto','cvat')
232      | map(attribute='local_path')
233      | first)
234     | default(runner_nfs_mount_dir ~ '/cvat', true) }}
235
236# Versioning / images
237cvat_image_tag: "v2.44.3"        # pulled via CVAT_VERSION; align with the git tag you run
238
239# Optional: serverless auto-annotation overlay (Nuclio/SAM/YOLO assist in CVAT)
240cvat_serverless_enabled: false
241
242# Optional: use an external Postgres instead of the bundled one
243cvat_external_db_enabled: false
244cvat_db_host: "postgres.internal"
245cvat_db_port: 5432
246cvat_db_name: "cvat"
247cvat_db_user: "cvat_user"
248cvat_db_password: "{{ vault_runner.cvat_db_password | default('change-me') }}"
249
250# Optional: expose Traefik dashboard (binds host port below)
251cvat_traefik_dashboard_enabled: false
252cvat_dashboard_port: 8899
253
254# Optional: GPU reservation for CVAT server container (you must have host GPU runtime ready)
255cvat_gpu_enabled: false
256cvat_gpu_driver: "nvidia"
257cvat_gpu_count: "all"            # or a number like "1"
258
259# ==============================================================================
260# DATABASE CONFIGURATIONS  
261# ==============================================================================
262
263# PostgreSQL (Immich)
264postgres_enabled: "{{ immich_enabled }}"
265postgres_config_dir: "/docker/immich/postgres"
266postgres_db: "{{ vault_runner.postgres_db | default('') }}"
267postgres_user: "{{ vault_runner.postgres_user | default('') }}"
268postgres_version: "14"
269
270# Redis (Immich)
271redis_enabled: "{{ immich_redis_enabled }}"
272redis_config_dir: "/docker/immich/redis"
273redis_port: 6379
274
275# MySQL (Ghost CMS)
276mysql_enabled: "{{ ghost_enabled }}"
277mysql_config_dir: "/docker/ghost/mysql"
278mysql_db: "{{ ghost_db_name }}"
279mysql_user: "{{ ghost_db_user }}"
280mysql_version: "8.0"
281
282# ==============================================================================
283# SECURITY SETTINGS (FROM VAULT)
284# ==============================================================================
285
286# Database passwords
287postgres_password: "{{ vault_runner.postgres_password | default('') }}"
288mysql_password: "{{ vault_runner.mysql_password | default('') }}"
289mysql_root_password: "{{ vault_runner.mysql_root_password | default('') }}"
290
291# Service secrets
292immich_jwt_secret: "{{ vault_runner.immich_jwt_secret | default('') }}"
293ghost_database_password: "{{ vault_runner.ghost_database_password | default('') }}"
294tandoor_secret_key: "{{ vault_runner.tandoor_secret_key | default('') }}"
295
296# MQTT credentials (from vault) - centralized definitions
297frigate_mqtt_username: "{{ vault_runner.frigate_mqtt_username | default('') }}"
298frigate_mqtt_password: "{{ vault_runner.frigate_mqtt_password | default('') }}"
299
300# ==============================================================================
301# DIRECTORY STRUCTURE
302# ==============================================================================
303
304# Local configuration directories
305runner_config_directories:
306  - "{{ llm_stack_config_dir }}"
307  - "{{ llm_stack_ollama_data_dir }}"
308  - "{{ llm_stack_openwebui_data_dir }}"
309  - "{{ llm_stack_litellm_data_dir }}"
310  - "{{ frigate_config_dir }}"
311  - "{{ immich_config_dir }}"
312  - "{{ immich_config_dir }}/postgres"
313  - "{{ immich_config_dir }}/redis"
314  - "{{ immich_config_dir }}/library"
315  - "{{ immich_config_dir }}/cache"
316  - "{{ immich_config_dir }}/model-cache"
317  - "{{ immich_config_dir }}/postgres-init"
318  - "{{ forgejo_config_dir }}"
319  - "{{ forgejo_config_dir }}/forgejo-runner-data"
320  - "{{ stirling_pdf_config_dir }}"
321  - "{{ tandoor_config_dir }}"
322  - "{{ tandoor_data_dir }}/db"
323  - "{{ tandoor_data_dir }}/media"
324  - "{{ tandoor_data_dir }}/static"
325  - "{{ ghost_config_dir }}/config"
326  - "{{ ghost_config_dir }}/content"
327  - "{{ ghost_config_dir }}/mysql"
328
329# NFS mount directories
330runner_nfs_directories:
331  - "{{ runner_nfs_mount_dir }}"
332  - "{{ runner_nfs_mount_dir }}/frigate"
333  - "{{ runner_nfs_mount_dir }}/immich"
334  - "{{ runner_nfs_mount_dir }}/forgejo"
335  - "{{ runner_nfs_mount_dir }}/harbor"
336  - "{{ runner_nfs_mount_dir }}/cvat"
337
338# ==============================================================================
339# PERFORMANCE SETTINGS
340# ==============================================================================
341
342# Network performance tuning for NFS
343runner_performance_tuning_enabled: true
344runner_sysctl_settings:
345  # Extreme performance network buffers for Ryzen 7 + 32GB RAM
346  net.core.rmem_max: 268435456          # 256MB socket receive buffer  
347  net.core.wmem_max: 268435456          # 256MB socket send buffer
348  net.core.rmem_default: 33554432       # 32MB default receive buffer
349  net.core.wmem_default: 33554432       # 32MB default send buffer
350  net.ipv4.tcp_rmem: "4096 131072 268435456"   # TCP receive: 4KB min, 128KB default, 256MB max
351  net.ipv4.tcp_wmem: "4096 131072 268435456"   # TCP send: 4KB min, 128KB default, 256MB max
352  net.core.netdev_max_backlog: 30000    # Handle high connection burst (32 connections)
353  net.ipv4.tcp_congestion_control: "bbr" # BBR congestion control
354  net.ipv4.tcp_window_scaling: 1        # Enable TCP window scaling
355  net.ipv4.tcp_timestamps: 1            # Enable TCP timestamps for RTT calculation
356  net.ipv4.tcp_sack: 1                  # Enable selective acknowledgments
357  # NFS client cache tuning for 32GB RAM
358  vm.dirty_background_ratio: 3          # Start writeback at 3% (more aggressive)
359  vm.dirty_ratio: 8                     # Force writeback at 8% (more aggressive)
360  vm.vfs_cache_pressure: 25             # Keep even more file cache (25% vs 50%)
361  vm.min_free_kbytes: 131072            # Keep 128MB free for network buffers
362
363# Harbor Configuration (external deployment)
364harbor_enabled: true
365harbor_config_dir: "/docker/harbor"
366harbor_version: "2.13.0"
367harbor_hostname: "registry.local"
368harbor_http_port: 8080
369harbor_registry_port: 5000
370harbor_admin_password: "Harbor12345"
371harbor_checksum: "b4a3b0e7d8e3a8b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1"
372
373# ==============================================================================
374# CONTAINER IMAGES
375# ==============================================================================
376
377# Centralized container image mapping for version control
378# Note: Frigate and Immich use conditional images based on hardware acceleration
379container_images:
380
381  # LLM Stack services
382  ollama: "ollama/ollama:latest"
383  openwebui: "ghcr.io/open-webui/open-webui:main"
384  litellm: "ghcr.io/berriai/litellm:main-latest"
385  
386  # Core services  
387  forgejo: "codeberg.org/forgejo/forgejo:12"
388  forgejo_runner: "data.forgejo.org/forgejo/runner:9.1.1"
389  
390  # Productivity services
391  stirling_pdf: "frooodle/s-pdf:latest"
392  tandoor: "vabene1111/recipes:latest"
393  ghost: "ghost:5-alpine"
394  
395  # Database services
396  postgres: "postgres:14-alpine"
397  mysql: "mysql:8.0"
398  redis: "redis:7-alpine"
399
400# Docker resource limits
401default_memory_limit: "1g"
402default_cpu_limit: "1"
403
404# Health check configuration
405health_check_interval: "30s"
406health_check_timeout: "30s"
407health_check_retries: 5
408health_check_start_period: "60s"
409
410# ==============================================================================
411# SERVICE HEALTH ENDPOINTS
412# ==============================================================================
413service_endpoints:
414  ollama: "http://localhost:{{ llm_stack_ollama_port }}/api/tags"
415  openwebui: "http://localhost:{{ llm_stack_openwebui_port }}/api/health"
416  litellm: "http://localhost:{{ llm_stack_litellm_port }}/"
417  frigate: "http://localhost:{{ frigate_port }}/api/config"
418  immich: "http://localhost:{{ immich_server_port }}/api/server-info/ping"
419  forgejo: "http://localhost:{{ forgejo_http_port }}/api/v1/version"
420  stirling_pdf: "http://localhost:{{ stirling_pdf_port }}/api/v1/info/status"
421  tandoor: "http://localhost:{{ tandoor_port }}/accounts/login/"
422  ghost: "http://localhost:{{ ghost_port }}/ghost/api/admin/site/"
423
424# ==============================================================================
425# LOGGING CONFIGURATION
426# ==============================================================================
427logging_driver: "json-file"
428logging_max_size: "10m"
429logging_max_file: "3"
430
431# Service-specific logging levels (unified LLM stack uses llm_stack_* variables)
432# ollama_log_level: "info"  # Now uses llm_stack_ollama_log_level
433# openwebui_log_level: "info"  # Now uses llm_stack_openwebui_log_level
434# litellm_log_level: "info"  # Now uses llm_stack_litellm_log_level
435frigate_log_level: "info"
436immich_log_level: "log"
437forgejo_log_level: "Info"
438ghost_logging: "info"
439
440