Compare commits

...

6 Commits

Author SHA1 Message Date
8710ffc70d feat: update documentation and infrastructure configuration
- Update service count from 22+ to 25 across documentation
- Add vault.yml to gitignore for security
- Add notifications configuration for AppriseAPI integration
- Add jq package to common role dependencies
- Add hairpin networking fix for AppriseAPI chat subdomain access
- Remove diun service references from monitoring category
- Update project completion status in todo.md

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-08 21:10:30 -06:00
a98fae0b92 feat: update container versions for Baikal, Karakeep, and Postiz
- Update Baikal to v0.10.1 (PostgreSQL support, PHP 8.4 compatibility)
- Update Karakeep to v0.25.0 (Safari extension, PDF screenshots, bulk tag deletion)
- Update Postiz to v1.48.4 (AI image generation, drag-drop uploads, enhanced platform support)

All services tested and running successfully with no errors.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-08 21:04:24 -06:00
d05bac8651 fix: add NEXT_API_DEBUG_MODE environment variable to MMDL
Resolves calendar creation issue where clicking save would fail with
'Cannot read properties of undefined (Reading 'toUpperCase')' error.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-08 20:37:08 -06:00
c500790ea3 feat: update Glance to v0.8.3
- Updated image version from latest to v0.8.3
- Deployed and verified successful upgrade
- New features available: theme picker, authentication, to-do widget

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-07 12:49:44 -06:00
2e4c096bbe feat: complete variable management implementation and update documentation
- Update remaining Docker Compose templates with centralized variables
- Fix service tag isolation to deploy individual services only
- Update all README files with variable management architecture
- Document variable hierarchy in DEPLOYMENT_LEARNINGS.md
- Add comprehensive variable usage patterns to CLAUDE.md
- Standardize domain references using {{ subdomains.* }} pattern
- Replace hardcoded network names with {{ docker.network_name }}
- Update hairpinning configuration to use variables

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-06 15:45:52 -06:00
12582b352c feat: implement comprehensive variable management system
- Create standardized group_vars directory structure
- Add domains.yml with centralized subdomain mappings
- Add infrastructure.yml with network, SMTP, and path config
- Reorganize vault.yml secrets by service with consistent naming
- Update 15+ Docker compose templates to use new variable structure
- Simplify playbook commands by removing --extra-vars requirement
- Replace hardcoded domains/IPs with template variables
- Standardize secret references across all services

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-06 15:14:47 -06:00
35 changed files with 319 additions and 198 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
.python-version .python-version
secrets.enc secrets.enc
vault_pass vault_pass
DEPLOYMENT_LEARNINGS.md DEPLOYMENT_LEARNINGS.md
group_vars/all/vault.yml

View File

