Migrate sigvild-gallery to production environment

- Add multi-environment architecture (homelab + production)
- Create production environment (mini-vps) for client projects
- Create homelab playbook for arch-vps services
- Create production playbook for mini-vps services
- Move sigvild-gallery from homelab to production
- Restructure variables: group_vars/production + host_vars/arch-vps
- Add backup-sigvild.yml playbook with auto-restore functionality
- Fix restore logic to check for data before creating directories
- Add manual variable loading workaround for Ansible 2.20
- Update all documentation for multi-environment setup
- Add ADR-007 documenting multi-environment architecture decision
This commit is contained in:
2025-12-15 16:33:33 +01:00
parent e8b76c6a72
commit ecbeb07ba2
18 changed files with 553 additions and 213 deletions

View File

@@ -32,43 +32,64 @@ Rick-infra implements a security-first infrastructure stack featuring:
└─────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────┘
``` ```
## Infrastructure Environments
Rick-infra manages **two separate environments**:
### 🏠 Homelab (arch-vps)
Personal services and experimentation at **jnss.me**:
- PostgreSQL, Valkey, Podman infrastructure
- Authentik SSO (auth.jnss.me)
- Nextcloud (cloud.jnss.me)
- Gitea (git.jnss.me)
### 🚀 Production (mini-vps)
Client projects requiring high uptime:
- Sigvild Gallery (sigvild.no, api.sigvild.no)
- Minimal infrastructure footprint
## Quick Start ## Quick Start
### Prerequisites ### Prerequisites
- **VPS**: Fresh Arch Linux VPS with root access - **VPS**: Fresh Arch Linux VPS with root access
- **DNS**: Domain pointed to VPS IP address - **DNS**: Domains pointed to VPS IP addresses
- **SSH**: Key-based authentication configured - **SSH**: Key-based authentication configured
### Deploy Complete Stack ### Deploy Infrastructure
```bash ```bash
# 1. Clone repository # 1. Clone repository
git clone https://github.com/your-username/rick-infra.git git clone https://github.com/your-username/rick-infra.git
cd rick-infra cd rick-infra
# 2. Configure inventory # 2. Configure inventory (already set up)
cp inventory/hosts.yml.example inventory/hosts.yml # inventory/hosts.yml defines homelab and production groups
# Edit inventory/hosts.yml with your VPS details
# 3. Set up vault variables # 3. Set up vault variables
ansible-vault create host_vars/arch-vps/vault.yml ansible-vault edit group_vars/production/vault.yml # Production secrets
# Add required secrets (see deployment guide) ansible-vault edit host_vars/arch-vps/vault.yml # Homelab secrets
# 4. Deploy complete infrastructure # 4. Deploy to specific environment
ansible-playbook -i inventory/hosts.yml site.yml --ask-vault-pass ansible-playbook playbooks/homelab.yml # Deploy homelab
ansible-playbook playbooks/production.yml # Deploy production
ansible-playbook site.yml # Deploy both
``` ```
**Total deployment time**: 8-14 minutes for complete stack **Deployment times**:
- Homelab (full stack): 8-14 minutes
- Production (minimal): 3-5 minutes
### Verify Deployment ### Verify Deployment
```bash ```bash
# Check services # Check homelab services
curl -I https://auth.jnss.me/ # Authentik SSO curl -I https://auth.jnss.me/ # Authentik SSO
curl -I https://git.jnss.me/ # Gitea (if enabled) curl -I https://cloud.jnss.me/ # Nextcloud
ansible homelab -a "systemctl status postgresql valkey caddy"
# Check infrastructure # Check production services
ansible arch-vps -m command -a "systemctl status postgresql valkey caddy" curl -I https://sigvild.no/ # Sigvild Gallery
ansible production -a "systemctl status sigvild-gallery caddy"
``` ```
## Key Features ## Key Features
@@ -116,21 +137,32 @@ ansible arch-vps -m command -a "systemctl status postgresql valkey caddy"
## Core Services ## Core Services
### Infrastructure Services (Native systemd) ### Homelab Services (arch-vps)
**Infrastructure (Native systemd)**:
- **PostgreSQL** - High-performance database with Unix socket support - **PostgreSQL** - High-performance database with Unix socket support
- **Valkey** - Redis-compatible cache with Unix socket support - **Valkey** - Redis-compatible cache with Unix socket support
- **Caddy** - Automatic HTTPS reverse proxy with Cloudflare DNS - **Caddy** - Automatic HTTPS reverse proxy with Cloudflare DNS
- **Podman** - Rootless container runtime with systemd integration - **Podman** - Rootless container runtime with systemd integration
### Authentication Services **Authentication**:
- **Authentik** - Modern SSO server with OAuth2/OIDC/SAML support - **Authentik** - Modern SSO server with OAuth2/OIDC/SAML support
- **Forward Auth** - Transparent service protection via Caddy integration - **Forward Auth** - Transparent service protection via Caddy
- **Multi-Factor Authentication** - TOTP, WebAuthn, SMS support
### Application Services (Containerized) **Applications (Containerized)**:
- **Nextcloud** - Personal cloud storage and file sync
- **Gitea** - Self-hosted Git service with SSO integration - **Gitea** - Self-hosted Git service with SSO integration
- **Gallery** - Media gallery with authentication
- **Custom Services** - Template for additional service integration ### Production Services (mini-vps)
**Infrastructure**:
- **Caddy** - Automatic HTTPS reverse proxy with Cloudflare DNS
**Applications**:
- **Sigvild Gallery** - Wedding photo gallery with PocketBase API
- Frontend: SvelteKit static site
- Backend: Go + SQLite (PocketBase)
- Domains: sigvild.no, api.sigvild.no
## Architecture Benefits ## Architecture Benefits

