feat: add comprehensive framework features and deployment improvements
Major additions: - Storage abstraction layer with filesystem and in-memory implementations - Gitea API integration with MCP tools for repository management - Console dialog mode with interactive command execution - WireGuard VPN DNS fix implementation and documentation - HTTP client streaming response support - Router generic result type - Parameter type validator for framework core Framework enhancements: - Console command registry improvements - Console dialog components - Method signature analyzer updates - Route mapper refinements - MCP server and tool mapper updates - Queue job chain and dependency commands - Discovery tokenizer improvements Infrastructure: - Deployment architecture documentation - Ansible playbook updates for WireGuard client regeneration - Production environment configuration updates - Docker Compose local configuration updates - Remove obsolete docker-compose.yml (replaced by environment-specific configs) Documentation: - PERMISSIONS.md for access control guidelines - WireGuard DNS fix implementation details - Console dialog mode usage guide - Deployment architecture overview Testing: - Multi-purpose attribute tests - Gitea Actions integration tests (typed and untyped)
This commit is contained in:
226
docs/PERMISSIONS.md
Normal file
226
docs/PERMISSIONS.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Storage Permissions Management
|
||||
|
||||
## Problem
|
||||
|
||||
Docker containers laufen standardmäßig als `root` und erstellen Files/Directories mit root-Ownership.
|
||||
Beim Zugriff vom Host aus (z.B. `console.php` direkt) gibt es dann Permission-Probleme.
|
||||
|
||||
## Implementierte Lösungen
|
||||
|
||||
### 1. Docker-Wrapper Script ⭐ (EMPFOHLEN)
|
||||
|
||||
**Location**: `./bin/console`
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
# Direkt ausführen
|
||||
./bin/console
|
||||
./bin/console routes:list
|
||||
./bin/console db:migrate
|
||||
|
||||
# Optional: In PATH aufnehmen
|
||||
export PATH="$PATH:/home/michael/dev/michaelschiemer/bin"
|
||||
console routes:list # Jetzt direkt aufrufbar
|
||||
```
|
||||
|
||||
**Features**:
|
||||
- ✅ Läuft automatisch im PHP-Container
|
||||
- ✅ TTY-Detection (interaktiv/non-interaktiv)
|
||||
- ✅ Keine Permission-Probleme
|
||||
- ✅ Funktioniert in WSL, Linux, macOS
|
||||
|
||||
**Implementation**:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Auto-detect TTY und nutze entsprechende docker exec Flags
|
||||
if [ -t 0 ]; then
|
||||
docker exec -it php php console.php "$@"
|
||||
else
|
||||
docker exec php php console.php "$@"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Container User Configuration ⭐
|
||||
|
||||
**Status**: ✅ Konfiguriert in `docker-compose.local.yml`
|
||||
|
||||
```yaml
|
||||
php:
|
||||
user: "1000:1000" # Läuft als Host-User
|
||||
|
||||
queue-worker:
|
||||
user: "1000:1000" # Konsistent
|
||||
|
||||
php-test:
|
||||
user: "1000:1000" # Konsistent
|
||||
```
|
||||
|
||||
**Vorteile**:
|
||||
- Container erstellt keine root-Files mehr
|
||||
- Konsistente Permissions über alle Services
|
||||
- Keine sudo-Rechte für Storage-Zugriffe nötig
|
||||
|
||||
**Einmalige Permissions-Korrektur**:
|
||||
```bash
|
||||
# Via Makefile (empfohlen)
|
||||
make fix-perms
|
||||
|
||||
# Oder manuell
|
||||
sudo chown -R $(id -u):$(id -g) storage/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Git Hooks (Automatisch) ⭐
|
||||
|
||||
**Location**:
|
||||
- `.git/hooks/post-checkout`
|
||||
- `.git/hooks/post-merge`
|
||||
|
||||
**Funktion**:
|
||||
Automatische Permissions-Korrektur nach `git checkout` oder `git pull`
|
||||
|
||||
**Implementation**:
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Prüfe ob storage-Directories root gehören
|
||||
if find storage -user root 2>/dev/null | grep -q .; then
|
||||
echo "🔧 Fixing storage permissions..."
|
||||
sudo chown -R $(id -u):$(id -g) storage/
|
||||
fi
|
||||
```
|
||||
|
||||
**Wann ausgeführt**:
|
||||
- Nach `git checkout <branch>`
|
||||
- Nach `git pull`
|
||||
- Nach `git merge`
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: "Permission denied for create directory"
|
||||
|
||||
**Symptom**:
|
||||
```
|
||||
Fehler: Permission denied for create directory on file: /home/michael/dev/michaelschiemer/storage/queue/priority
|
||||
Parent directory: /home/michael/dev/michaelschiemer/storage/queue (owner: root, group: root, writable: no)
|
||||
```
|
||||
|
||||
**Lösung 1** (Sofort):
|
||||
```bash
|
||||
make fix-perms
|
||||
```
|
||||
|
||||
**Lösung 2** (Dauerhaft - Container verwenden):
|
||||
```bash
|
||||
./bin/console # Statt: php console.php
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Problem: Console-Command vom Host aus
|
||||
|
||||
**❌ Falsch**:
|
||||
```bash
|
||||
php console.php # Verwendet Host-PHP, hat keine Container-Permissions
|
||||
console # Alias existiert nicht
|
||||
```
|
||||
|
||||
**✅ Richtig**:
|
||||
```bash
|
||||
./bin/console # Docker-Wrapper Script
|
||||
docker exec php php console.php # Direkt im Container
|
||||
make console ARGS="command" # Via Makefile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Problem: Git Hook fragt nach sudo-Password
|
||||
|
||||
**Erklärung**:
|
||||
Hook versucht automatisch permissions zu fixen, benötigt sudo für chown.
|
||||
|
||||
**Optionen**:
|
||||
1. **Password eingeben** - Hook korrigiert automatisch
|
||||
2. **Abbrechen** - Später manuell `make fix-perms` ausführen
|
||||
3. **Sudo-less chown** (advanced):
|
||||
```bash
|
||||
# In /etc/sudoers.d/storage-permissions
|
||||
michael ALL=(ALL) NOPASSWD: /usr/bin/chown -R * /home/michael/dev/michaelschiemer/storage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Development Workflow
|
||||
|
||||
```bash
|
||||
# 1. Container starten
|
||||
make up
|
||||
|
||||
# 2. Console Commands im Container ausführen
|
||||
./bin/console routes:list
|
||||
./bin/console db:migrate
|
||||
|
||||
# 3. Bei Permission-Problemen
|
||||
make fix-perms
|
||||
|
||||
# 4. Container neu starten (bei Config-Änderungen)
|
||||
make restart
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
|
||||
- **KEINE** Container-User-Config in Production
|
||||
- Storage-Directories gehören `www-data` User
|
||||
- Container laufen als `www-data` (uid/gid in Dockerfile gesetzt)
|
||||
- Keine Host-Mounts (nur Docker Volumes)
|
||||
|
||||
---
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Permissions Check
|
||||
|
||||
```bash
|
||||
# Check storage permissions
|
||||
ls -la storage/
|
||||
|
||||
# Find root-owned files
|
||||
find storage -user root
|
||||
|
||||
# Fix all at once
|
||||
make fix-perms
|
||||
```
|
||||
|
||||
### Git Hooks Update
|
||||
|
||||
```bash
|
||||
# Check if hooks are installed
|
||||
ls -la .git/hooks/post-*
|
||||
|
||||
# Test hook manually
|
||||
.git/hooks/post-checkout
|
||||
|
||||
# Remove hooks (disable auto-fix)
|
||||
rm .git/hooks/post-checkout .git/hooks/post-merge
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Empfohlener Workflow**:
|
||||
1. ✅ Verwende `./bin/console` für Console-Commands
|
||||
2. ✅ Container laufen als User 1000:1000 (development)
|
||||
3. ✅ Git Hooks korrigieren automatisch nach pull/checkout
|
||||
4. ✅ Bei Problemen: `make fix-perms`
|
||||
|
||||
**Vermeiden**:
|
||||
- ❌ `php console.php` vom Host aus
|
||||
- ❌ Console-Commands außerhalb des Containers
|
||||
- ❌ Manuelle chown-Befehle (verwende `make fix-perms`)
|
||||
777
docs/claude/deployment-architecture.md
Normal file
777
docs/claude/deployment-architecture.md
Normal file
@@ -0,0 +1,777 @@
|
||||
# Deployment Architecture
|
||||
|
||||
Comprehensive documentation of the deployment infrastructure for the Custom PHP Framework.
|
||||
|
||||
## Overview
|
||||
|
||||
The project uses a sophisticated multi-layered deployment approach:
|
||||
|
||||
- **Local Development**: Docker Compose with Base+Override pattern
|
||||
- **Production**: Ansible-orchestrated deployment of separate Docker stacks
|
||||
- **CI/CD**: Gitea Actions triggering Ansible playbooks
|
||||
- **Infrastructure**: Modular service stacks (Traefik, PostgreSQL, Registry, Gitea, Monitoring, WireGuard)
|
||||
|
||||
**Deployment Status**: ~95% complete (Infrastructure and Application stacks complete, CI/CD pipeline configured but not tested)
|
||||
|
||||
---
|
||||
|
||||
## Docker Compose Architecture
|
||||
|
||||
### Base+Override Pattern
|
||||
|
||||
The project uses a modern Base+Override pattern instead of a monolithic docker-compose.yml:
|
||||
|
||||
```
|
||||
docker-compose.base.yml # Shared service definitions
|
||||
docker-compose.local.yml # Local development overrides
|
||||
docker-compose.staging.yml # Staging environment overrides
|
||||
docker-compose.production.yml # Production environment overrides
|
||||
```
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
# Local Development
|
||||
docker compose -f docker-compose.base.yml -f docker-compose.local.yml up
|
||||
|
||||
# Production (via Ansible)
|
||||
docker compose -f docker-compose.base.yml -f docker-compose.production.yml up
|
||||
```
|
||||
|
||||
### Legacy docker-compose.yml
|
||||
|
||||
**⚠️ DEPRECATED**: The root `docker-compose.yml` is marked as DEPRECATED and kept only for backward compatibility during migration.
|
||||
|
||||
**Planned Removal**: Q2 2025
|
||||
|
||||
**DO NOT USE** for new deployments - use Base+Override pattern instead.
|
||||
|
||||
---
|
||||
|
||||
## Production Deployment Configuration
|
||||
|
||||
### docker-compose.production.yml
|
||||
|
||||
Production environment configuration with security hardening:
|
||||
|
||||
**Key Features**:
|
||||
- **Docker Secrets**: Sensitive data managed via Docker Secrets pattern
|
||||
- `DB_PASSWORD_FILE=/run/secrets/db_user_password`
|
||||
- `REDIS_PASSWORD_FILE=/run/secrets/redis_password`
|
||||
- `APP_KEY_FILE=/run/secrets/app_key`
|
||||
- `VAULT_ENCRYPTION_KEY=/run/secrets/vault_encryption_key`
|
||||
|
||||
- **Security Hardening**:
|
||||
- Container starts as root for gosu, drops to www-data
|
||||
- `no-new-privileges:true` security option
|
||||
- Minimal capabilities (ALL dropped, only CHOWN and DAC_OVERRIDE added)
|
||||
- Environment: `APP_ENV=production`, `APP_DEBUG=false`
|
||||
|
||||
- **Services**:
|
||||
- **web** (Nginx): Ports 80/443 exposed, SSL/TLS ready
|
||||
- **php** (PHP-FPM): Application runtime with security constraints
|
||||
- **redis**: Cache with Docker Secrets authentication
|
||||
- **queue-worker**: Background job processing
|
||||
- **scheduler**: Cron-like task scheduling
|
||||
- **certbot**: Automatic SSL certificate management
|
||||
|
||||
**Example Service Configuration**:
|
||||
```yaml
|
||||
php:
|
||||
restart: always
|
||||
user: "root" # Container starts as root for gosu
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
environment:
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
- DB_PASSWORD_FILE=/run/secrets/db_user_password
|
||||
secrets:
|
||||
- db_user_password
|
||||
- redis_password
|
||||
- app_key
|
||||
- vault_encryption_key
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Directory Structure
|
||||
|
||||
```
|
||||
deployment/
|
||||
├── ansible/ # Ansible automation
|
||||
│ ├── playbooks/ # Deployment playbooks
|
||||
│ │ ├── deploy-update.yml # Application deployment/update
|
||||
│ │ ├── rollback.yml # Rollback to previous version
|
||||
│ │ ├── setup-infrastructure.yml # Infrastructure provisioning
|
||||
│ │ └── system-maintenance.yml # System maintenance tasks
|
||||
│ ├── roles/ # Ansible roles
|
||||
│ │ ├── common/ # Common server setup
|
||||
│ │ ├── docker/ # Docker installation
|
||||
│ │ ├── firewall/ # Firewall configuration
|
||||
│ │ ├── monitoring/ # Monitoring setup
|
||||
│ │ ├── postgresql/ # PostgreSQL stack
|
||||
│ │ ├── registry/ # Docker Registry
|
||||
│ │ ├── traefik/ # Traefik reverse proxy
|
||||
│ │ └── wireguard/ # WireGuard VPN
|
||||
│ ├── secrets/ # Ansible Vault encrypted secrets
|
||||
│ ├── templates/ # Configuration templates
|
||||
│ ├── group_vars/ # Group-specific variables
|
||||
│ │ └── production.yml # Production environment config
|
||||
│ ├── host_vars/ # Host-specific variables
|
||||
│ ├── inventory/ # Server inventory
|
||||
│ │ └── production # Production servers
|
||||
│ └── ansible.cfg # Ansible configuration
|
||||
│
|
||||
├── stacks/ # Docker Stack definitions
|
||||
│ ├── traefik/ # Reverse proxy & SSL
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ ├── traefik.yml # Traefik configuration
|
||||
│ │ └── README.md
|
||||
│ ├── postgresql/ # Database stack
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ └── README.md
|
||||
│ ├── registry/ # Docker Registry
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ └── README.md
|
||||
│ ├── gitea/ # Git server & CI/CD
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ └── README.md
|
||||
│ ├── monitoring/ # Prometheus & Grafana
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ ├── prometheus.yml
|
||||
│ │ └── README.md
|
||||
│ ├── wireguard/ # VPN access
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ └── README.md
|
||||
│ └── application/ # Main application
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── README.md
|
||||
│ └── configs/
|
||||
│
|
||||
├── docs/ # Documentation
|
||||
│ ├── guides/ # How-to guides
|
||||
│ │ ├── setup-guide.md # Complete setup walkthrough
|
||||
│ │ └── ...
|
||||
│ ├── status/ # Deployment status
|
||||
│ │ ├── deployment-summary.md
|
||||
│ │ └── ...
|
||||
│ ├── tests/ # Test documentation
|
||||
│ ├── history/ # Historical decisions
|
||||
│ └── reference/ # Reference material
|
||||
│
|
||||
└── .gitea/ # CI/CD workflows
|
||||
└── workflows/
|
||||
└── deploy.yml # Gitea Actions deployment
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ansible Automation
|
||||
|
||||
### Playbook Overview
|
||||
|
||||
**Infrastructure Setup** (`setup-infrastructure.yml`):
|
||||
- Server provisioning and hardening
|
||||
- Docker installation and configuration
|
||||
- Firewall and security setup
|
||||
- Stack deployment (Traefik, PostgreSQL, Registry, Gitea, Monitoring)
|
||||
|
||||
**Application Deployment** (`deploy-update.yml`):
|
||||
- Pull latest code from Git
|
||||
- Build Docker images
|
||||
- Push to private registry
|
||||
- Deploy application stack via docker-compose
|
||||
- Run database migrations
|
||||
- Restart services with zero-downtime
|
||||
|
||||
**Rollback** (`rollback.yml`):
|
||||
- Rollback to previous Docker image tag
|
||||
- Restore database from backup (if needed)
|
||||
- Restart services
|
||||
|
||||
**System Maintenance** (`system-maintenance.yml`):
|
||||
- System updates and security patches
|
||||
- Docker cleanup (unused images, volumes)
|
||||
- Log rotation
|
||||
- Backup tasks
|
||||
|
||||
### Ansible Vault Secrets
|
||||
|
||||
**Encrypted Secrets** in `deployment/ansible/secrets/`:
|
||||
- `production.vault.yml`: Production credentials (DB passwords, API keys, etc.)
|
||||
- `registry.vault.yml`: Docker Registry authentication
|
||||
- `gitea.vault.yml`: Gitea runner tokens and SSH keys
|
||||
|
||||
**Vault Operations**:
|
||||
```bash
|
||||
# Encrypt new file
|
||||
ansible-vault encrypt deployment/ansible/secrets/production.vault.yml
|
||||
|
||||
# Edit encrypted file
|
||||
ansible-vault edit deployment/ansible/secrets/production.vault.yml
|
||||
|
||||
# View encrypted file
|
||||
ansible-vault view deployment/ansible/secrets/production.vault.yml
|
||||
|
||||
# Run playbook with vault
|
||||
ansible-playbook -i inventory/production playbooks/deploy-update.yml --ask-vault-pass
|
||||
```
|
||||
|
||||
### Inventory Configuration
|
||||
|
||||
**Production Inventory** (`inventory/production`):
|
||||
```ini
|
||||
[web_servers]
|
||||
app.michaelschiemer.com ansible_host=YOUR_SERVER_IP ansible_user=deploy
|
||||
|
||||
[db_servers]
|
||||
app.michaelschiemer.com
|
||||
|
||||
[all:vars]
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
```
|
||||
|
||||
**Group Variables** (`group_vars/production.yml`):
|
||||
- Domain configuration
|
||||
- SSL/TLS settings
|
||||
- Docker Registry URL
|
||||
- Application-specific variables
|
||||
- Resource limits (CPU, Memory)
|
||||
|
||||
---
|
||||
|
||||
## Docker Stacks
|
||||
|
||||
### Stack Architecture
|
||||
|
||||
Each service runs as an independent Docker stack for modularity and isolation:
|
||||
|
||||
#### 1. Traefik Stack
|
||||
**Purpose**: Reverse proxy, SSL/TLS termination, Let's Encrypt integration
|
||||
|
||||
**Features**:
|
||||
- Automatic SSL certificate management
|
||||
- HTTP to HTTPS redirection
|
||||
- Load balancing
|
||||
- Service discovery via Docker labels
|
||||
|
||||
**Configuration**: `deployment/stacks/traefik/traefik.yml`
|
||||
|
||||
#### 2. PostgreSQL Stack
|
||||
**Purpose**: Primary database for application
|
||||
|
||||
**Features**:
|
||||
- Automated backups
|
||||
- Connection pooling
|
||||
- Replication support (optional)
|
||||
- Monitoring integration
|
||||
|
||||
**Configuration**: `deployment/stacks/postgresql/docker-compose.yml`
|
||||
|
||||
#### 3. Docker Registry Stack
|
||||
**Purpose**: Private Docker image registry
|
||||
|
||||
**Features**:
|
||||
- Authentication via Basic Auth or LDAP
|
||||
- SSL/TLS encryption
|
||||
- Image scanning (optional)
|
||||
- Integration with CI/CD pipeline
|
||||
|
||||
**Configuration**: `deployment/stacks/registry/docker-compose.yml`
|
||||
|
||||
#### 4. Gitea Stack
|
||||
**Purpose**: Git server and CI/CD platform
|
||||
|
||||
**Features**:
|
||||
- Git repository hosting
|
||||
- Gitea Actions (GitHub Actions compatible)
|
||||
- Gitea Runner for CI/CD execution
|
||||
- Webhook support
|
||||
|
||||
**Configuration**: `deployment/stacks/gitea/docker-compose.yml`
|
||||
|
||||
#### 5. Monitoring Stack
|
||||
**Purpose**: Metrics collection and visualization
|
||||
|
||||
**Features**:
|
||||
- Prometheus for metrics collection
|
||||
- Grafana for visualization
|
||||
- Node Exporter for server metrics
|
||||
- cAdvisor for container metrics
|
||||
- Pre-configured dashboards
|
||||
|
||||
**Configuration**: `deployment/stacks/monitoring/docker-compose.yml`
|
||||
|
||||
#### 6. WireGuard Stack
|
||||
**Purpose**: Secure VPN access to infrastructure
|
||||
|
||||
**Features**:
|
||||
- Encrypted VPN tunnel
|
||||
- Access to internal services
|
||||
- Multi-device support
|
||||
|
||||
**Configuration**: `deployment/stacks/wireguard/docker-compose.yml`
|
||||
|
||||
#### 7. Application Stack
|
||||
**Purpose**: Main PHP application
|
||||
|
||||
**Services**:
|
||||
- **Nginx**: Web server
|
||||
- **PHP-FPM**: PHP application runtime
|
||||
- **Redis**: Cache and session storage
|
||||
- **Queue Worker**: Background job processing
|
||||
- **Scheduler**: Cron-like task scheduling
|
||||
|
||||
**Configuration**: `deployment/stacks/application/docker-compose.yml`
|
||||
|
||||
**Prerequisites**:
|
||||
- Traefik stack running (for routing)
|
||||
- PostgreSQL stack running (database)
|
||||
- Docker Registry access (for image pulls)
|
||||
- DNS configured (A records pointing to server)
|
||||
|
||||
---
|
||||
|
||||
## CI/CD Pipeline
|
||||
|
||||
### Gitea Actions Workflow
|
||||
|
||||
**Workflow File**: `.gitea/workflows/deploy.yml`
|
||||
|
||||
**Trigger Events**:
|
||||
- Push to `main` branch (production deployment)
|
||||
- Push to `staging` branch (staging deployment)
|
||||
- Manual trigger via Gitea UI
|
||||
|
||||
**Workflow Steps**:
|
||||
1. **Checkout Code**: Clone repository
|
||||
2. **Build Docker Image**: Build application Docker image
|
||||
3. **Push to Registry**: Push image to private Docker Registry
|
||||
4. **Run Tests**: Execute test suite (PHPUnit/Pest)
|
||||
5. **Deploy via Ansible**: Trigger Ansible playbook for deployment
|
||||
6. **Health Check**: Verify deployment success
|
||||
7. **Rollback on Failure**: Automatic rollback if health check fails
|
||||
|
||||
**Example Workflow**:
|
||||
```yaml
|
||||
name: Deploy to Production
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
docker build -t registry.michaelschiemer.com/app:${{ github.sha }} .
|
||||
docker push registry.michaelschiemer.com/app:${{ github.sha }}
|
||||
|
||||
- name: Deploy via Ansible
|
||||
run: |
|
||||
ansible-playbook -i deployment/ansible/inventory/production \
|
||||
deployment/ansible/playbooks/deploy-update.yml \
|
||||
--extra-vars "image_tag=${{ github.sha }}" \
|
||||
--vault-password-file=/secrets/vault-password
|
||||
```
|
||||
|
||||
### Gitea Runner Setup
|
||||
|
||||
**Installation** (via Ansible):
|
||||
- Gitea Runner installed on deployment server
|
||||
- Configured with runner token from Gitea
|
||||
- Systemd service for automatic start
|
||||
- Docker-in-Docker (DinD) support for builds
|
||||
|
||||
**Configuration**:
|
||||
```bash
|
||||
# Register runner
|
||||
gitea-runner register \
|
||||
--instance https://gitea.michaelschiemer.com \
|
||||
--token $RUNNER_TOKEN \
|
||||
--name production-runner
|
||||
|
||||
# Start runner
|
||||
systemctl start gitea-runner
|
||||
systemctl enable gitea-runner
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Workflow
|
||||
|
||||
### Phase 1: Initial Setup (One-Time)
|
||||
|
||||
**1.1 Gitea Runner Registration**:
|
||||
```bash
|
||||
# On deployment server
|
||||
ssh deploy@app.michaelschiemer.com
|
||||
|
||||
# Register Gitea Runner
|
||||
gitea-runner register \
|
||||
--instance https://gitea.michaelschiemer.com \
|
||||
--token <RUNNER_TOKEN> \
|
||||
--name production-runner
|
||||
|
||||
# Verify registration
|
||||
gitea-runner list
|
||||
```
|
||||
|
||||
**1.2 Ansible Vault Setup**:
|
||||
```bash
|
||||
# Create vault password file
|
||||
echo "your-vault-password" > ~/.ansible/vault-password
|
||||
chmod 600 ~/.ansible/vault-password
|
||||
|
||||
# Encrypt production secrets
|
||||
cd deployment/ansible/secrets
|
||||
ansible-vault create production.vault.yml
|
||||
ansible-vault create registry.vault.yml
|
||||
ansible-vault create gitea.vault.yml
|
||||
```
|
||||
|
||||
**1.3 Server Provisioning**:
|
||||
```bash
|
||||
# Run infrastructure setup playbook
|
||||
cd deployment/ansible
|
||||
ansible-playbook -i inventory/production \
|
||||
playbooks/setup-infrastructure.yml \
|
||||
--vault-password-file ~/.ansible/vault-password
|
||||
```
|
||||
|
||||
This provisions:
|
||||
- Docker installation
|
||||
- Firewall configuration
|
||||
- All infrastructure stacks (Traefik, PostgreSQL, Registry, Gitea, Monitoring, WireGuard)
|
||||
|
||||
### Phase 2: Application Deployment (Repeatable)
|
||||
|
||||
**2.1 Manual Deployment** (via Ansible):
|
||||
```bash
|
||||
# Deploy/Update application
|
||||
cd deployment/ansible
|
||||
ansible-playbook -i inventory/production \
|
||||
playbooks/deploy-update.yml \
|
||||
--vault-password-file ~/.ansible/vault-password \
|
||||
--extra-vars "image_tag=latest"
|
||||
```
|
||||
|
||||
**2.2 Automated Deployment** (via CI/CD):
|
||||
```bash
|
||||
# Push to main branch triggers automatic deployment
|
||||
git push origin main
|
||||
|
||||
# Or trigger manually via Gitea UI
|
||||
# Repository → Actions → Deploy to Production → Run Workflow
|
||||
```
|
||||
|
||||
### Phase 3: Rollback (If Needed)
|
||||
|
||||
```bash
|
||||
# Rollback to previous version
|
||||
cd deployment/ansible
|
||||
ansible-playbook -i inventory/production \
|
||||
playbooks/rollback.yml \
|
||||
--vault-password-file ~/.ansible/vault-password \
|
||||
--extra-vars "rollback_version=v1.2.3"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Monitoring and Health Checks
|
||||
|
||||
### Application Health Endpoint
|
||||
|
||||
**URL**: `https://app.michaelschiemer.com/health`
|
||||
|
||||
**Response** (Healthy):
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"checks": {
|
||||
"database": "ok",
|
||||
"redis": "ok",
|
||||
"filesystem": "ok"
|
||||
},
|
||||
"timestamp": "2025-01-28T12:34:56Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Prometheus Metrics
|
||||
|
||||
**URL**: `https://metrics.michaelschiemer.com` (via WireGuard VPN)
|
||||
|
||||
**Key Metrics**:
|
||||
- Application response times
|
||||
- Database query performance
|
||||
- Redis cache hit rate
|
||||
- Queue job processing rate
|
||||
- System resources (CPU, Memory, Disk)
|
||||
|
||||
### Grafana Dashboards
|
||||
|
||||
**URL**: `https://grafana.michaelschiemer.com` (via WireGuard VPN)
|
||||
|
||||
**Pre-configured Dashboards**:
|
||||
- Application Overview
|
||||
- Database Performance
|
||||
- Queue System Metrics
|
||||
- Infrastructure Health
|
||||
- Docker Container Stats
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Deployment Failed
|
||||
|
||||
**Check Ansible Logs**:
|
||||
```bash
|
||||
# View last deployment log
|
||||
tail -f /var/log/ansible/deploy-update.log
|
||||
|
||||
# Check playbook output
|
||||
ansible-playbook -i inventory/production \
|
||||
playbooks/deploy-update.yml \
|
||||
-vvv # Verbose output
|
||||
```
|
||||
|
||||
**Common Issues**:
|
||||
- **Docker Registry Authentication Failed**: Check registry credentials in `secrets/registry.vault.yml`
|
||||
- **Database Migration Failed**: Check database connectivity, review migration logs
|
||||
- **Image Pull Failed**: Verify Docker Registry is accessible, image exists with specified tag
|
||||
|
||||
### Application Not Starting
|
||||
|
||||
**Check Docker Logs**:
|
||||
```bash
|
||||
# Application stack logs
|
||||
ssh deploy@app.michaelschiemer.com
|
||||
docker compose -f /opt/stacks/application/docker-compose.yml logs -f
|
||||
|
||||
# Specific service logs
|
||||
docker compose logs -f php
|
||||
docker compose logs -f nginx
|
||||
```
|
||||
|
||||
**Common Issues**:
|
||||
- **PHP Fatal Error**: Check PHP logs in `/var/log/app/php-error.log`
|
||||
- **Database Connection Refused**: Verify PostgreSQL stack is running, check credentials
|
||||
- **Redis Connection Failed**: Verify Redis stack is running, check authentication
|
||||
|
||||
### SSL Certificate Issues
|
||||
|
||||
**Check Traefik Logs**:
|
||||
```bash
|
||||
docker compose -f /opt/stacks/traefik/docker-compose.yml logs -f
|
||||
```
|
||||
|
||||
**Verify Let's Encrypt Certificate**:
|
||||
```bash
|
||||
# Check certificate expiry
|
||||
openssl s_client -connect app.michaelschiemer.com:443 -servername app.michaelschiemer.com \
|
||||
| openssl x509 -noout -dates
|
||||
|
||||
# Force certificate renewal (if needed)
|
||||
docker exec traefik /usr/bin/traefik \
|
||||
--acme.email=admin@michaelschiemer.com \
|
||||
--certificatesresolvers.letsencrypt.acme.email=admin@michaelschiemer.com
|
||||
```
|
||||
|
||||
### Rollback Procedure
|
||||
|
||||
**Immediate Rollback**:
|
||||
```bash
|
||||
# 1. Identify previous working version
|
||||
docker images | grep app
|
||||
|
||||
# 2. Execute rollback playbook
|
||||
cd deployment/ansible
|
||||
ansible-playbook -i inventory/production \
|
||||
playbooks/rollback.yml \
|
||||
--vault-password-file ~/.ansible/vault-password \
|
||||
--extra-vars "rollback_version=<IMAGE_TAG>"
|
||||
|
||||
# 3. Verify health
|
||||
curl -k https://app.michaelschiemer.com/health
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Development Workflow
|
||||
|
||||
**1. Local Development**:
|
||||
```bash
|
||||
# Use local docker-compose override
|
||||
docker compose -f docker-compose.base.yml -f docker-compose.local.yml up
|
||||
```
|
||||
|
||||
**2. Test Before Push**:
|
||||
```bash
|
||||
# Run test suite
|
||||
./vendor/bin/pest
|
||||
|
||||
# Code style check
|
||||
composer cs
|
||||
|
||||
# Static analysis
|
||||
composer analyze
|
||||
```
|
||||
|
||||
**3. Feature Branch Deployment** (Optional):
|
||||
```bash
|
||||
# Create feature branch
|
||||
git checkout -b feature/new-feature
|
||||
|
||||
# Deploy to staging (if configured)
|
||||
git push origin feature/new-feature
|
||||
# Triggers staging deployment
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
|
||||
**1. Use Ansible for Deployments**:
|
||||
- Never manually SSH and run docker commands
|
||||
- Always use Ansible playbooks for consistency
|
||||
- Ansible provides idempotency and rollback capability
|
||||
|
||||
**2. Monitor Deployments**:
|
||||
- Watch Grafana dashboards during deployment
|
||||
- Check application logs for errors
|
||||
- Verify health endpoint returns 200 OK
|
||||
|
||||
**3. Database Migrations**:
|
||||
- Always backup database before migrations
|
||||
- Test migrations on staging first
|
||||
- Migrations are automatically run by Ansible during deployment
|
||||
|
||||
**4. Zero-Downtime Deployments**:
|
||||
- Ansible uses rolling updates for PHP-FPM workers
|
||||
- Old containers remain until new containers are healthy
|
||||
- Traefik automatically routes to healthy containers
|
||||
|
||||
### Security
|
||||
|
||||
**1. Secrets Management**:
|
||||
- All secrets stored in Ansible Vault (encrypted)
|
||||
- Production credentials never committed to Git
|
||||
- Vault password stored securely (not in repository)
|
||||
|
||||
**2. Docker Secrets**:
|
||||
- Sensitive environment variables use Docker Secrets (`_FILE` suffix)
|
||||
- Secrets mounted at `/run/secrets/` (tmpfs, never written to disk)
|
||||
|
||||
**3. Network Isolation**:
|
||||
- Services communicate via internal Docker networks
|
||||
- Only Traefik exposes ports to public internet
|
||||
- Database and Redis not publicly accessible
|
||||
|
||||
**4. SSL/TLS**:
|
||||
- All traffic encrypted via Traefik
|
||||
- Let's Encrypt automatic certificate renewal
|
||||
- HTTP to HTTPS redirection enforced
|
||||
|
||||
---
|
||||
|
||||
## Future Improvements
|
||||
|
||||
### Planned Enhancements
|
||||
|
||||
**1. Blue-Green Deployments** (Q2 2025):
|
||||
- Run two identical production environments
|
||||
- Switch traffic between blue and green
|
||||
- Instant rollback capability
|
||||
|
||||
**2. Database Replication** (Q3 2025):
|
||||
- PostgreSQL primary-replica setup
|
||||
- Read replicas for scaling
|
||||
- Automatic failover
|
||||
|
||||
**3. Multi-Region Deployment** (Q4 2025):
|
||||
- Deploy to multiple geographic regions
|
||||
- DNS-based load balancing
|
||||
- Regional failover
|
||||
|
||||
**4. Enhanced Monitoring** (Q1 2025):
|
||||
- APM integration (Application Performance Monitoring)
|
||||
- Distributed tracing
|
||||
- Real-time alerting via PagerDuty/Slack
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
**Comprehensive Guides**:
|
||||
- `deployment/docs/guides/setup-guide.md` - Complete 8-phase setup walkthrough
|
||||
- `deployment/ansible/README.md` - Ansible automation details
|
||||
- `deployment/stacks/application/README.md` - Application stack deep-dive
|
||||
|
||||
**Status & Progress**:
|
||||
- `deployment/docs/status/deployment-summary.md` - Current deployment status (~95% complete)
|
||||
|
||||
**Framework Documentation**:
|
||||
- `docs/claude/architecture.md` - Framework architecture overview
|
||||
- `docs/claude/development-commands.md` - Development tools and commands
|
||||
- `docs/claude/common-workflows.md` - Standard development workflows
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Common Commands
|
||||
|
||||
**Local Development**:
|
||||
```bash
|
||||
# Start local environment
|
||||
docker compose -f docker-compose.base.yml -f docker-compose.local.yml up
|
||||
|
||||
# Run migrations
|
||||
docker exec php php console.php db:migrate
|
||||
|
||||
# Run tests
|
||||
./vendor/bin/pest
|
||||
```
|
||||
|
||||
**Deployment (via Ansible)**:
|
||||
```bash
|
||||
# Deploy to production
|
||||
cd deployment/ansible
|
||||
ansible-playbook -i inventory/production playbooks/deploy-update.yml --ask-vault-pass
|
||||
|
||||
# Rollback
|
||||
ansible-playbook -i inventory/production playbooks/rollback.yml --ask-vault-pass --extra-vars "rollback_version=v1.2.3"
|
||||
|
||||
# System maintenance
|
||||
ansible-playbook -i inventory/production playbooks/system-maintenance.yml --ask-vault-pass
|
||||
```
|
||||
|
||||
**Monitoring**:
|
||||
```bash
|
||||
# Check application health
|
||||
curl -k https://app.michaelschiemer.com/health
|
||||
|
||||
# View logs
|
||||
ssh deploy@app.michaelschiemer.com
|
||||
docker compose -f /opt/stacks/application/docker-compose.yml logs -f
|
||||
|
||||
# Access Grafana (via WireGuard VPN)
|
||||
https://grafana.michaelschiemer.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-01-28
|
||||
**Deployment Status**: 95% Complete (CI/CD pipeline configured, pending testing)
|
||||
**Next Critical Step**: Test CI/CD pipeline end-to-end
|
||||
472
docs/console-dialog-mode.md
Normal file
472
docs/console-dialog-mode.md
Normal file
@@ -0,0 +1,472 @@
|
||||
# Console Dialog Mode
|
||||
|
||||
## Übersicht
|
||||
|
||||
Der Console Dialog Mode bietet eine einfache, textbasierte interaktive Schnittstelle für die Console, ähnlich einem AI-Assistenten. Im Gegensatz zur grafischen TUI (Text User Interface) verwendet der Dialog-Modus eine klassische Prompt-Eingabe mit Command-Vorschlägen und History-Support.
|
||||
|
||||
## Features
|
||||
|
||||
### ✅ Hauptfunktionen
|
||||
|
||||
- **Prompt-basierte Eingabe**: Einfache Text-Eingabe wie bei einem AI-Assistenten
|
||||
- **Readline-Support**: Tab-Completion und History-Navigation (falls php-readline installiert)
|
||||
- **Command-Vorschläge**: Automatische Vorschläge bei Tippfehlern
|
||||
- **Kontextuelle Hilfe**: Hilfe während der Eingabe
|
||||
- **Command-History**: Nachverfolgung und Anzeige von verwendeten Commands
|
||||
- **Einfache Ausgabe**: Keine komplexe Terminal-Manipulation
|
||||
|
||||
### 🎯 Optional Features
|
||||
|
||||
- **Tab-Completion**: Automatische Vervollständigung von Commands
|
||||
- **History-Navigation**: ↑/↓ Tasten für Command-History (mit Readline)
|
||||
- **Command-Suggestions**: Intelligente Vorschläge bei Tippfehlern (Levenshtein-Similarity)
|
||||
- **Kontextuelle Hilfe**: Detaillierte Hilfe während der Eingabe
|
||||
- **Quoted Arguments**: Unterstützung für Argumente in Anführungszeichen
|
||||
|
||||
## Verwendung
|
||||
|
||||
### Dialog-Modus starten
|
||||
|
||||
```bash
|
||||
# Dialog-Modus explizit starten
|
||||
php console.php --dialog
|
||||
|
||||
# Alternative (Alias)
|
||||
php console.php --chat
|
||||
```
|
||||
|
||||
### Vergleich: TUI vs. Dialog-Modus
|
||||
|
||||
| Feature | TUI (Standard) | Dialog-Modus |
|
||||
|---------|----------------|--------------|
|
||||
| Start | `php console.php` | `php console.php --dialog` |
|
||||
| Interface | Grafische Navigation | Prompt-Eingabe |
|
||||
| Navigation | Maus + Tastatur | Nur Tastatur |
|
||||
| Completion | Limited | Tab-Completion |
|
||||
| History | ✅ | ✅ (mit Readline) |
|
||||
| Suggestions | ✅ | ✅ (intelligent) |
|
||||
| Terminal-Anforderungen | Kompatibles Terminal | Funktioniert überall |
|
||||
|
||||
### Standard-Verhalten
|
||||
|
||||
Ohne Argumente startet die Console standardmäßig die **TUI**:
|
||||
|
||||
```bash
|
||||
php console.php # Startet TUI
|
||||
php console.php --interactive # Startet TUI explizit
|
||||
php console.php --tui # Startet TUI explizit
|
||||
php console.php -i # Startet TUI explizit
|
||||
```
|
||||
|
||||
## Built-in Commands
|
||||
|
||||
Der Dialog-Modus bietet mehrere Built-in Commands:
|
||||
|
||||
### `help` - Hilfe anzeigen
|
||||
|
||||
Zeigt alle verfügbaren Commands gruppiert nach Kategorien:
|
||||
|
||||
```bash
|
||||
console> help
|
||||
console> ?
|
||||
console> :help
|
||||
console> h
|
||||
```
|
||||
|
||||
### `help <command>` - Detaillierte Hilfe
|
||||
|
||||
Zeigt detaillierte Hilfe für einen spezifischen Command:
|
||||
|
||||
```bash
|
||||
console> help db:migrate
|
||||
console> help user:create
|
||||
```
|
||||
|
||||
### `history` - Command-History
|
||||
|
||||
Zeigt die letzten verwendeten Commands:
|
||||
|
||||
```bash
|
||||
console> history
|
||||
console> :history
|
||||
```
|
||||
|
||||
### `clear` - Bildschirm löschen
|
||||
|
||||
Löscht den Bildschirm:
|
||||
|
||||
```bash
|
||||
console> clear
|
||||
console> :clear
|
||||
```
|
||||
|
||||
### `exit` / `quit` - Beenden
|
||||
|
||||
Beendet den Dialog-Modus:
|
||||
|
||||
```bash
|
||||
console> exit
|
||||
console> quit
|
||||
console> q
|
||||
console> :q
|
||||
```
|
||||
|
||||
## Command-Ausführung
|
||||
|
||||
### Basis-Commands
|
||||
|
||||
Commands werden direkt eingegeben:
|
||||
|
||||
```bash
|
||||
console> db:migrate
|
||||
console> user:list
|
||||
console> cache:clear
|
||||
```
|
||||
|
||||
### Commands mit Argumenten
|
||||
|
||||
Argumente werden nach dem Command angegeben:
|
||||
|
||||
```bash
|
||||
console> user:create alice@example.com 25
|
||||
console> db:migrate --force
|
||||
```
|
||||
|
||||
### Quoted Arguments
|
||||
|
||||
Argumente mit Leerzeichen können in Anführungszeichen gesetzt werden:
|
||||
|
||||
```bash
|
||||
console> user:create "John Doe" "john@example.com"
|
||||
console> deploy "production environment"
|
||||
```
|
||||
|
||||
## Readline-Support
|
||||
|
||||
### Installation
|
||||
|
||||
Für optimale Erfahrung sollte die `php-readline` Extension installiert sein:
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt-get install php-readline
|
||||
|
||||
# macOS (Homebrew)
|
||||
brew install php-readline
|
||||
|
||||
# Alpine
|
||||
apk add php-readline
|
||||
```
|
||||
|
||||
### Features mit Readline
|
||||
|
||||
Wenn Readline verfügbar ist, werden folgende Features aktiviert:
|
||||
|
||||
- **Tab-Completion**: Automatische Vervollständigung von Commands
|
||||
- **History-Navigation**: ↑/↓ Tasten für Command-History
|
||||
- **History-Persistenz**: History wird zwischen Sessions gespeichert
|
||||
|
||||
### Ohne Readline
|
||||
|
||||
Wenn Readline nicht verfügbar ist, funktioniert der Dialog-Modus weiterhin, aber ohne Tab-Completion und History-Navigation. Die History wird trotzdem gespeichert.
|
||||
|
||||
## Command-Vorschläge
|
||||
|
||||
### Automatische Vorschläge
|
||||
|
||||
Bei Tippfehlern werden automatisch ähnliche Commands vorgeschlagen:
|
||||
|
||||
```bash
|
||||
console> db:migrat
|
||||
Command 'db:migrat' not found.
|
||||
|
||||
Did you mean one of these?
|
||||
• db:migrate (95% match - prefix match)
|
||||
• db:migration:status (45% match - fuzzy match)
|
||||
```
|
||||
|
||||
### Vorschlags-Algorithmus
|
||||
|
||||
Die Vorschläge basieren auf:
|
||||
|
||||
1. **Exact Match**: 100% Ähnlichkeit
|
||||
2. **Prefix Match**: Command beginnt mit Eingabe (90% Ähnlichkeit)
|
||||
3. **Contains Match**: Command enthält Eingabe (70% Ähnlichkeit)
|
||||
4. **Levenshtein Distance**: Edit-Distanz-basierte Ähnlichkeit
|
||||
5. **Word Similarity**: Wort-basierte Ähnlichkeit für Commands mit Doppelpunkt
|
||||
|
||||
### History-basierte Vorschläge
|
||||
|
||||
Commands aus der History haben Priorität:
|
||||
|
||||
- **Favorites**: Commands, die als Favoriten markiert sind
|
||||
- **Recent**: Kürzlich verwendete Commands
|
||||
- **Frequency**: Häufig verwendete Commands
|
||||
|
||||
## Kontextuelle Hilfe
|
||||
|
||||
### Während der Eingabe
|
||||
|
||||
Nach fehlgeschlagenen Commands wird kontextuelle Hilfe angezeigt:
|
||||
|
||||
```bash
|
||||
console> db:migrate
|
||||
Executing: db:migrate
|
||||
────────────────────────────────────────────────────────────
|
||||
✗ Command failed with exit code: 1
|
||||
────────────────────────────────────────────────────────────
|
||||
|
||||
💡 Tip: Use "help db:migrate" for detailed help.
|
||||
Description: Run database migrations
|
||||
```
|
||||
|
||||
### Detaillierte Hilfe
|
||||
|
||||
Die detaillierte Hilfe zeigt:
|
||||
|
||||
- Command-Name und Beschreibung
|
||||
- Usage-Beispiele
|
||||
- Parameter-Dokumentation
|
||||
- Optionen und Flags
|
||||
- Beispiele
|
||||
|
||||
```bash
|
||||
console> help db:migrate
|
||||
|
||||
📖 Command Help: db:migrate
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
Command: db:migrate
|
||||
Description: Run database migrations
|
||||
|
||||
Usage:
|
||||
php console.php db:migrate [options]
|
||||
|
||||
Options:
|
||||
--force Force migration execution
|
||||
--pretend Show SQL without executing
|
||||
|
||||
Examples:
|
||||
php console.php db:migrate
|
||||
php console.php db:migrate --force
|
||||
php console.php db:migrate --pretend
|
||||
```
|
||||
|
||||
## Command-History
|
||||
|
||||
### History-Verwaltung
|
||||
|
||||
Die History wird automatisch verwaltet:
|
||||
|
||||
- **Automatische Speicherung**: Jeder ausgeführte Command wird gespeichert
|
||||
- **Persistenz**: History wird zwischen Sessions gespeichert
|
||||
- **Deduplizierung**: Doppelte Commands werden aktualisiert, nicht dupliziert
|
||||
- **Limit**: Standardmäßig werden 100 Commands gespeichert
|
||||
|
||||
### History anzeigen
|
||||
|
||||
```bash
|
||||
console> history
|
||||
|
||||
📜 Command History
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
1. db:migrate (used 5 times, last: 2024-01-15 10:30:45)
|
||||
2. user:create (used 3 times, last: 2024-01-15 09:15:22)
|
||||
3. cache:clear (used 2 times, last: 2024-01-14 16:45:10)
|
||||
```
|
||||
|
||||
### History-Navigation (mit Readline)
|
||||
|
||||
Mit Readline können Sie durch die History navigieren:
|
||||
|
||||
- **↑**: Vorheriger Command
|
||||
- **↓**: Nächster Command
|
||||
- **Tab**: Command-Vervollständigung
|
||||
|
||||
## Workflow-Beispiel
|
||||
|
||||
```bash
|
||||
$ php console.php --dialog
|
||||
|
||||
🤖 Console Dialog Mode
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
Available commands: 42
|
||||
✓ Readline support enabled (Tab completion, ↑/↓ history)
|
||||
|
||||
Type "help" for available commands or "exit" to quit.
|
||||
|
||||
console> help
|
||||
📚 Available Commands
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
Database:
|
||||
db:migrate
|
||||
Run database migrations
|
||||
db:seed
|
||||
Seed database with test data
|
||||
|
||||
User:
|
||||
user:create
|
||||
Create a new user
|
||||
user:list
|
||||
List all users
|
||||
|
||||
console> user:create alice@example.com 25
|
||||
Executing: user:create
|
||||
Arguments: alice@example.com 25
|
||||
────────────────────────────────────────────────────────────
|
||||
✓ Command completed successfully
|
||||
────────────────────────────────────────────────────────────
|
||||
|
||||
console> help user:create
|
||||
📖 Command Help: user:create
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
Command: user:create
|
||||
Description: Create a new user
|
||||
|
||||
Usage:
|
||||
php console.php user:create <email> [age] [--admin]
|
||||
|
||||
Parameters:
|
||||
email (string, required) - User email address
|
||||
age (int, optional, default: 18) - User age
|
||||
--admin (bool, optional) - Create as admin user
|
||||
|
||||
console> history
|
||||
📜 Command History
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
1. user:create (used 1 times, last: 2024-01-15 10:30:45)
|
||||
2. help (used 2 times, last: 2024-01-15 10:30:30)
|
||||
|
||||
console> exit
|
||||
Goodbye! 👋
|
||||
```
|
||||
|
||||
## Tipps & Best Practices
|
||||
|
||||
### Tab-Completion nutzen
|
||||
|
||||
Verwenden Sie Tab für Command-Vervollständigung:
|
||||
|
||||
```bash
|
||||
console> db:mi<Tab> # Vervollständigt zu db:migrate
|
||||
console> user:cr<Tab> # Vervollständigt zu user:create
|
||||
```
|
||||
|
||||
### History effizient nutzen
|
||||
|
||||
- **↑/↓**: Navigieren Sie durch die History
|
||||
- **History-Command**: Zeigen Sie alle Commands an
|
||||
- **Readline**: Nutzen Sie Readline für bessere Erfahrung
|
||||
|
||||
### Hilfe verwenden
|
||||
|
||||
- **`help`**: Zeigt alle Commands
|
||||
- **`help <command>`**: Detaillierte Hilfe für einen Command
|
||||
- **Kontextuelle Hilfe**: Wird nach Fehlern automatisch angezeigt
|
||||
|
||||
### Commands mit Argumenten
|
||||
|
||||
- **Quoted Arguments**: Verwenden Sie Anführungszeichen für Argumente mit Leerzeichen
|
||||
- **Flags**: Verwenden Sie `--flag` für boolesche Optionen
|
||||
- **Positional Arguments**: Argumente werden in der Reihenfolge der Methoden-Parameter übergeben
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Readline nicht verfügbar
|
||||
|
||||
Wenn Readline nicht verfügbar ist, sehen Sie:
|
||||
|
||||
```
|
||||
⚠ Readline not available (install php-readline for better experience)
|
||||
```
|
||||
|
||||
**Lösung**: Installieren Sie die `php-readline` Extension.
|
||||
|
||||
### Commands nicht gefunden
|
||||
|
||||
Wenn ein Command nicht gefunden wird, werden Vorschläge angezeigt:
|
||||
|
||||
```bash
|
||||
console> db:migrat
|
||||
Command 'db:migrat' not found.
|
||||
|
||||
Did you mean one of these?
|
||||
• db:migrate (95% match)
|
||||
```
|
||||
|
||||
### History funktioniert nicht
|
||||
|
||||
- **Ohne Readline**: History-Navigation (↑/↓) funktioniert nicht, aber History wird gespeichert
|
||||
- **Mit Readline**: History-Navigation funktioniert automatisch
|
||||
|
||||
### Hilfe generiert Fehler
|
||||
|
||||
Wenn die Hilfe-Generierung fehlschlägt, wird eine Fallback-Ausgabe angezeigt:
|
||||
|
||||
```bash
|
||||
console> help invalid:command
|
||||
Command 'invalid:command' not found.
|
||||
|
||||
Did you mean one of these?
|
||||
• valid:command (85% match)
|
||||
```
|
||||
|
||||
## Architektur
|
||||
|
||||
### Komponenten
|
||||
|
||||
- **`ConsoleDialog`**: Haupt-Orchestrator für den Dialog-Modus
|
||||
- **`DialogCommandExecutor`**: Command-Execution für Dialog-Modus
|
||||
- **`CommandHistory`**: History-Verwaltung (geteilt mit TUI)
|
||||
- **`CommandSuggestionEngine`**: Vorschlags-Engine (geteilt mit TUI)
|
||||
- **`CommandHelpGenerator`**: Hilfe-Generator (geteilt mit TUI)
|
||||
|
||||
### Integration
|
||||
|
||||
Der Dialog-Modus ist vollständig in `ConsoleApplication` integriert:
|
||||
|
||||
```php
|
||||
// In ConsoleApplication::run()
|
||||
if (in_array($commandName, ['--dialog', '--chat'])) {
|
||||
return $this->launchDialogMode();
|
||||
}
|
||||
```
|
||||
|
||||
### Wiederverwendung
|
||||
|
||||
Der Dialog-Modus nutzt die gleichen Komponenten wie die TUI:
|
||||
|
||||
- **CommandRegistry**: Command-Discovery und -Execution
|
||||
- **CommandGroupRegistry**: Command-Kategorisierung
|
||||
- **CommandHistory**: History-Verwaltung
|
||||
- **CommandSuggestionEngine**: Vorschlags-Engine
|
||||
|
||||
## Unterschiede zur TUI
|
||||
|
||||
| Aspekt | TUI | Dialog-Modus |
|
||||
|--------|-----|--------------|
|
||||
| **Interface** | Grafisch mit Navigation | Prompt-basiert |
|
||||
| **Terminal-Anforderungen** | Kompatibles Terminal erforderlich | Funktioniert überall |
|
||||
| **Maus-Support** | ✅ | ❌ |
|
||||
| **Tab-Completion** | Limited | ✅ (mit Readline) |
|
||||
| **History-Navigation** | Limited | ✅ (mit Readline) |
|
||||
| **Command-Suggestions** | ✅ | ✅ (intelligenter) |
|
||||
| **Einfachheit** | Komplexer | Einfacher |
|
||||
| **Best für** | Visuelle Navigation | Schnelle Eingabe |
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Der Dialog-Modus bietet eine einfache, effiziente Alternative zur TUI für Benutzer, die:
|
||||
|
||||
- Eine klassische Prompt-Eingabe bevorzugen
|
||||
- Schnelle Command-Ausführung ohne Navigation benötigen
|
||||
- Tab-Completion und History-Navigation nutzen möchten
|
||||
- In Terminals ohne TUI-Support arbeiten
|
||||
|
||||
**Start**: `php console.php --dialog` oder `php console.php --chat`
|
||||
|
||||
283
docs/deployment/WIREGUARD-DNS-FIX-IMPLEMENTED.md
Normal file
283
docs/deployment/WIREGUARD-DNS-FIX-IMPLEMENTED.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# WireGuard DNS Fix - Implementation Status
|
||||
|
||||
**Status**: ✅ Phase 1 COMPLETED - DNS Configuration Added
|
||||
**Datum**: 2025-01-29
|
||||
**Implementiert**: DNS-Konfiguration in Ansible Variables
|
||||
|
||||
## Was wurde geändert?
|
||||
|
||||
### 1. Ansible Group Variables Update
|
||||
|
||||
**Datei**: `deployment/ansible/group_vars/production.yml`
|
||||
|
||||
**Änderung**:
|
||||
```yaml
|
||||
# WireGuard DNS Configuration
|
||||
# DNS server for VPN clients (points to VPN server IP)
|
||||
# This ensures internal services are resolved to VPN IPs
|
||||
wireguard_dns_servers:
|
||||
- "{{ wireguard_server_ip_default }}"
|
||||
```
|
||||
|
||||
**Effekt**:
|
||||
- Template `wireguard-client.conf.j2` wird jetzt `DNS = 10.8.0.1` in Client-Configs generieren
|
||||
- Die `{% if wireguard_dns_servers | length > 0 %}` Bedingung im Template wird jetzt TRUE
|
||||
- Alle neu generierten Client-Configs enthalten DNS-Konfiguration
|
||||
|
||||
## Wie funktioniert es?
|
||||
|
||||
### Template Logic (bereits vorhanden)
|
||||
```jinja2
|
||||
{% if wireguard_dns_servers | length > 0 %}
|
||||
# DNS servers provided via Ansible (optional)
|
||||
DNS = {{ wireguard_dns_servers | join(', ') }}
|
||||
{% endif %}
|
||||
```
|
||||
|
||||
### Generated Client Config (nach Regenerierung)
|
||||
```ini
|
||||
[Interface]
|
||||
PrivateKey = <client_private_key>
|
||||
Address = 10.8.0.7/24
|
||||
DNS = 10.8.0.1 # ← JETZT ENTHALTEN!
|
||||
|
||||
[Peer]
|
||||
PublicKey = <server_public_key>
|
||||
Endpoint = michaelschiemer.de:51820
|
||||
AllowedIPs = 10.8.0.0/24
|
||||
PersistentKeepalive = 25
|
||||
```
|
||||
|
||||
## Erwartetes Verhalten
|
||||
|
||||
### DNS Resolution (Windows Client)
|
||||
```powershell
|
||||
# Nach Import der neuen Config:
|
||||
Get-DnsClientServerAddress | Where-Object {$_.InterfaceAlias -like "*WireGuard*"}
|
||||
|
||||
# Expected Output:
|
||||
InterfaceAlias : WireGuard Tunnel wg0
|
||||
ServerAddresses : {10.8.0.1} # ← VPN DNS Server
|
||||
```
|
||||
|
||||
### Service Resolution
|
||||
```powershell
|
||||
Resolve-DnsName grafana.michaelschiemer.de
|
||||
|
||||
# Expected Output:
|
||||
Name Type TTL Section IPAddress
|
||||
---- ---- --- ------- ---------
|
||||
grafana.michaelschiemer.de A 300 Answer 10.8.0.1 # ← VPN IP statt Public IP!
|
||||
```
|
||||
|
||||
### HTTP Traffic Routing
|
||||
```bash
|
||||
# Traefik Access Log (Server-Side):
|
||||
# VORHER (ohne DNS):
|
||||
89.246.96.244 - - [Date] "GET /grafana HTTP/2.0" 404
|
||||
↑ Public IP (FALSCH)
|
||||
|
||||
# NACHHER (mit DNS):
|
||||
10.8.0.5 - - [Date] "GET /grafana HTTP/2.0" 200
|
||||
↑ VPN IP (KORREKT)
|
||||
```
|
||||
|
||||
## Nächste Schritte (PENDING)
|
||||
|
||||
### Phase 2: Client Config Regenerierung
|
||||
|
||||
**Für Windows Client "mikepc"**:
|
||||
```bash
|
||||
cd ~/dev/michaelschiemer/deployment/ansible
|
||||
|
||||
ansible-playbook -i inventory/production.yml \
|
||||
playbooks/regenerate-wireguard-client.yml \
|
||||
-e "client_name=mikepc" \
|
||||
-e "client_ip=10.8.0.5"
|
||||
```
|
||||
|
||||
**Output**:
|
||||
- Backup: `mikepc.conf.backup-<timestamp>`
|
||||
- Neue Config: `deployment/ansible/wireguard-clients/mikepc.conf`
|
||||
- QR Code: `deployment/ansible/wireguard-clients/mikepc.png`
|
||||
|
||||
### Phase 3: Docker Container Test (OPTIONAL)
|
||||
|
||||
Teste VPN-Funktionalität in isolierter Umgebung:
|
||||
```bash
|
||||
ansible-playbook -i inventory/production.yml \
|
||||
playbooks/test-wireguard-docker-container.yml \
|
||||
-e "client_name=mikepc"
|
||||
```
|
||||
|
||||
**Verifizierung**:
|
||||
```bash
|
||||
# Ping Test
|
||||
docker exec wireguard-test-mikepc ping -c 4 10.8.0.1
|
||||
|
||||
# DNS Test
|
||||
docker exec wireguard-test-mikepc nslookup grafana.michaelschiemer.de 10.8.0.1
|
||||
|
||||
# HTTP Test
|
||||
docker exec wireguard-test-mikepc curl -v https://grafana.michaelschiemer.de
|
||||
```
|
||||
|
||||
### Phase 4: Windows Client Import
|
||||
|
||||
1. **WireGuard Application öffnen**
|
||||
2. **Tunnel "wg0" deaktivieren** (falls aktiv)
|
||||
3. **Tunnel "wg0" löschen** (alte Config entfernen)
|
||||
4. **Neue Config importieren**:
|
||||
- "Add Tunnel" → "Import from file"
|
||||
- Datei: `deployment/ansible/wireguard-clients/mikepc.conf`
|
||||
5. **Tunnel "wg0" aktivieren**
|
||||
|
||||
### Phase 5: Verification (Windows)
|
||||
|
||||
**DNS Check**:
|
||||
```powershell
|
||||
Get-DnsClientServerAddress | Where-Object {$_.InterfaceAlias -like "*WireGuard*"}
|
||||
# Expected: ServerAddresses = {10.8.0.1}
|
||||
|
||||
Resolve-DnsName grafana.michaelschiemer.de
|
||||
# Expected: IPAddress = 10.8.0.1
|
||||
```
|
||||
|
||||
**Browser Test**:
|
||||
```
|
||||
https://grafana.michaelschiemer.de
|
||||
Expected: Grafana Dashboard OHNE 404 Error
|
||||
```
|
||||
|
||||
**Server-Side Verification**:
|
||||
```bash
|
||||
# Traefik Access Log
|
||||
ssh deploy@michaelschiemer.de
|
||||
docker logs traefik --tail 50 | grep grafana
|
||||
|
||||
# Expected:
|
||||
# 10.8.0.5 - - [Date] "GET /grafana HTTP/2.0" 200
|
||||
# ↑ VPN IP statt Public IP!
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: DNS Still Not Working
|
||||
|
||||
**Check 1: Verify Config Contains DNS Line**
|
||||
```powershell
|
||||
Get-Content "C:\Path\To\mikepc.conf" | Select-String -Pattern "DNS"
|
||||
|
||||
# Expected:
|
||||
DNS = 10.8.0.1
|
||||
```
|
||||
|
||||
**Check 2: Verify Windows Uses VPN DNS**
|
||||
```powershell
|
||||
Get-DnsClientServerAddress | Format-Table InterfaceAlias, ServerAddresses
|
||||
|
||||
# WireGuard Interface should show 10.8.0.1
|
||||
```
|
||||
|
||||
**Check 3: Flush DNS Cache**
|
||||
```powershell
|
||||
ipconfig /flushdns
|
||||
Clear-DnsClientCache
|
||||
```
|
||||
|
||||
### Problem: VPN Connects But Still Uses Public IP
|
||||
|
||||
**Check 1: Verify Routes**
|
||||
```powershell
|
||||
Get-NetRoute | Where-Object {$_.DestinationPrefix -eq "10.8.0.0/24"}
|
||||
|
||||
# Should exist with WireGuard interface
|
||||
```
|
||||
|
||||
**Check 2: Test DNS Resolution**
|
||||
```powershell
|
||||
Resolve-DnsName grafana.michaelschiemer.de -Server 10.8.0.1
|
||||
|
||||
# Direct query to VPN DNS should work
|
||||
```
|
||||
|
||||
### Problem: Cannot Reach grafana.michaelschiemer.de
|
||||
|
||||
**Check 1: CoreDNS on Server**
|
||||
```bash
|
||||
ssh deploy@michaelschiemer.de
|
||||
docker ps | grep coredns
|
||||
docker logs coredns
|
||||
```
|
||||
|
||||
**Check 2: Traefik Configuration**
|
||||
```bash
|
||||
docker logs traefik | grep grafana
|
||||
# Check for middleware configuration
|
||||
```
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
Falls Probleme auftreten:
|
||||
|
||||
### Rollback Client Config
|
||||
```bash
|
||||
# Restore backup on server
|
||||
ssh deploy@michaelschiemer.de
|
||||
cd /etc/wireguard/clients
|
||||
cp mikepc.conf.backup-<timestamp> mikepc.conf
|
||||
|
||||
# Re-import on Windows
|
||||
```
|
||||
|
||||
### Rollback Ansible Variables
|
||||
```bash
|
||||
git diff deployment/ansible/group_vars/production.yml
|
||||
git checkout deployment/ansible/group_vars/production.yml
|
||||
```
|
||||
|
||||
## Success Criteria
|
||||
|
||||
✅ **DNS Configuration Added**: Ansible variables updated
|
||||
⏳ **Client Config Regenerated**: PENDING
|
||||
⏳ **Windows Client Import**: PENDING
|
||||
⏳ **DNS Resolution Working**: PENDING
|
||||
⏳ **HTTP/HTTPS via VPN**: PENDING
|
||||
⏳ **Traefik Shows VPN IP**: PENDING
|
||||
|
||||
## Alternative Options (If DNS Fix Fails)
|
||||
|
||||
### Option B: Full Tunnel VPN
|
||||
```yaml
|
||||
# AllowedIPs = 0.0.0.0/0 statt 10.8.0.0/24
|
||||
# Routes ALL traffic through VPN
|
||||
```
|
||||
|
||||
### Option C: Alternative VPN Software
|
||||
- OpenVPN (bewährt, stabil)
|
||||
- Tailscale (managed, einfach)
|
||||
- ZeroTier (mesh network)
|
||||
|
||||
## Referenzen
|
||||
|
||||
- **Implementation Plan**: `WIREGUARD-IMPLEMENTATION-PLAN.md`
|
||||
- **Original Analysis**: `WIREGUARD-WINDOWS-ROUTING-FINAL-ANALYSIS.md`
|
||||
- **DNS Solution**: `WIREGUARD-WINDOWS-DNS-FIX.md`
|
||||
- **Template**: `deployment/ansible/templates/wireguard-client.conf.j2`
|
||||
- **Variables**: `deployment/ansible/group_vars/production.yml`
|
||||
|
||||
## Notes
|
||||
|
||||
**Warum DNS-Konfiguration fehlt**:
|
||||
- Template hatte bereits Unterstützung via `{% if wireguard_dns_servers | length > 0 %}`
|
||||
- Variable `wireguard_dns_servers` fehlte in group_vars
|
||||
- Jetzt gesetzt auf `["{{ wireguard_server_ip_default }}"]` → `["10.8.0.1"]`
|
||||
|
||||
**Erwarteter Effekt**:
|
||||
- Alle neuen Client-Configs enthalten `DNS = 10.8.0.1`
|
||||
- Windows nutzt VPN-DNS für Namensauflösung
|
||||
- Interne Services (grafana.michaelschiemer.de) werden zu VPN-IP (10.8.0.1) aufgelöst
|
||||
- HTTP/HTTPS Traffic geht über VPN statt Public Interface
|
||||
|
||||
**Nächster kritischer Schritt**:
|
||||
Client Config für "mikepc" regenerieren und auf Windows importieren
|
||||
1175
docs/deployment/WIREGUARD-IMPLEMENTATION-PLAN.md
Normal file
1175
docs/deployment/WIREGUARD-IMPLEMENTATION-PLAN.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user