@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Overview ## Overview
This is a personal infrastructure Ansible playbook that automates deployment and management of 22+ self-hosted Docker services across two domains (`thesatelliteoflove.com` and `nerder.land`). The setup uses Tailscale VPN for secure networking and Caddy for reverse proxy with automated HTTPS. This is a personal infrastructure Ansible playbook that automates deployment and management of 25 self-hosted Docker services across two domains (`thesatelliteoflove.com` and `nerder.land`). The setup uses Tailscale VPN for secure networking and Caddy for reverse proxy with automated HTTPS.
**Important**: Always review `DEPLOYMENT_LEARNINGS.md` when working on this repository for lessons learned and troubleshooting guidance. **Important**: Always review `DEPLOYMENT_LEARNINGS.md` when working on this repository for lessons learned and troubleshooting guidance.
@@ -27,9 +27,10 @@ ansible-playbook dns.yml -i hosts.yml
### Service Management ### Service Management
```bash ```bash
# Deploy specific services using tags # Deploy specific services using tags (now properly isolated)
ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass --extra-vars "@secrets.enc" ansible-playbook site.yml -i hosts.yml --tags caddy --vault-password-file vault_pass --extra-vars "@secrets.enc"
ansible-playbook site.yml -i hosts.yml --tags authentik,gitea --vault-password-file vault_pass --extra-vars "@secrets.enc" ansible-playbook site.yml -i hosts.yml --tags authentik --vault-password-file vault_pass --extra-vars "@secrets.enc"
ansible-playbook site.yml -i hosts.yml --tags mmdl --vault-password-file vault_pass --extra-vars "@secrets.enc"
ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass --extra-vars "@secrets.enc" # all docker services ansible-playbook site.yml -i hosts.yml --tags docker --vault-password-file vault_pass --extra-vars "@secrets.enc" # all docker services
# Deploy services by category (new organized structure) # Deploy services by category (new organized structure)
@@ -50,7 +51,7 @@ ansible-playbook site.yml -i hosts.yml --tags common,cron --vault-password-file
### Role Structure ### Role Structure
- **bootstrap**: Initial server hardening, user creation, Tailscale VPN setup - **bootstrap**: Initial server hardening, user creation, Tailscale VPN setup
- **common**: Basic system configuration, UFW firewall management - **common**: Basic system configuration, UFW firewall management
- **docker**: Comprehensive service deployment (22+ containerized applications, organized by category) - **docker**: Comprehensive service deployment (25 containerized applications, organized by category)
- **cron**: Scheduled task management (currently Warhammer RSS feed generation) - **cron**: Scheduled task management (currently Warhammer RSS feed generation)
### Docker Role Organization (Reorganized into Logical Categories) ### Docker Role Organization (Reorganized into Logical Categories)
@@ -61,7 +62,7 @@ The docker role is now organized into logical service groups under `roles/docker
- **development/**: Development and collaboration tools - **development/**: Development and collaboration tools
- Gitea, Code Server, Matrix (Conduit) - Gitea, Code Server, Matrix (Conduit)
- **media/**: Content creation and consumption - **media/**: Content creation and consumption
- Audiobookshelf, Calibre, Ghost blog, Pinchflat, Pinry, Karakeep, Manyfold - Audiobookshelf, Calibre, Ghost blog, Pinchflat, Pinry, Karakeep (formerly Hoarder), Manyfold
- **productivity/**: Personal organization and document management - **productivity/**: Personal organization and document management
- Paperless-NGX, MMDL, Baikal (CalDAV/CardDAV), Syncthing, Heyform, Dawarich, Pingvin - Paperless-NGX, MMDL, Baikal (CalDAV/CardDAV), Syncthing, Heyform, Dawarich, Pingvin
- **communication/**: Social media and external communication - **communication/**: Social media and external communication
@@ -69,10 +70,21 @@ The docker role is now organized into logical service groups under `roles/docker
- **monitoring/**: System monitoring and alerts - **monitoring/**: System monitoring and alerts
- Changedetection, Glance dashboard, AppriseAPI - Changedetection, Glance dashboard, AppriseAPI
### Variable Management
**Critical**: This infrastructure uses a centralized variable hierarchy in `group_vars/all/`:
- **domains.yml**: Domain and subdomain mappings (use `{{ subdomains.service }}`)
- **infrastructure.yml**: Network configuration, Docker settings (`{{ docker.network_name }}`, `{{ docker.hairpin_ip }}`)
- **vault.yml**: Encrypted secrets with `vault_` prefix
- **services.yml**: Service-specific configuration and feature flags
**Important**: All templates use variables instead of hardcoded values. Never hardcode domains, IPs, or secrets.
### Data Structure ### Data Structure
- All service data stored in `/opt/stacks/[service-name]/` on docker host - All service data stored in `/opt/stacks/[service-name]/` on docker host
- Docker Compose files generated from Jinja2 templates in `roles/docker/templates/` - Docker Compose files generated from Jinja2 templates in `roles/docker/templates/`
- Environment files templated for services requiring configuration - Environment files templated for services requiring configuration
- All configurations use centralized variables for consistency
## Key Implementation Details ## Key Implementation Details
@@ -104,14 +116,48 @@ Services inside Docker containers cannot reach external domains that resolve to
```yaml ```yaml
extra_hosts: extra_hosts:
- "auth.thesatelliteoflove.com:172.20.0.5" - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}"
- "cal.thesatelliteoflove.com:172.20.0.5" - "{{ subdomains.cal }}:{{ docker.hairpin_ip }}"
``` ```
Common domains requiring hairpinning fixes: Common domains requiring hairpinning fixes:
- `auth.thesatelliteoflove.com` (Authentik SSO) - `{{ subdomains.auth }}` (Authentik SSO)
- `cal.thesatelliteoflove.com` (Baikal CalDAV) - `{{ subdomains.cal }}` (Baikal CalDAV)
- Any service domain the container needs to communicate with - Any service domain the container needs to communicate with
**Note**: Use variables instead of hardcoded values for maintainability.
### Service-Specific Reference Configurations ### Service-Specific Reference Configurations
- **Dawarich**: Based on production compose file at https://github.com/Freika/dawarich/blob/master/docker/docker-compose.production.yml - **Dawarich**: Based on production compose file at https://github.com/Freika/dawarich/blob/master/docker/docker-compose.production.yml
## Service Memories
- pingvin is the service that responds on files.thesatelliteoflove.com
- karakeep (formerly called hoarder) is deployed with both 'hoarder' and 'karakeep' tags for backward compatibility
- whenever i ask you what containers need updates, run dockcheck and return a list of containers needing updates
- when i ask for the status container updates i want you to run dockcheck on the docker host https://github.com/mag37/dockcheck?ref=selfh.st
## Variable Management Implementation Notes
**Major Infrastructure Update**: Variable management system was implemented to replace all hardcoded values with centralized variables.
### Key Changes Made:
- Created comprehensive `group_vars/all/` structure
- Updated all Docker Compose templates to use variables
- Fixed service tag isolation (individual service tags now deploy only that service)
- Standardized domain and network configuration
- Organized secrets by service with consistent `vault_` prefix
### Service Tag Fix:
**Critical**: Service tags are now properly isolated. `--tags mmdl` deploys only MMDL (5 tasks), not the entire productivity category.
### Template Pattern:
All templates now follow this pattern:
```yaml
# Use variables, not hardcoded values
glance.url: "https://{{ subdomains.service }}/"
networks:
default:
external: true
name: "{{ docker.network_name }}"
extra_hosts:
- "{{ subdomains.auth }}:{{ docker.hairpin_ip }}"
```

View File

@@ -10,7 +10,7 @@ The playbook manages two main environments:
## Services Deployed ## Services Deployed
The Docker role deploys and manages 22+ self-hosted services organized into logical categories: The Docker role deploys and manages 25 self-hosted services organized into logical categories:
### Infrastructure ### Infrastructure
- **Caddy** (Reverse proxy with automatic HTTPS) - **Caddy** (Reverse proxy with automatic HTTPS)
@@ -28,7 +28,7 @@ The Docker role deploys and manages 22+ self-hosted services organized into logi
- **Ghost** (Blog platform) - **Ghost** (Blog platform)
- **Pinchflat** (Media downloader) - **Pinchflat** (Media downloader)
- **Pinry** (Pinterest-like board) - **Pinry** (Pinterest-like board)
- **Karakeep** (Bookmark manager) - **Hoarder** (Bookmark manager)
- **Manyfold** (3D model organizer) - **Manyfold** (3D model organizer)
### Productivity ### Productivity
@@ -88,7 +88,7 @@ Manages scheduled tasks and automation:
- Supports easy addition of new scheduled tasks - Supports easy addition of new scheduled tasks
### [Docker Role](roles/docker/README.md) ### [Docker Role](roles/docker/README.md)
The most comprehensive role, deploying 22+ containerized services organized into logical categories: The most comprehensive role, deploying 25 containerized services organized into logical categories:
- **Infrastructure**: Caddy reverse proxy, Authentik SSO, Dockge management - **Infrastructure**: Caddy reverse proxy, Authentik SSO, Dockge management
- **Development**: Gitea, Code Server, Matrix communication - **Development**: Gitea, Code Server, Matrix communication
- **Media**: Audiobookshelf, Calibre, Ghost blog, Pinchflat, and more - **Media**: Audiobookshelf, Calibre, Ghost blog, Pinchflat, and more

View File

@@ -3,11 +3,8 @@
become: true become: true
vars: vars:
created_username: phil created_username: phil
vars_prompt:
- name: tailscale_key
prompt: Enter the tailscale key
roles: roles:
- bootstrap - bootstrap
- role: artis3n.tailscale - role: artis3n.tailscale
vars: vars:
tailscale_authkey: "{{ tailscale_key }}" tailscale_authkey: "{{ vault_infrastructure.tailscale_key }}"

View File

@@ -0,0 +1,39 @@
# Domain Configuration
primary_domain: "thesatelliteoflove.com"
secondary_domain: "nerder.land"
# Subdomain mappings
subdomains:
auth: "auth.{{ primary_domain }}"
git: "git.{{ primary_domain }}"
cal: "cal.{{ primary_domain }}"
docs: "docs.{{ primary_domain }}"
phlog: "phlog.{{ primary_domain }}" # Ghost blog
bookmarks: "bookmarks.{{ primary_domain }}" # Hoarder/Karakeep
heyform: "forms.{{ secondary_domain }}" # Heyform on nerder.land
media: "media.{{ primary_domain }}"
audio: "audio.{{ primary_domain }}" # Audiobookshelf
books: "books.{{ primary_domain }}" # Calibre
models: "models.{{ primary_domain }}" # Manyfold
pinchflat: "pinchflat.{{ primary_domain }}"
pin: "pin.{{ primary_domain }}" # Pinry
paper: "paper.{{ primary_domain }}" # Paperless-NGX
tasks: "tasks.{{ primary_domain }}" # MMDL
syncthing: "syncthing.{{ primary_domain }}"
loclog: "loclog.{{ primary_domain }}" # Dawarich
files: "files.{{ primary_domain }}" # Pingvin file sharing
social: "social.{{ primary_domain }}" # GoToSocial
post: "post.{{ primary_domain }}" # Postiz
home: "home.{{ primary_domain }}" # Glance
watcher: "watcher.{{ primary_domain }}" # Changedetection
appriseapi: "appriseapi.{{ primary_domain }}"
dockge: "dockge.{{ primary_domain }}"
code: "code.{{ primary_domain }}" # Code Server
chat: "chat.{{ primary_domain }}" # Conduit Matrix
# Email domains for notifications
email_domains:
updates: "updates.{{ primary_domain }}"
auth_email: "auth@updates.{{ primary_domain }}"
git_email: "git@updates.{{ primary_domain }}"
cal_email: "cal@updates.{{ primary_domain }}"

View File

@@ -0,0 +1,26 @@
# Infrastructure Configuration
# Docker configuration
docker:
network_name: "lava"
stacks_path: "/opt/stacks"
hairpin_ip: "172.20.0.5"
# SMTP configuration
smtp:
host: "smtp.resend.com"
username: "resend"
from_domain: "{{ email_domains.updates }}"
# Network configuration
network:
netcup_ip: "152.53.36.98"
docker_host_ip: "100.70.169.99"
# Paths
paths:
stacks: "{{ docker.stacks_path }}"
# Notification services
notifications:
appriseapi_endpoint: "http://apprise:8000/notify/apprise"

View File

@@ -0,0 +1,25 @@
# Docker Services Configuration
# Service categories for organization
service_categories:
infrastructure: ["caddy", "authentik", "dockge"]
development: ["gitea", "codeserver", "conduit"]
media: ["audiobookshelf", "calibre", "ghost", "pinchflat", "pinry", "hoarder", "manyfold"]
productivity: ["paperlessngx", "baikal", "syncthing", "mmdl", "heyform", "dawarich", "pingvin"]
communication: ["gotosocial", "postiz"]
monitoring: ["glance", "changedetection", "appriseapi"]
# Common service configuration
services:
common:
restart_policy: "unless-stopped"
network: "{{ docker.network_name }}"
# Service-specific configurations
dawarich:
db_name: "dawarich"
db_user: "dawarich"
mmdl:
db_name: "mmdl"
db_user: "mmdl"

View File

@@ -1,6 +1,8 @@
- name: Install aptitude - name: Install common packages
apt: apt:
name: aptitude name:
- aptitude
- jq
state: latest state: latest
update_cache: true update_cache: true

View File

@@ -6,7 +6,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 22+ containe
## Architecture Overview ## Architecture Overview
### Network Configuration ### Network Configuration
- **External Network**: All services connect to shared `lava` network (172.20.0.0/24) - **External Network**: All services connect to shared Docker network (configurable)
- **Reverse Proxy**: Caddy handles all ingress traffic with automatic HTTPS - **Reverse Proxy**: Caddy handles all ingress traffic with automatic HTTPS
- **Service Discovery**: Container-to-container communication using service names - **Service Discovery**: Container-to-container communication using service names
- **Firewall Integration**: UFW-Docker script properly configures firewall rules - **Firewall Integration**: UFW-Docker script properly configures firewall rules
@@ -16,6 +16,7 @@ Deploys and manages a comprehensive self-hosted infrastructure with 22+ containe
- **Network Isolation**: Services restricted to appropriate network segments - **Network Isolation**: Services restricted to appropriate network segments
- **Container Hardening**: Non-root users, capability dropping, security options - **Container Hardening**: Non-root users, capability dropping, security options
- **Secret Management**: Ansible vault for sensitive configuration - **Secret Management**: Ansible vault for sensitive configuration
- **Variable Management**: Centralized variable hierarchy using group_vars structure
## Services Deployed (Organized by Category) ## Services Deployed (Organized by Category)
@@ -68,7 +69,9 @@ Each service follows a consistent pattern:
### Template System ### Template System
- **Compose Templates**: `.j2` files in `templates/` for dynamic configuration - **Compose Templates**: `.j2` files in `templates/` for dynamic configuration
- **Environment Templates**: Separate `.env.j2` files for services requiring environment variables - **Environment Templates**: Separate `.env.j2` files for services requiring environment variables
- **Variable Substitution**: Uses Ansible vault variables for secrets and configuration - **Variable Substitution**: Uses centralized variable hierarchy from group_vars structure
- **Domain Management**: Centralized domain and subdomain configuration
- **Network Configuration**: Standardized Docker network and IP address management
## Shell Environment Setup ## Shell Environment Setup
The role also configures the shell environment: The role also configures the shell environment:
@@ -161,11 +164,20 @@ ansible-playbook site.yml -i hosts.yml --tags mmdl
## Configuration ## Configuration
### Required Variables (in vault) ### Variable Structure
- Authentication credentials for various services The role uses a centralized variable hierarchy in `group_vars/all/`:
- **domains.yml**: Domain and subdomain mappings for all services
- **infrastructure.yml**: Network configuration, Docker settings, and system parameters
- **vault.yml**: Encrypted secrets including API keys, passwords, and OAuth credentials
- **services.yml**: Service-specific configuration and feature flags
### Required Variables (in vault.yml)
- Authentication credentials for various services (vault_*)
- API keys for external integrations - API keys for external integrations
- OAuth client secrets for SSO integration - OAuth client secrets for SSO integration
- Database passwords and connection strings - Database passwords and connection strings
- SMTP credentials for notifications
### Network Configuration ### Network Configuration
Services expect to be accessible via subdomains of configured domains: Services expect to be accessible via subdomains of configured domains:

View File

@@ -59,56 +59,24 @@
# Deploy services by category for better organization and dependency management # Deploy services by category for better organization and dependency management
- name: Deploy infrastructure services - name: Deploy infrastructure services
import_tasks: infrastructure/main.yml import_tasks: infrastructure/main.yml
tags: tags: infrastructure
- infrastructure
- caddy
- authentik
- dockge
- name: Deploy development services - name: Deploy development services
import_tasks: development/main.yml import_tasks: development/main.yml
tags: tags: development
- development
- gitea
- codeserver
- conduit
- name: Deploy media services - name: Deploy media services
import_tasks: media/main.yml import_tasks: media/main.yml
tags: tags: media
- media
- audiobookshelf
- calibre
- ghost-1
- pinchflat
- pinry
- hoarder
- karakeep
- manyfold
- name: Deploy productivity services - name: Deploy productivity services
import_tasks: productivity/main.yml import_tasks: productivity/main.yml
tags: tags: productivity
- productivity
- paperlessngx
- baikal
- syncthing
- mmdl
- heyform
- dawarich
- pingvin
- name: Deploy monitoring services - name: Deploy monitoring services
import_tasks: monitoring/main.yml import_tasks: monitoring/main.yml
tags: tags: monitoring
- monitoring
- glance
- changedetection
- appriseapi
- name: Deploy communication services - name: Deploy communication services
import_tasks: communication/main.yml import_tasks: communication/main.yml
tags: tags: communication
- communication
- gotosocial
- postiz

View File

@@ -2,7 +2,7 @@ services:
apprise: apprise:
container_name: apprise container_name: apprise
ports: ports:
- 100.70.169.99:8000:8000 - {{ network.docker_host_ip }}:8000:8000
environment: environment:
- APPRISE_STATEFUL_MODE=simple - APPRISE_STATEFUL_MODE=simple
- APPRISE_WORKER_COUNT=1 - APPRISE_WORKER_COUNT=1
@@ -11,10 +11,12 @@ services:
- plugin:/plugin - plugin:/plugin
- attach:/attach - attach:/attach
image: caronc/apprise:latest image: caronc/apprise:latest
extra_hosts:
- "{{ subdomains.chat }}:{{ docker.hairpin_ip }}"
labels: labels:
glance.name: Apprise glance.name: Apprise
glance.icon: si:imessage glance.icon: si:imessage
glance.url: https://auth.thesatelliteoflove.com/ glance.url: https://{{ subdomains.appriseapi }}/
glance.description: Apprise api server glance.description: Apprise api server
glance.id: apprise glance.id: apprise
@@ -25,4 +27,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -10,11 +10,11 @@ services:
- TZ=America/Denver - TZ=America/Denver
- DISABLE_SSRF_REQUEST_FILTER=1 - DISABLE_SSRF_REQUEST_FILTER=1
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:172.20.0.5'
labels: labels:
glance.name: Audiobookshelf glance.name: Audiobookshelf
glance.icon: si:audiobookshelf glance.icon: si:audiobookshelf
glance.url: https://audio.thesatelliteoflove.com/ glance.url: https://{{ subdomains.audio }}/
glance.description: Audio book server glance.description: Audio book server
volumes: volumes:
audiobooks: audiobooks:
@@ -28,4 +28,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,15 +1,15 @@
PG_PASS={{ authentik_pg_pass }} PG_PASS={{ vault_authentik.postgres_password }}
AUTHENTIK_SECRET_KEY={{ authentik_secret_key }} AUTHENTIK_SECRET_KEY={{ vault_authentik.secret_key }}
# SMTP Host Emails are sent to # SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST=smtp.resend.com AUTHENTIK_EMAIL__HOST={{ smtp.host }}
AUTHENTIK_EMAIL__PORT=25 AUTHENTIK_EMAIL__PORT=25
# Optionally authenticate (don't add quotation marks to your password) # Optionally authenticate (don't add quotation marks to your password)
AUTHENTIK_EMAIL__USERNAME=resend AUTHENTIK_EMAIL__USERNAME={{ smtp.username }}
AUTHENTIK_EMAIL__PASSWORD={{ resend_key }} AUTHENTIK_EMAIL__PASSWORD={{ vault_smtp.password }}
# Use StartTLS # Use StartTLS
AUTHENTIK_EMAIL__USE_TLS=true AUTHENTIK_EMAIL__USE_TLS=true
# Use SSL # Use SSL
AUTHENTIK_EMAIL__USE_SSL=false AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10 AUTHENTIK_EMAIL__TIMEOUT=10
# Email address authentik will send from, should have a correct @domain # Email address authentik will send from, should have a correct @domain
AUTHENTIK_EMAIL__FROM=auth@updates.thesatelliteoflove.com AUTHENTIK_EMAIL__FROM=auth@{{ email_domains.updates }}

View File

@@ -1,6 +1,6 @@
services: services:
baikal: baikal:
image: ckulka/baikal:nginx image: ckulka/baikal:0.10.1-nginx
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- config:/var/www/baikal/config - config:/var/www/baikal/config
@@ -8,7 +8,7 @@ services:
labels: labels:
glance.name: Baikal glance.name: Baikal
glance.icon: si:protoncalendar glance.icon: si:protoncalendar
glance.url: https://cal.thesatelliteoflove.com/ glance.url: https://{{ subdomains.cal }}/
glance.description: CalDav server glance.description: CalDav server
volumes: volumes:
@@ -18,4 +18,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -16,11 +16,11 @@ services:
labels: labels:
glance.name: Caddy glance.name: Caddy
glance.icon: si:caddy glance.icon: si:caddy
glance.url: https://thesatelliteoflove.com/ glance.url: https://{{ primary_domain }}/
glance.description: Reverse proxy glance.description: Reverse proxy
networks: networks:
default: default:
ipv4_address: 172.20.0.5 ipv4_address: {{ docker.hairpin_ip }}
volumes: volumes:
caddy_data: caddy_data:
caddy_config: caddy_config:
@@ -28,4 +28,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -16,7 +16,7 @@ services:
labels: labels:
glance.name: Calibre glance.name: Calibre
glance.icon: si:calibreweb glance.icon: si:calibreweb
glance.url: https://books.thesatelliteoflove.com/ glance.url: https://{{ subdomains.books }}/
glance.description: Book server glance.description: Book server
volumes: volumes:
config: config:
@@ -26,4 +26,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -5,11 +5,11 @@ services:
container_name: changedetection container_name: changedetection
hostname: changedetection hostname: changedetection
extra_hosts: extra_hosts:
- 'chat.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.chat }}:172.20.0.5'
labels: labels:
glance.name: Changedetection glance.name: Changedetection
glance.icon: si:watchtower glance.icon: si:watchtower
glance.url: https://watcher.thesatelliteoflove.com/ glance.url: https://{{ subdomains.watcher }}/
glance.description: Changedetection glance.description: Changedetection
glance.id: changedetection glance.id: changedetection
volumes: volumes:
@@ -50,7 +50,7 @@ services:
# - NO_PROXY="localhost,192.168.0.0/24" # - NO_PROXY="localhost,192.168.0.0/24"
# #
# Base URL of your changedetection.io install (Added to the notification alert) # Base URL of your changedetection.io install (Added to the notification alert)
- BASE_URL=https://watcher.thesatelliteoflove.com - BASE_URL=https://{{ subdomains.watcher }}
# Respect proxy_pass type settings, `proxy_set_header Host "localhost";` and `proxy_set_header X-Forwarded-Prefix /app;` # Respect proxy_pass type settings, `proxy_set_header Host "localhost";` and `proxy_set_header X-Forwarded-Prefix /app;`
# More here https://github.com/dgtlmoon/changedetection.io/wiki/Running-changedetection.io-behind-a-reverse-proxy-sub-directory # More here https://github.com/dgtlmoon/changedetection.io/wiki/Running-changedetection.io-behind-a-reverse-proxy-sub-directory
# - USE_X_SETTINGS=1 # - USE_X_SETTINGS=1
@@ -130,4 +130,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -5,7 +5,7 @@ services:
labels: labels:
glance.name: Code Server glance.name: Code Server
glance.icon: si:vscodium glance.icon: si:vscodium
glance.url: https://code.thesatelliteoflove.com/ glance.url: https://{{ subdomains.code }}/
glance.description: Code Server glance.description: Code Server
container_name: codeserver container_name: codeserver
volumes: volumes:
@@ -19,4 +19,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -7,10 +7,10 @@ services:
labels: labels:
glance.name: Conduit glance.name: Conduit
glance.icon: si:matrix glance.icon: si:matrix
glance.url: https://chat.thesatelliteoflove.com/ glance.url: https://{{ subdomains.chat }}/
glance.description: Matrix server glance.description: Matrix server
environment: environment:
CONDUIT_SERVER_NAME: chat.thesatelliteoflove.com # EDIT THIS CONDUIT_SERVER_NAME: {{ subdomains.chat }} # EDIT THIS
CONDUIT_DATABASE_PATH: /var/lib/matrix-conduit/ CONDUIT_DATABASE_PATH: /var/lib/matrix-conduit/
CONDUIT_DATABASE_BACKEND: rocksdb CONDUIT_DATABASE_BACKEND: rocksdb
CONDUIT_PORT: 6167 CONDUIT_PORT: 6167
@@ -43,4 +43,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -10,7 +10,7 @@ services:
- dawarich_db_data:/var/lib/postgresql/data - dawarich_db_data:/var/lib/postgresql/data
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: {{ dawarich_db_password }} POSTGRES_PASSWORD: {{ vault_dawarich.postgres_password }}
POSTGRES_DB: dawarich_production POSTGRES_DB: dawarich_production
restart: always restart: always
healthcheck: healthcheck:
@@ -25,7 +25,7 @@ services:
labels: labels:
glance.name: Dawarich glance.name: Dawarich
glance.icon: si:openstreetmap glance.icon: si:openstreetmap
glance.url: https://loclog.thesatelliteoflove.com/ glance.url: https://{{ subdomains.loclog }}/
glance.description: Dawarich glance.description: Dawarich
glance.id: dawarich glance.id: dawarich
volumes: volumes:
@@ -45,10 +45,10 @@ services:
DATABASE_HOST: dawarich_db DATABASE_HOST: dawarich_db
DATABASE_PORT: 5432 DATABASE_PORT: 5432
DATABASE_USERNAME: postgres DATABASE_USERNAME: postgres
DATABASE_PASSWORD: {{ dawarich_db_password }} DATABASE_PASSWORD: {{ vault_dawarich.postgres_password }}
DATABASE_NAME: dawarich_production DATABASE_NAME: dawarich_production
MIN_MINUTES_SPENT_IN_CITY: 60 MIN_MINUTES_SPENT_IN_CITY: 60
APPLICATION_HOSTS: loclog.thesatelliteoflove.com,localhost,::1,127.0.0.1 APPLICATION_HOSTS: {{ subdomains.loclog }},localhost,::1,127.0.0.1
TIME_ZONE: America/Denver TIME_ZONE: America/Denver
APPLICATION_PROTOCOL: http APPLICATION_PROTOCOL: http
DISTANCE_UNIT: mi DISTANCE_UNIT: mi
@@ -85,4 +85,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -7,15 +7,15 @@ services:
- database__client=sqlite3 - database__client=sqlite3
- database__connection__filename=/var/lib/ghost/content/data/ghost.db - database__connection__filename=/var/lib/ghost/content/data/ghost.db
- database__useNullAsDefault=true - database__useNullAsDefault=true
- url=https://phlog.thesatelliteoflove.com - url=https://{{ subdomains.phlog }}
volumes: volumes:
- ghost:/var/lib/ghost/content - ghost:/var/lib/ghost/content
extra_hosts: extra_hosts:
- 'phlog.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.phlog }}:172.20.0.5'
labels: labels:
glance.name: Ghost glance.name: Ghost
glance.icon: si:ghost glance.icon: si:ghost
glance.url: https://phlog.thesatelliteoflove.com/ glance.url: https://{{ subdomains.phlog }}/
glance.description: Photo Blog glance.description: Photo Blog
volumes: volumes:
@@ -24,4 +24,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -7,17 +7,17 @@ services:
- USER_UID=1000 - USER_UID=1000
- USER_GID=1000 - USER_GID=1000
- GITEA__mailer__ENABLED=true - GITEA__mailer__ENABLED=true
- GITEA__mailer__FROM=git@updates.thesatelliteoflove.com - GITEA__mailer__FROM=git@{{ email_domains.updates }}
- GITEA__mailer__PROTOCOL=smtps - GITEA__mailer__PROTOCOL=smtps
- GITEA__mailer__SMTP_ADDR=smtp.resend.com - GITEA__mailer__SMTP_ADDR={{ smtp.host }}
- GITEA__mailer__SMTP_PORT=465 - GITEA__mailer__SMTP_PORT=465
- GITEA__mailer__USER=resend - GITEA__mailer__USER={{ smtp.username }}
- GITEA__mailer__PASSWD={{ resend_key }} - GITEA__mailer__PASSWD={{ vault_smtp.password }}
restart: unless-stopped restart: unless-stopped
labels: labels:
glance.name: Gitea glance.name: Gitea
glance.icon: si:gitea glance.icon: si:gitea
glance.url: https://git.thesatelliteoflove.com/ glance.url: https://{{ subdomains.git }}/
glance.description: Code repo glance.description: Code repo
glance.id: gitea glance.id: gitea
volumes: volumes:
@@ -27,8 +27,8 @@ services:
ports: ports:
- 222:22 - 222:22
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
- 'git.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.git }}:{{ docker.hairpin_ip }}'
runner: runner:
image: gitea/act_runner:nightly image: gitea/act_runner:nightly
restart: unless-stopped restart: unless-stopped
@@ -37,12 +37,12 @@ services:
environment: environment:
- CONFIG_FILE=/config.yaml - CONFIG_FILE=/config.yaml
- GITEA_INSTANCE_URL=http://gitea:3000 - GITEA_INSTANCE_URL=http://gitea:3000
- GITEA_RUNNER_REGISTRATION_TOKEN={{ gitea_runner_key }} - GITEA_RUNNER_REGISTRATION_TOKEN={{ vault_infrastructure.gitea_runner_key }}
- GITEA_RUNNER_NAME=runner_1 - GITEA_RUNNER_NAME=runner_1
- GITEA_RUNNER_LABELS=docker - GITEA_RUNNER_LABELS=docker
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
- 'git.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.git }}:{{ docker.hairpin_ip }}'
labels: labels:
glance.parent: gitea glance.parent: gitea
glance.name: Worker glance.name: Worker
@@ -50,11 +50,11 @@ services:
- ./runner-config.yaml:/config.yaml - ./runner-config.yaml:/config.yaml
- ./data:/data - ./data:/data
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- /opt/stacks/caddy/site:/sites - {{ paths.stacks }}/caddy/site:/sites
volumes: volumes:
gitea: gitea:
driver: local driver: local
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,6 +1,6 @@
services: services:
glance: glance:
image: glanceapp/glance image: glanceapp/glance:v0.8.3
volumes: volumes:
- ./config:/app/config - ./config:/app/config
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
@@ -8,16 +8,16 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped restart: unless-stopped
extra_hosts: extra_hosts:
- 'thesatelliteoflove.com:172.20.0.5' - '{{ primary_domain }}:172.20.0.5'
- 'watcher.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.watcher }}:172.20.0.5'
labels: labels:
glance.name: Glance glance.name: Glance
glance.icon: si:homepage glance.icon: si:homepage
glance.url: https://home.thesatelliteoflove.com/ glance.url: https://{{ subdomains.home }}/
glance.description: Homepage app glance.description: Homepage app
glance.id: glance glance.id: glance
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -4,28 +4,28 @@ services:
container_name: gotosocial container_name: gotosocial
user: 1000:1000 user: 1000:1000
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
environment: environment:
GTS_HOST: social.thesatelliteoflove.com GTS_HOST: {{ subdomains.social }}
GTS_DB_TYPE: sqlite GTS_DB_TYPE: sqlite
GTS_DB_ADDRESS: /gotosocial/storage/sqlite.db GTS_DB_ADDRESS: /gotosocial/storage/sqlite.db
GTS_WAZERO_COMPILATION_CACHE: /gotosocial/.cache GTS_WAZERO_COMPILATION_CACHE: /gotosocial/.cache
GTS_LETSENCRYPT_ENABLED: "false" GTS_LETSENCRYPT_ENABLED: "false"
GTS_LETSENCRYPT_EMAIL_ADDRESS: "" GTS_LETSENCRYPT_EMAIL_ADDRESS: ""
GTS_TRUSTED_PROXIES: "172.20.0.5" GTS_TRUSTED_PROXIES: "{{ docker.hairpin_ip }}"
GTS_ACCOUNT_DOMAIN: thesatelliteoflove.com GTS_ACCOUNT_DOMAIN: {{ primary_domain }}
GTS_OIDC_ENABLED: "true" GTS_OIDC_ENABLED: "true"
GTS_OIDC_IDP_NAME: "Authentik" GTS_OIDC_IDP_NAME: "Authentik"
GTS_OIDC_ISSUER: https://auth.thesatelliteoflove.com/application/o/gotosocial/ GTS_OIDC_ISSUER: https://{{ subdomains.auth }}/application/o/gotosocial/
GTS_OIDC_CLIENT_ID: {{ gts_oidc_client_id }} GTS_OIDC_CLIENT_ID: {{ vault_gotosocial.oidc.client_id }}
GTS_OIDC_CLIENT_SECRET: {{ gts_oidc_client_secret }} GTS_OIDC_CLIENT_SECRET: {{ vault_gotosocial.oidc.client_secret }}
GTS_OIDC_LINK_EXISTING: "true" GTS_OIDC_LINK_EXISTING: "true"
GTS_HTTP_CLIENT: "20s" GTS_HTTP_CLIENT: "20s"
GTS_SMTP_HOST: "smtp.resend.com" GTS_SMTP_HOST: "{{ smtp.host }}"
GTS_SMTP_PORT: "587" GTS_SMTP_PORT: "587"
GTS_SMTP_USERNAME: "resend" GTS_SMTP_USERNAME: "{{ smtp.username }}"
GTS_SMTP_PASSWORD: {{ resend_key }} GTS_SMTP_PASSWORD: {{ vault_smtp.password }}
GTS_SMTP_FROM: "social@updates.thesatelliteoflove.com" GTS_SMTP_FROM: "social@{{ email_domains.updates }}"
TZ: UTC TZ: UTC
volumes: volumes:
- gotosocial:/gotosocial/storage - gotosocial:/gotosocial/storage
@@ -34,7 +34,7 @@ services:
docker-volume-backup.stop-during-backup: true docker-volume-backup.stop-during-backup: true
glance.name: GoToSocial glance.name: GoToSocial
glance.icon: si:mastodon glance.icon: si:mastodon
glance.url: https://social.thesatelliteoflove.com/ glance.url: https://{{ subdomains.social }}/
glance.description: Fediverse server glance.description: Fediverse server
glance.id: gotosocial glance.id: gotosocial
@@ -52,8 +52,8 @@ services:
BACKUP_RETENTION_DAYS: 1 BACKUP_RETENTION_DAYS: 1
AWS_S3_BUCKET_NAME: tsolbackups AWS_S3_BUCKET_NAME: tsolbackups
AWS_ENDPOINT: s3.us-west-004.backblazeb2.com AWS_ENDPOINT: s3.us-west-004.backblazeb2.com
AWS_ACCESS_KEY_ID: {{ backup_key_id }} AWS_ACCESS_KEY_ID: {{ vault_backup.access_key_id }}
AWS_SECRET_ACCESS_KEY: {{ backup_key }} AWS_SECRET_ACCESS_KEY: {{ vault_backup.secret_access_key }}
BACKUP_SKIP_BACKENDS_FROM_PRUNE: s3 BACKUP_SKIP_BACKENDS_FROM_PRUNE: s3
@@ -69,4 +69,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -11,21 +11,21 @@ services:
labels: labels:
glance.name: Heyform glance.name: Heyform
glance.icon: si:googleforms glance.icon: si:googleforms
glance.url: https://forms.nerder.land/ glance.url: https://{{ subdomains.heyform }}/
glance.description: Forms server glance.description: Forms server
glance.id: heyform glance.id: heyform
environment: environment:
- APP_HOMEPAGE_URL=http://forms.nerder.land - APP_HOMEPAGE_URL=http://{{ subdomains.heyform }}
- SESSION_KEY={{ heyform_session_key }} - SESSION_KEY={{ vault_heyform.session_key }}
- FORM_ENCRYPTION_KEY={{ heyform_encryption_key }} - FORM_ENCRYPTION_KEY={{ vault_heyform.encryption_key }}
- MONGO_URI='mongodb://mongo:27017/heyform' - MONGO_URI='mongodb://mongo:27017/heyform'
- REDIS_HOST=keydb - REDIS_HOST=keydb
- REDIS_PORT=6379 - REDIS_PORT=6379
- SMTP_FROM=nerderland@updates.thesatelliteoflove.com - SMTP_FROM=nerderland@{{ email_domains.updates }}
- SMTP_HOST=smtp.resend.com - SMTP_HOST={{ smtp.host }}
- SMTP_PORT=465 - SMTP_PORT=465
- SMTP_USER=resend - SMTP_USER={{ smtp.username }}
- SMTP_PASSWORD={{ resend_key }} - SMTP_PASSWORD={{ vault_smtp.password }}
- SMTP_SECURE=true - SMTP_SECURE=true
mongo: mongo:
@@ -60,4 +60,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,7 +1,7 @@
version: "3.8" version: "3.8"
services: services:
web: web:
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release} image: ghcr.io/karakeep-app/karakeep:0.25.0
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- data:/data - data:/data
@@ -10,8 +10,8 @@ services:
env_file: env_file:
- .env - .env
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
- bookmarks.thesatelliteoflove.com:172.20.0.5 - '{{ subdomains.bookmarks }}:{{ docker.hairpin_ip }}'
environment: environment:
MEILI_ADDR: http://meilisearch:7700 MEILI_ADDR: http://meilisearch:7700
DATA_DIR: /data DATA_DIR: /data
@@ -19,7 +19,7 @@ services:
labels: labels:
glance.name: Karakeep glance.name: Karakeep
glance.icon: si:wikibooks glance.icon: si:wikibooks
glance.url: https://bookmarks.thesatelliteoflove.com/ glance.url: https://{{ subdomains.bookmarks }}/
glance.description: Bookmark manager glance.description: Bookmark manager
glance.id: karakeep glance.id: karakeep
chrome: chrome:
@@ -53,4 +53,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,10 +1,10 @@
KARAKEEP_VERSION=release KARAKEEP_VERSION=release
NEXTAUTH_SECRET={{ hoarder_nextauth_secret }} NEXTAUTH_SECRET={{ vault_hoarder.nextauth_secret }}
MEILI_MASTER_KEY={{ hoarder_meili_master_key }} MEILI_MASTER_KEY={{ vault_hoarder.meili_master_key }}
NEXTAUTH_URL=https://bookmarks.thesatelliteoflove.com NEXTAUTH_URL=https://{{ subdomains.bookmarks }}
OPENAI_API_KEY={{ openai_api_key }} OPENAI_API_KEY={{ vault_infrastructure.openai_api_key }}
OAUTH_CLIENT_SECRET={{ hoarder_oidc_client_secret }} OAUTH_CLIENT_SECRET={{ vault_hoarder.oidc.client_secret }}
OAUTH_CLIENT_ID=GTi0QBRH5TiTqZfxfAkYSQVVFouGdlOFMc2sjivN OAUTH_CLIENT_ID=GTi0QBRH5TiTqZfxfAkYSQVVFouGdlOFMc2sjivN
OAUTH_PROVIDER_NAME=Authentik OAUTH_PROVIDER_NAME=Authentik
OAUTH_WELLKNOWN_URL=https://auth.thesatelliteoflove.com/application/o/hoarder/.well-known/openid-configuration OAUTH_WELLKNOWN_URL=https://{{ subdomains.auth }}/application/o/hoarder/.well-known/openid-configuration
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING=true OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING=true

View File

@@ -9,12 +9,12 @@ services:
- .env.local - .env.local
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
- "auth.thesatelliteoflove.com:172.20.0.5" - "{{ subdomains.auth }}:{{ docker.hairpin_ip }}"
- "cal.thesatelliteoflove.com:172.20.0.5" - "{{ subdomains.cal }}:{{ docker.hairpin_ip }}"
labels: labels:
glance.name: MMDL glance.name: MMDL
glance.icon: si:task glance.icon: si:task
glance.url: https://tasks.thesatelliteoflove.com/ glance.url: https://{{ subdomains.tasks }}/
glance.description: Task and calendar management glance.description: Task and calendar management
glance.id: mmdl glance.id: mmdl
@@ -26,8 +26,8 @@ services:
environment: environment:
MYSQL_DATABASE: mmdl MYSQL_DATABASE: mmdl
MYSQL_USER: mmdl MYSQL_USER: mmdl
MYSQL_PASSWORD: "{{ vault_mmdl_mysql_password }}" MYSQL_PASSWORD: "{{ vault_mmdl.mysql_password }}"
MYSQL_ROOT_PASSWORD: "{{ vault_mmdl_mysql_root_password }}" MYSQL_ROOT_PASSWORD: "{{ vault_mmdl.mysql_root_password }}"
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_ROOT_HOST: "%" MYSQL_ROOT_HOST: "%"
volumes: volumes:
@@ -43,4 +43,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,32 +1,32 @@
# Database Configuration # Database Configuration
DB_HOST=mmdl_db DB_HOST=mmdl_db
DB_USER=mmdl DB_USER=mmdl
DB_PASS={{ vault_mmdl_mysql_password }} DB_PASS={{ vault_mmdl.mysql_password }}
DB_PORT=3306 DB_PORT=3306
DB_DIALECT=mysql DB_DIALECT=mysql
DB_CHARSET=utf8mb4 DB_CHARSET=utf8mb4
DB_NAME=mmdl DB_NAME=mmdl
# Encryption # Encryption
AES_PASSWORD={{ vault_mmdl_aes_password }} AES_PASSWORD={{ vault_mmdl.aes_password }}
# SMTP Settings # SMTP Settings
SMTP_HOST=smtp.resend.com SMTP_HOST={{ smtp.host }}
SMTP_USERNAME=resend SMTP_USERNAME={{ smtp.username }}
SMTP_PASSWORD={{ resend_key }} SMTP_PASSWORD={{ vault_smtp.password }}
SMTP_FROM=tasks@updates.thesatelliteoflove.com SMTP_FROM=tasks@{{ email_domains.updates }}
SMTP_PORT=587 SMTP_PORT=587
SMTP_SECURE=true SMTP_SECURE=true
# Authentication # Authentication
USE_NEXT_AUTH=true USE_NEXT_AUTH=true
NEXTAUTH_URL=https://tasks.thesatelliteoflove.com NEXTAUTH_URL=https://{{ subdomains.tasks }}
NEXTAUTH_SECRET={{ vault_mmdl_nextauth_secret }} NEXTAUTH_SECRET={{ vault_mmdl.nextauth_secret }}
# Authentik OIDC Configuration # Authentik OIDC Configuration
AUTHENTIK_ISSUER=https://auth.thesatelliteoflove.com/application/o/mmdl AUTHENTIK_ISSUER=https://{{ subdomains.auth }}/application/o/mmdl
AUTHENTIK_CLIENT_ID={{ vault_mmdl_oidc_client_id }} AUTHENTIK_CLIENT_ID={{ vault_mmdl.oidc.client_id }}
AUTHENTIK_CLIENT_SECRET={{ vault_mmdl_oidc_client_secret }} AUTHENTIK_CLIENT_SECRET={{ vault_mmdl.oidc.client_secret }}
# User and Session Management # User and Session Management
ALLOW_USER_REGISTRATION=false ALLOW_USER_REGISTRATION=false
@@ -35,7 +35,8 @@ OTP_VALIDITY_PERIOD=300
SESSION_VALIDITY_PERIOD=30 SESSION_VALIDITY_PERIOD=30
# Application Settings # Application Settings
API_URL=https://tasks.thesatelliteoflove.com API_URL=https://{{ subdomains.tasks }}
DEBUG_MODE=false DEBUG_MODE=false
TEST_MODE=false TEST_MODE=false
NEXT_API_DEBUG_MODE=false
SUBTASK_RECURSION_DEPTH=5 SUBTASK_RECURSION_DEPTH=5

View File

@@ -14,7 +14,7 @@ services:
labels: labels:
glance.name: Paperless NGX glance.name: Paperless NGX
glance.icon: si:paperlessngx glance.icon: si:paperlessngx
glance.url: https://papers.thesatelliteoflove.com/ glance.url: https://{{ subdomains.paper }}/
glance.description: Document server glance.description: Document server
glance.id: paperlessngx glance.id: paperlessngx
depends_on: depends_on:
@@ -28,7 +28,7 @@ services:
- ./consume:/usr/src/paperless/consume - ./consume:/usr/src/paperless/consume
env_file: docker-compose.env env_file: docker-compose.env
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
environment: environment:
PAPERLESS_REDIS: redis://broker:6379 PAPERLESS_REDIS: redis://broker:6379
PAPERLESS_TIKA_ENABLED: 1 PAPERLESS_TIKA_ENABLED: 1
@@ -65,4 +65,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -24,11 +24,11 @@
# This is required if you will be exposing Paperless-ngx on a public domain # This is required if you will be exposing Paperless-ngx on a public domain
# (if doing so please consider security measures such as reverse proxy) # (if doing so please consider security measures such as reverse proxy)
PAPERLESS_URL=https://paper.thesatelliteoflove.com PAPERLESS_URL=https://{{ subdomains.paper }}
# Adjust this key if you plan to make paperless available publicly. It should # Adjust this key if you plan to make paperless available publicly. It should
# be a very long sequence of random characters. You don't need to remember it. # be a very long sequence of random characters. You don't need to remember it.
PAPERLESS_SECRET_KEY={{ paperlessngx_secret }} PAPERLESS_SECRET_KEY={{ vault_paperlessngx.secret_key }}
# Use this variable to set a timezone for the Paperless Docker containers. If not specified, defaults to UTC. # Use this variable to set a timezone for the Paperless Docker containers. If not specified, defaults to UTC.
PAPERLESS_TIME_ZONE=America/Denver PAPERLESS_TIME_ZONE=America/Denver
@@ -43,4 +43,4 @@ PAPERLESS_TIME_ZONE=America/Denver
# authentik # authentik
PAPERLESS_APPS: "allauth.socialaccount.providers.openid_connect" PAPERLESS_APPS: "allauth.socialaccount.providers.openid_connect"
PAPERLESS_SOCIALACCOUNT_PROVIDERS: '{"openid_connect": {"APPS": [{"provider_id": "authentik","name": "Authentik SSO","client_id": "{{ paperless_oauth_client_id }}","secret": "{{ paperless_oauth_client_secret }}","settings": { "server_url": "https://auth.thesatelliteoflove.com/application/o/paperlessngx/.well-known/openid-configuration"}}]}}' PAPERLESS_SOCIALACCOUNT_PROVIDERS: '{"openid_connect": {"APPS": [{"provider_id": "authentik","name": "Authentik SSO","client_id": "{{ vault_paperlessngx.oidc.client_id }}","secret": "{{ vault_paperlessngx.oidc.client_secret }}","settings": { "server_url": "https://{{ subdomains.auth }}/application/o/paperlessngx/.well-known/openid-configuration"}}]}}'

View File

@@ -5,11 +5,11 @@ services:
environment: environment:
- TRUST_PROXY=true - TRUST_PROXY=true
extra_hosts: extra_hosts:
- 'auth.thesatelliteoflove.com:172.20.0.5' - '{{ subdomains.auth }}:{{ docker.hairpin_ip }}'
labels: labels:
glance.name: Pingvin glance.name: Pingvin
glance.icon: si:files glance.icon: si:files
glance.url: http://netcup.porgy-porgy.ts.net:8945 glance.url: https://{{ subdomains.files }}
glance.description: File sharing service glance.description: File sharing service
glance.id: pingvin glance.id: pingvin
volumes: volumes:
@@ -21,4 +21,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -5,7 +5,7 @@ services:
labels: labels:
glance.name: Pinry glance.name: Pinry
glance.icon: si:pinterest glance.icon: si:pinterest
glance.url: https://pin.thesatelliteoflove.com glance.url: https://{{ subdomains.pin }}
glance.description: Pinterest clone glance.description: Pinterest clone
glance.id: pinterest glance.id: pinterest
environment: environment:
@@ -18,4 +18,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

View File

@@ -1,13 +1,13 @@
services: services:
postiz: postiz:
image: ghcr.io/gitroomhq/postiz-app:latest image: ghcr.io/gitroomhq/postiz-app:v1.48.4
container_name: postiz container_name: postiz
restart: always restart: always
environment: environment:
# You must change these. Replace `postiz.your-server.com` with your DNS name - what your web browser sees. # You must change these. Replace `postiz.your-server.com` with your DNS name - what your web browser sees.
MAIN_URL: "https://post.thesatelliteoflove.com" MAIN_URL: "https://{{ subdomains.post }}"
FRONTEND_URL: "https://post.thesatelliteoflove.com" FRONTEND_URL: "https://{{ subdomains.post }}"
NEXT_PUBLIC_BACKEND_URL: "https://post.thesatelliteoflove.com/api" NEXT_PUBLIC_BACKEND_URL: "https://{{ subdomains.post }}/api"
JWT_SECRET: "TShr6Fdcwf67wIhuUvg0gOsJbdcQmgMiJl5kUh6JCfY=" JWT_SECRET: "TShr6Fdcwf67wIhuUvg0gOsJbdcQmgMiJl5kUh6JCfY="
# These defaults are probably fine, but if you change your user/password, update it in the # These defaults are probably fine, but if you change your user/password, update it in the
@@ -24,7 +24,7 @@ services:
# Social keys # Social keys
LINKEDIN_CLIENT_ID: "86q7ksc8q5pai3" LINKEDIN_CLIENT_ID: "86q7ksc8q5pai3"
LINKEDIN_CLIENT_SECRET: {{ linkedin_secret }} LINKEDIN_CLIENT_SECRET: {{ vault_postiz.linkedin_secret }}
volumes: volumes:
- postiz-config:/config/ - postiz-config:/config/
- postiz-uploads:/uploads/ - postiz-uploads:/uploads/
@@ -35,7 +35,7 @@ services:
condition: service_healthy condition: service_healthy
labels: labels:
glance.name: Postiz glance.name: Postiz
glance.url: https://post.thesatelliteoflove.com/ glance.url: https://{{ subdomains.post }}/
glance.description: Social media scheduler glance.description: Social media scheduler
glance.id: postiz glance.id: postiz
@@ -90,4 +90,4 @@ volumes:
networks: networks:
default: default:
external: true external: true
name: lava name: {{ docker.network_name }}

22
todo.md
View File

@@ -17,18 +17,18 @@
``` ```
- **COMPLETED**: All services organized into logical categories with category-level tags - **COMPLETED**: All services organized into logical categories with category-level tags
### 2. Standardize variable management ### 2. Standardize variable management ✅ COMPLETED
- **Current Issue**: Secrets in single encrypted file, no clear variable hierarchy - **Current Issue**: Secrets in single encrypted file, no clear variable hierarchy
- **Solution**: Create proper variable structure: - **Solution**: Create proper variable structure:
``` ```
group_vars/ group_vars/
├── all/ ├── all/
│ ├── common.yml (shared config) │ ├── domains.yml (domain and subdomain mappings)
── secrets.yml (vault encrypted) ── infrastructure.yml (network config, Docker settings)
├── docker/ │ ├── vault.yml (encrypted secrets with vault_ prefix)
── services.yml (service configs) ── services.yml (service configuration flags)
│ └── networking.yml (network settings)
``` ```
- **COMPLETED**: Implemented comprehensive variable hierarchy, updated all templates to use centralized variables, fixed service tag isolation
### 3. Template consolidation ✅ PARTIALLY COMPLETED ### 3. Template consolidation ✅ PARTIALLY COMPLETED
- **Current Issue**: Many compose templates repeat patterns, some services used static files - **Current Issue**: Many compose templates repeat patterns, some services used static files
@@ -43,7 +43,7 @@
- **Solution**: Implement comprehensive health monitoring with standardized healthcheck patterns - **Solution**: Implement comprehensive health monitoring with standardized healthcheck patterns
### 5. Implement backup strategy ### 5. Implement backup strategy
- **Issue**: No automated backups for 25+ services and their data - **Issue**: No automated backups for 25 services and their data
- **Solution**: Add backup role with: - **Solution**: Add backup role with:
- Database dumps for PostgreSQL services - Database dumps for PostgreSQL services
- Volume backups for file-based services - Volume backups for file-based services
@@ -99,7 +99,7 @@
- [x] Convert static compose files to templates - [x] Convert static compose files to templates
- [x] Remove unused services (beaver, grist, stirlingpdf, tasksmd, redlib) - [x] Remove unused services (beaver, grist, stirlingpdf, tasksmd, redlib)
- [x] Clean up templates and files directories - [x] Clean up templates and files directories
- [ ] Implement variable hierarchy - [x] Implement variable hierarchy
- [ ] Create reusable template patterns - [ ] Create reusable template patterns
### Week 2: Security & Monitoring ### Week 2: Security & Monitoring
@@ -124,10 +124,12 @@
- **Template Standardization**: Converted all static compose files to Jinja2 templates - **Template Standardization**: Converted all static compose files to Jinja2 templates
- **Service Cleanup**: Removed 5 unused/broken services (beaver, grist, stirlingpdf, tasksmd, redlib) - **Service Cleanup**: Removed 5 unused/broken services (beaver, grist, stirlingpdf, tasksmd, redlib)
- **Category-Based Deployment**: Can now deploy services by category using tags (infrastructure, media, etc.) - **Category-Based Deployment**: Can now deploy services by category using tags (infrastructure, media, etc.)
- **Documentation Updates**: Updated CLAUDE.md to reflect new architecture - **Variable Management**: Implemented comprehensive centralized variable hierarchy with proper secret organization
- **Service Tag Isolation**: Fixed service tags to deploy individual services only (not entire categories)
- **Documentation Updates**: Updated all README files and CLAUDE.md to reflect new architecture
### 📊 Current Stats ### 📊 Current Stats
- **22+ active services** organized into 6 categories - **25 active services** organized into 6 categories
- **100% templated** compose files (no static files) - **100% templated** compose files (no static files)
- **6 service directories** for logical organization - **6 service directories** for logical organization
- **Clean file structure** with only essential static files - **Clean file structure** with only essential static files