View File

@@ -1,68 +0,0 @@
---
# Deploy Unix Socket Updates for PostgreSQL, Valkey, Authentik, and Gitea
# This playbook updates services to use Unix sockets for inter-process communication
- name: Deploy Unix socket configuration updates
hosts: arch-vps
become: yes
tasks:
- name: Display deployment plan
debug:
msg: |
🔧 Unix Socket Migration Plan
=============================
📦 Services to Update:
1. PostgreSQL - Switch to socket-only (no TCP)
2. Valkey - Add Unix socket support
3. Authentik - Use sockets for DB/cache
4. Gitea - Use sockets for DB/cache
🔒 Security Benefits:
- Zero network exposure for databases
- Better performance (25-30% faster)
- Simplified security model
- name: Update PostgreSQL to socket-only
include_role:
name: postgresql
tags: [postgresql]
- name: Update Valkey with Unix socket
include_role:
name: valkey
tags: [valkey]
- name: Update Authentik for Unix sockets
include_role:
name: authentik
tags: [authentik]
- name: Update Gitea for Unix sockets
include_role:
name: gitea
tags: [gitea]
- name: Verify socket files exist
stat:
path: "{{ item }}"
loop:
- /run/postgresql/.s.PGSQL.5432
- /run/valkey/valkey.sock
register: socket_checks
- name: Display results
debug:
msg: |
✅ Deployment Complete!
Socket Status:
{% for check in socket_checks.results %}
- {{ check.item }}: {{ "EXISTS" if check.stat.exists else "MISSING" }}
{% endfor %}
Next Steps:
1. Check service logs: journalctl -u authentik-pod
2. Test Authentik: curl http://arch-vps:9000/if/flow/initial-setup/
3. Test Gitea: curl http://arch-vps:3000/

View File

@@ -1127,3 +1127,120 @@ curl -I http://127.0.0.1:9000/
3. **Hardcoded GIDs** - Rejected for portability; facts provide dynamic resolution 3. **Hardcoded GIDs** - Rejected for portability; facts provide dynamic resolution
4. **Directory permissions (777)** - Rejected for security; group-based access more restrictive. This is then later changed again to 777, due to Nextcloud switching from root to www-data, breaking group-based permissions. 4. **Directory permissions (777)** - Rejected for security; group-based access more restrictive. This is then later changed again to 777, due to Nextcloud switching from root to www-data, breaking group-based permissions.
--- ---
---
## ADR-007: Multi-Environment Infrastructure Architecture
**Date**: December 2025
**Status**: Accepted
**Context**: Separation of homelab services from production client projects
### Decision
Rick-infra will manage two separate environments with different purposes and uptime requirements:
1. **Homelab Environment** (arch-vps)
- Purpose: Personal services and experimentation
- Infrastructure: Full stack (PostgreSQL, Valkey, Podman, Caddy)
- Services: Authentik, Nextcloud, Gitea
- Uptime requirement: Best effort
2. **Production Environment** (mini-vps)
- Purpose: Client projects requiring high uptime
- Infrastructure: Minimal (Caddy only)
- Services: Sigvild Gallery
- Uptime requirement: High availability
### Rationale
**Separation of Concerns**:
- Personal experiments don't affect client services
- Client services isolated from homelab maintenance
- Clear distinction between environments in code
**Infrastructure Optimization**:
- Production runs minimal services (no PostgreSQL/Valkey overhead)
- Homelab can be rebooted/upgraded without affecting clients
- Cost optimization: smaller VPS for production
**Operational Flexibility**:
- Different backup strategies per environment
- Different monitoring/alerting levels
- Independent deployment schedules
### Implementation
**Variable Organization**:
```
rick-infra/
├── group_vars/
│ └── production/ # Production environment config
│ ├── main.yml
│ └── vault.yml
├── host_vars/
│ └── arch-vps/ # Homelab host config
│ ├── main.yml
│ └── vault.yml
└── playbooks/
├── homelab.yml # Homelab deployment
├── production.yml # Production deployment
└── site.yml # Orchestrates both
```
**Playbook Structure**:
- `site.yml` imports both homelab.yml and production.yml
- Each playbook manually loads variables (Ansible 2.20 workaround)
- Services deploy only to their designated environment
**Inventory Groups**:
```yaml
homelab:
hosts:
arch-vps:
ansible_host: 69.62.119.31
production:
hosts:
mini-vps:
ansible_host: 72.62.91.251
```
### Migration Example
**Sigvild Gallery Migration** (December 2025):
- **From**: arch-vps (homelab)
- **To**: mini-vps (production)
- **Reason**: Client project requiring higher uptime
- **Process**:
1. Created backup on arch-vps
2. Deployed to mini-vps with automatic restore
3. Updated DNS (5 min downtime)
4. Removed from arch-vps configuration
### Consequences
**Positive**:
- Clear separation of personal vs. client services
- Reduced blast radius for experiments
- Optimized resource usage per environment
- Independent scaling and management
**Negative**:
- Increased complexity in playbook organization
- Need to manage multiple VPS instances
- Ansible 2.20 variable loading requires workarounds
- Duplicate infrastructure code (Caddy on both)
**Neutral**:
- Services can be migrated between environments with minimal friction
- Backup/restore procedures work across environments
- Group_vars vs. host_vars hybrid approach
### Future Considerations
- Consider grouping multiple client projects on production VPS
- Evaluate if homelab needs full infrastructure stack
- Monitor for opportunities to share infrastructure between environments
- Document migration procedures for moving services between environments
---

View File

@@ -43,21 +43,45 @@ The rick-infra deployment system provides:
└─────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────┘
``` ```
## Infrastructure Overview
Rick-infra now manages **two separate environments**:
### Homelab (arch-vps)
Personal services and experimentation platform at **jnss.me**:
- PostgreSQL, Valkey, Podman infrastructure
- Caddy reverse proxy with auto-HTTPS
- Nextcloud (cloud.jnss.me)
- Authentik SSO (auth.jnss.me)
- Gitea (git.jnss.me)
### Production (mini-vps)
Client projects requiring high uptime:
- Caddy reverse proxy with auto-HTTPS
- Sigvild Gallery (sigvild.no, api.sigvild.no)
## Available Deployments ## Available Deployments
### 1. `site.yml` - Complete Infrastructure Stack ### 1. `site.yml` - Deploy All Environments
Deploys the full rick-infra stack with role dependencies automatically managed. Deploys both homelab and production infrastructure.
```bash ```bash
ansible-playbook -i inventory/hosts.yml site.yml --ask-vault-pass ansible-playbook site.yml --ask-vault-pass
``` ```
**What it deploys:** ### 2. Environment-Specific Deployments
- **Security Foundation**: SSH hardening, firewall, fail2ban, system updates
- **Infrastructure Services**: PostgreSQL, Valkey, Podman container runtime ```bash
- **Reverse Proxy**: Caddy with automatic HTTPS and Cloudflare DNS integration # Deploy only homelab services
- **Authentication**: Authentik SSO server with forward auth integration ansible-playbook playbooks/homelab.yml --ask-vault-pass
- **Applications**: Gitea, Gallery, and other configured services
# Deploy only production services
ansible-playbook playbooks/production.yml --ask-vault-pass
# Or use site.yml with limits
ansible-playbook site.yml -l homelab --ask-vault-pass
ansible-playbook site.yml -l production --ask-vault-pass
```
### 2. Service-Specific Deployments ### 2. Service-Specific Deployments
Deploy individual components using tags: Deploy individual components using tags:
@@ -193,7 +217,21 @@ For complete authentik architecture details, see [Architecture Decisions](archit
## Configuration Management ## Configuration Management
### Host Variables ### Variable Organization
Rick-infra uses a hybrid approach for variable management:
**Group Variables** (`group_vars/`):
- `production/main.yml` - Production environment configuration
- `production/vault.yml` - Production secrets (encrypted)
**Host Variables** (`host_vars/`):
- `arch-vps/main.yml` - Homelab configuration
- `arch-vps/vault.yml` - Homelab secrets (encrypted)
**Note:** Due to variable loading issues in Ansible 2.20, playbooks manually load variables using `include_vars`. This ensures reliable variable resolution during execution.
### Example: Homelab Configuration
Core infrastructure settings in `host_vars/arch-vps/main.yml`: Core infrastructure settings in `host_vars/arch-vps/main.yml`:

View File

@@ -1,39 +1,50 @@
# Sigvild Gallery Deployment Guide # Sigvild Gallery Deployment Guide
## Overview
Sigvild Wedding Gallery is deployed on **mini-vps** (production environment) for high uptime and reliability. The gallery uses PocketBase API backend with SvelteKit frontend.
**Production Host**: mini-vps (72.62.91.251)
**Domains**: sigvild.no (frontend), api.sigvild.no (API)
## Quick Start ## Quick Start
Deploy the complete Sigvild Wedding Gallery with PocketBase API and SvelteKit frontend. Deploy Sigvild Gallery to production:
```bash
ansible-playbook playbooks/production.yml
```
## Prerequisites Setup ## Prerequisites Setup
### 1. Vault Password Configuration ### 1. Vault Password Configuration
Create encrypted passwords for the gallery authentication: Encrypted passwords are stored in `group_vars/production/vault.yml`:
```bash ```bash
# Create vault passwords (run from rick-infra directory) # Edit production vault (run from rick-infra directory)
ansible-vault encrypt_string 'your-host-password-here' --name 'vault_sigvild_host_password' ansible-vault edit group_vars/production/vault.yml
ansible-vault encrypt_string 'your-guest-password-here' --name 'vault_sigvild_guest_password'
``` ```
Add the encrypted strings to `host_vars/arch-vps/main.yml`: Add these variables:
```yaml ```yaml
# Add to host_vars/arch-vps/main.yml # Production vault variables
vault_sigvild_host_password: !vault | vault_cloudflare_api_token: "your-cloudflare-token"
$ANSIBLE_VAULT;1.1;AES256 vault_caddy_tls_email: "admin@example.com"
66386439653765386... vault_sigvild_host_password: "host-user-password"
vault_sigvild_guest_password: "guest-user-password"
vault_sigvild_guest_password: !vault | vault_pb_su_email: "admin@sigvild.no"
$ANSIBLE_VAULT;1.1;AES256 vault_pb_su_password: "admin-password"
33663065383834313...
``` ```
**Note**: Use `ansible-vault encrypt group_vars/production/vault.yml` after editing.
### 2. DNS Configuration ### 2. DNS Configuration
Ensure these domains point to your server: Point these domains to **mini-vps** (72.62.91.251):
- `sigvild.no` → Frontend static site - `sigvild.no` A record → 72.62.91.251
- `api.sigvild.no` → API backend proxy - `api.sigvild.no` A record → 72.62.91.251
### 3. Project Structure ### 3. Project Structure
@@ -50,70 +61,92 @@ Ensure the sigvild-gallery project is adjacent to rick-infra:
## Deployment Commands ## Deployment Commands
### Full Infrastructure + Gallery ### Production Deployment
Deploy everything including Sigvild Gallery: Deploy to production environment (mini-vps):
```bash ```bash
ansible-playbook site.yml # Deploy complete production stack (Caddy + Sigvild Gallery)
``` ansible-playbook playbooks/production.yml
### Gallery Only # Or deploy everything with production limit
ansible-playbook site.yml -l production
Deploy just the Sigvild Gallery service:
```bash
ansible-playbook playbooks/deploy-sigvild.yml
``` ```
### Selective Updates ### Selective Updates
Update specific components: Update specific components using tags:
```bash ```bash
# Frontend only (quick static file updates) # Frontend only (quick static file updates)
ansible-playbook site.yml --tags="frontend" ansible-playbook playbooks/production.yml --tags="frontend"
# Backend only (API service updates) # Backend only (API service updates)
ansible-playbook site.yml --tags="backend" ansible-playbook playbooks/production.yml --tags="backend"
# Caddy configuration only # Caddy configuration only
ansible-playbook site.yml --tags="caddy" ansible-playbook playbooks/production.yml --tags="caddy"
# Just build process (development) # Just build process (development)
ansible-playbook site.yml --tags="build" ansible-playbook playbooks/production.yml --tags="build"
``` ```
### Backup and Restore
Create backups before major changes:
```bash
# Create backup (works on any host running sigvild-gallery)
ansible-playbook playbooks/backup-sigvild.yml -l mini-vps
# Backup is saved to: ~/sigvild-gallery-backup/
```
**Automatic Restore**: When deploying to a fresh server, the role automatically detects and restores from the latest backup if available.
## Architecture Overview ## Architecture Overview
**Production Environment**: mini-vps (72.62.91.251)
``` ```
Internet Internet
Caddy (Auto HTTPS) Cloudflare DNS → mini-vps
Caddy (Auto HTTPS with DNS Challenge)
├── sigvild.no → /var/www/sigvild-gallery/ (Static Files) ├── sigvild.no → /var/www/sigvild-gallery/ (Static Files)
└── api.sigvild.no → localhost:8090 (PocketBase API) └── api.sigvild.no → localhost:8090 (PocketBase API)
Go Binary (sigvild-gallery-server) Go Binary (/opt/sigvild-gallery/sigvild-gallery)
SQLite Database + File Storage SQLite Database (/opt/sigvild-gallery/pb_data/)
└── File Storage (wedding photos)
``` ```
**Key Features**:
- Automatic HTTPS with Let's Encrypt
- Cloudflare DNS challenge for certificate validation
- Security headers and CORS protection
- SystemD service management
- Automatic backup/restore capability
## Service Management ## Service Management
### Status Checks ### Status Checks
```bash ```bash
# Gallery API service # Check services on mini-vps
systemctl status sigvild-gallery ansible mini-vps -a "systemctl status sigvild-gallery"
ansible mini-vps -a "systemctl status caddy"
# Caddy web server
systemctl status caddy
# View gallery logs # View gallery logs
journalctl -u sigvild-gallery -f ansible mini-vps -a "journalctl -u sigvild-gallery -n 50 --no-pager"
# View Caddy logs # View Caddy logs
journalctl -u caddy -f ansible mini-vps -a "journalctl -u caddy -n 20 --no-pager"
# Check data directory
ansible mini-vps -a "ls -lh /opt/sigvild-gallery/pb_data/"
``` ```
### Manual Operations ### Manual Operations
@@ -216,23 +249,30 @@ journalctl -u caddy | grep -i "acme\|certificate"
- **CORS restrictions**: API access limited to frontend domain - **CORS restrictions**: API access limited to frontend domain
- **Rate limiting**: API endpoint protection - **Rate limiting**: API endpoint protection
## File Locations ## File Locations (on mini-vps)
### Application Files ### Application Files
- **Binary**: `/opt/sigvild-gallery/sigvild-gallery-server` - **Binary**: `/opt/sigvild-gallery/sigvild-gallery`
- **Database**: `/opt/sigvild-gallery/data/data.db` - **Database**: `/opt/sigvild-gallery/pb_data/data.db`
- **File uploads**: `/opt/sigvild-gallery/data/storage/` - **File uploads**: `/opt/sigvild-gallery/pb_data/storage/`
- **Frontend**: `/var/www/sigvild-gallery/` - **Frontend**: `/var/www/sigvild-gallery/`
- **User/Group**: `sigvild:sigvild`
### Configuration Files ### Configuration Files
- **Service**: `/etc/systemd/system/sigvild-gallery.service` - **Service**: `/etc/systemd/system/sigvild-gallery.service`
- **Caddy frontend**: `/etc/caddy/sites-enabled/sigvild-frontend.caddy` - **Caddy frontend**: `/etc/caddy/sites-enabled/sigvild-frontend.caddy`
- **Caddy API**: `/etc/caddy/sites-enabled/sigvild-api.caddy` - **Caddy API**: `/etc/caddy/sites-enabled/sigvild-api.caddy`
### Local Files (on control machine)
- **Configuration**: `group_vars/production/main.yml`
- **Secrets**: `group_vars/production/vault.yml` (encrypted)
- **Backups**: `~/sigvild-gallery-backup/`
- **Source code**: `~/sigvild-gallery/`
### Log Files ### Log Files
- **Service logs**: `journalctl -u sigvild-gallery` - **Service logs**: `journalctl -u sigvild-gallery`
- **Caddy logs**: `journalctl -u caddy` - **Caddy logs**: `journalctl -u caddy`
- **Access logs**: `/var/log/caddy/sigvild-*.log` - **Access logs**: `/var/log/caddy/access.log`
## Next Steps After Deployment ## Next Steps After Deployment
@@ -248,15 +288,28 @@ For ongoing development:
```bash ```bash
# 1. Make changes to sigvild-gallery project # 1. Make changes to sigvild-gallery project
cd ../sigvild-gallery cd ~/sigvild-gallery
# 2. Test locally # 2. Test locally
go run . serve & go run . serve &
cd sigvild-kit && npm run dev cd sigvild-kit && npm run dev
# 3. Deploy updates # 3. Deploy updates to production
cd ../rick-infra cd ~/rick-infra
ansible-playbook site.yml --tags="sigvild" ansible-playbook playbooks/production.yml --tags="sigvild"
``` ```
The deployment system builds locally and transfers assets, so you don't need build tools on the server. **Build Process**:
- Backend: Built locally with `GOOS=linux GOARCH=amd64 go build`
- Frontend: Built locally with `npm run build` in sigvild-kit/
- Assets transferred to mini-vps via Ansible
- No build tools required on the server
## Migration History
**December 2025**: Migrated from arch-vps (homelab) to mini-vps (production)
- **Reason**: Client project requiring higher uptime reliability
- **Method**: Backup from arch-vps, automatic restore to mini-vps
- **Downtime**: ~5 minutes during DNS propagation
- **Previous host**: arch-vps (69.62.119.31)
- **Current host**: mini-vps (72.62.91.251)

View File

@@ -0,0 +1,52 @@
---
# =================================================================
# Production Configuration for mini-vps (Client Projects)
# =================================================================
# This host runs production services requiring high uptime
# Currently hosting: Sigvild Gallery
# =================================================================
# TLS Configuration - Production Setup
# =================================================================
caddy_tls_enabled: true
caddy_domain: "health.sigvild.no"
caddy_tls_email: "{{ vault_caddy_tls_email }}"
# DNS Challenge Configuration (Cloudflare)
caddy_dns_provider: "cloudflare"
cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
# Production Let's Encrypt CA
caddy_acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
# =================================================================
# API Service Registration Configuration
# =================================================================
# Services now self-register using Caddy's admin API
caddy_api_enabled: true
caddy_server_name: "main"
# =================================================================
# Sigvild Gallery Configuration
# =================================================================
sigvild_gallery_frontend_domain: "sigvild.no"
sigvild_gallery_api_domain: "api.sigvild.no"
sigvild_gallery_local_project_path: "{{ lookup('env', 'HOME') }}/sigvild-gallery/"
# Backup configuration
sigvild_gallery_backup_enabled: true
sigvild_gallery_backup_local_path: "{{ lookup('env', 'HOME') }}/sigvild-gallery-backup/"
# Vault-encrypted passwords (create with ansible-vault)
sigvild_gallery_pb_su_email: "{{ vault_pb_su_email}}"
sigvild_gallery_pb_su_password: "{{ vault_pb_su_password}}"
sigvild_gallery_host_password: "{{ vault_sigvild_host_password }}"
sigvild_gallery_guest_password: "{{ vault_sigvild_guest_password }}"
# =================================================================
# Security & Logging
# =================================================================
caddy_log_level: "INFO"
caddy_log_format: "json"
caddy_systemd_security: true

View File

@@ -24,24 +24,6 @@ caddy_acme_ca: "https://acme-v02.api.letsencrypt.org/directory"
caddy_api_enabled: true caddy_api_enabled: true
caddy_server_name: "main" caddy_server_name: "main"
# =================================================================
# Sigvild Gallery Configuration
# =================================================================
sigvild_gallery_frontend_domain: "sigvild.no"
sigvild_gallery_api_domain: "api.sigvild.no"
sigvild_gallery_local_project_path: "~/sigvild-gallery/"
# Backup configuration
sigvild_gallery_backup_enabled: true
sigvild_gallery_backup_local_path: "~/sigvild-gallery-backup/"
# Vault-encrypted passwords (create with ansible-vault)
sigvild_gallery_pb_su_email: "{{ vault_pb_su_email}}"
sigvild_gallery_pb_su_password: "{{ vault_pb_su_password}}"
sigvild_gallery_host_password: "{{ vault_sigvild_host_password }}"
sigvild_gallery_guest_password: "{{ vault_sigvild_guest_password }}"
# ================================================================= # =================================================================
# Authentik Configuration # Authentik Configuration
# ================================================================= # =================================================================

View File

View File

@@ -1,11 +1,15 @@
--- ---
all: homelab:
children: hosts:
production: arch-vps:
hosts: ansible_host: 69.62.119.31
arch-vps: ansible_user: root
ansible_host: 69.62.119.31 vars:
ansible_user: root ansible_python_interpreter: /usr/bin/python3
production:
hosts:
mini-vps:
ansible_host: 72.62.91.251
ansible_user: root
vars: vars:
ansible_python_interpreter: /usr/bin/python3 ansible_python_interpreter: /usr/bin/python3

25
now-what.md Normal file
View File

@@ -0,0 +1,25 @@
# Now what?
- [ ] Redeploy on clean VPS to test playbook
- [ ] Must set up mini-vps for sigvild and devigo
- [ ] What gets served on jnss.me?
- [ ] Backups
- [ ] Configure and set up Nextcloud
- [ ] OAuth
- [ ] Settings
- [ ] Contacts and calendars
- [ ] Storage bucket integration?
- [ ] Gitea
- [ ] SSH setup
- [ ] Authentik Invitations for users?
- [ ] Sail the high seas
- [ ] Set up Jellyfin
- [ ] Set up *arr applications
- [ ] "Blog post"

View File

@@ -0,0 +1,24 @@
---
# Sigvild Gallery Data Backup Playbook
#
# This playbook creates a backup of the Sigvild Gallery data including:
# - PocketBase SQLite database (data.db, auxiliary.db)
# - All uploaded wedding photos and media files
# - PocketBase logs and system state
#
# Usage:
# ansible-playbook playbooks/backup-sigvild.yml -l arch-vps
# ansible-playbook playbooks/backup-sigvild.yml -l mini-vps
#
# Backup location: ~/sigvild-gallery-backup/sigvild-gallery-backup-YYYYMMDDTHHMMSS.tar.gz
- name: Backup Sigvild Gallery Data
hosts: all
become: true
gather_facts: true
tasks:
- name: Run backup tasks from sigvild-gallery role
include_role:
name: sigvild-gallery
tasks_from: backup.yml

64
playbooks/homelab.yml Normal file
View File

@@ -0,0 +1,64 @@
---
# Homelab Infrastructure Deployment
#
# Deploys personal homelab services to arch-vps including:
# - PostgreSQL database
# - Valkey cache/session store
# - Podman container runtime
# - Caddy web server
# - Nextcloud cloud storage
# - Authentik SSO/authentication
# - Gitea git hosting
#
# Usage:
# ansible-playbook playbooks/homelab.yml
- name: Deploy Homelab Infrastructure
hosts: homelab
become: true
gather_facts: true
tasks:
# Workaround: Manually load host_vars due to Ansible 2.20 variable loading issue
- name: Load homelab host variables
include_vars:
dir: "{{ playbook_dir }}/../host_vars/{{ inventory_hostname }}"
extensions: ['yml']
tags: always
# Deploy infrastructure services
- name: Deploy PostgreSQL
include_role:
name: postgresql
tags: ['postgresql', 'infrastructure', 'database']
- name: Deploy Valkey
include_role:
name: valkey
tags: ['valkey', 'redis', 'infrastructure', 'cache']
- name: Deploy Podman
include_role:
name: podman
tags: ['podman', 'containers', 'infrastructure']
- name: Deploy Caddy
include_role:
name: caddy
tags: ['caddy', 'infrastructure', 'web']
# Deploy application services
- name: Deploy Nextcloud
include_role:
name: nextcloud
tags: ['nextcloud', 'cloud', 'storage']
- name: Deploy Authentik
include_role:
name: authentik
tags: ['authentik', 'sso', 'auth']
- name: Deploy Gitea
include_role:
name: gitea
tags: ['gitea', 'git', 'development']

29
playbooks/production.yml Normal file
View File

@@ -0,0 +1,29 @@
---
# Production Services Deployment
#
# Deploys production services requiring high uptime to mini-vps including:
# - Caddy web server
# - Sigvild Gallery (wedding photo gallery)
#
# Usage:
# ansible-playbook playbooks/production.yml
# - import_playbook: security.yml
- name: Deploy Production Services
hosts: production
become: true
gather_facts: true
tasks:
# Workaround: Manually load group_vars due to Ansible 2.20 variable loading issue
- name: Load production group variables
include_vars:
dir: "{{ playbook_dir }}/../group_vars/production"
extensions: ['yml']
tags: always
- name: Deploy Sigvild Gallery
include_role:
name: sigvild-gallery
tags: ['sigvild', 'gallery', 'wedding']

View File

@@ -1,7 +1,7 @@
--- ---
- name: Check if DNS challenge is needed - name: Check if DNS challenge is needed
set_fact: set_fact:
dns_challenge_needed: "{{ caddy_dns_provider == 'cloudflare' and cloudflare_api_token != '' }}" dns_challenge_needed: "{{ caddy_dns_provider == 'cloudflare' }}"
- name: Check if Caddy is already installed - name: Check if Caddy is already installed
command: /usr/bin/caddy version command: /usr/bin/caddy version

View File

@@ -25,7 +25,7 @@ sigvild_gallery_guest_username: guest
sigvild_gallery_guest_password: "{{ vault_sigvild_guest_password }}" sigvild_gallery_guest_password: "{{ vault_sigvild_guest_password }}"
# Build configuration # Build configuration
sigvild_gallery_local_project_path: "{{ ansible_env.PWD }}/sigvild-gallery" sigvild_gallery_local_project_path: "{{ lookup('env', 'HOME') }}/sigvild-gallery"
# Service configuration # Service configuration
sigvild_gallery_service_enabled: true sigvild_gallery_service_enabled: true
@@ -33,7 +33,7 @@ sigvild_gallery_service_state: started
# Backup configuration # Backup configuration
sigvild_gallery_backup_enabled: true sigvild_gallery_backup_enabled: true
sigvild_gallery_backup_local_path: "{{ playbook_dir }}/backups/sigvild-gallery" sigvild_gallery_backup_local_path: "{{ lookup('env', 'HOME') }}/sigvild-gallery-backup/"
# Caddy integration (assumes caddy role provides these) # Caddy integration (assumes caddy role provides these)
# caddy_sites_enabled_dir: /etc/caddy/sites-enabled # caddy_sites_enabled_dir: /etc/caddy/sites-enabled

View File

@@ -33,11 +33,7 @@
notify: restart sigvild-gallery notify: restart sigvild-gallery
tags: [backend] tags: [backend]
- name: Restore data from backup if available - name: Create data directory for PocketBase (if not created by restore)
include_tasks: restore.yml
tags: [backend, restore]
- name: Create data directory for PocketBase
file: file:
path: "{{ sigvild_gallery_data_dir }}" path: "{{ sigvild_gallery_data_dir }}"
state: directory state: directory

View File

@@ -14,7 +14,7 @@
home: "{{ sigvild_gallery_home }}" home: "{{ sigvild_gallery_home }}"
create_home: yes create_home: yes
- name: Create directories - name: Create directories (excluding pb_data, created later)
file: file:
path: "{{ item }}" path: "{{ item }}"
state: directory state: directory
@@ -23,7 +23,6 @@
mode: '0755' mode: '0755'
loop: loop:
- "{{ sigvild_gallery_home }}" - "{{ sigvild_gallery_home }}"
- "{{ sigvild_gallery_data_dir }}"
- "{{ sigvild_gallery_web_root }}" - "{{ sigvild_gallery_web_root }}"
- name: Check for existing gallery data - name: Check for existing gallery data

View File

@@ -1,29 +1,22 @@
--- ---
# Security hardening establishes secure foundation before web services # Main Site Deployment Playbook
#
# This playbook orchestrates deployment across all hosts:
# - Homelab (arch-vps): Personal services and experimentation
# - Production (mini-vps): Client projects requiring high uptime
#
# Usage:
# ansible-playbook site.yml # Deploy everything
# ansible-playbook site.yml -l homelab # Deploy only homelab
# ansible-playbook site.yml -l production # Deploy only production
# ansible-playbook site.yml --tags caddy # Deploy Caddy everywhere
# Security hardening playbook (optional, currently commented out)
# Establishes secure foundation before web services
# - import_playbook: playbooks/security.yml # - import_playbook: playbooks/security.yml
- name: Deploy Core Infrastructure # Deploy homelab infrastructure on arch-vps
hosts: arch-vps - import_playbook: playbooks/homelab.yml
become: true
gather_facts: true # Deploy production services on mini-vps
- import_playbook: playbooks/production.yml
roles:
# Infrastructure services
# - role: postgresql
# tags: ['postgresql', 'infrastructure', 'database']
# - role: valkey
# tags: ['valkey', 'redis', 'infrastructure', 'cache']
# - role: podman
# tags: ['podman', 'containers', 'infrastructure']
# - role: caddy
# tags: ['caddy', 'infrastructure', 'web']
# Application services
# - role: sigvild-gallery
# tags: ['sigvild', 'gallery', 'wedding']
# - role: gitea
# tags: ['gitea', 'git', 'development']
- role: nextcloud
tags: ['nextcloud']
# - role: authentik
# tags: ['authentik']