- Replace git.michaelschiemer.de:5000 (HTTP) with registry.michaelschiemer.de (HTTPS) - Update all Ansible playbooks and configuration files - Update CI/CD workflows to use HTTPS registry endpoint - Update Docker Compose files with new registry URL - Update documentation and scripts Benefits: - Secure HTTPS connection (no insecure registry config needed) - Consistent use of HTTPS endpoint via Traefik - Better security practices for production deployment
794 lines
19 KiB
Markdown
794 lines
19 KiB
Markdown
# Production Deployment - Complete Setup Guide
|
|
|
|
**Status**: 🚧 In Progress
|
|
**Last Updated**: 2025-10-30
|
|
**Target Server**: 94.16.110.151 (Netcup)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
This guide walks through the complete setup of production deployment from scratch, covering:
|
|
1. Gitea Runner (Development Machine)
|
|
2. Ansible Vault Secrets
|
|
3. Production Server Initial Setup
|
|
4. CI/CD Pipeline Testing
|
|
5. Monitoring & Health Checks
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
**Development Machine:**
|
|
- ✅ Docker & Docker Compose installed
|
|
- ✅ Ansible installed (`pip install ansible`)
|
|
- ✅ SSH key for production server (`~/.ssh/production`)
|
|
- ✅ Git SSH key configured (see Phase 0)
|
|
- ✅ Access to Gitea admin panel
|
|
|
|
**Production Server (94.16.110.151):**
|
|
- ✅ Docker & Docker Compose installed
|
|
- ✅ User `deploy` created with Docker permissions
|
|
- ✅ SSH access configured
|
|
- ✅ Firewall configured (ports 80, 443, 2222)
|
|
|
|
---
|
|
|
|
## Phase 0: Git Repository SSH Access Setup (Development Machine)
|
|
|
|
### Step 0.1: Generate Git SSH Key
|
|
|
|
Create a separate SSH key specifically for Git operations (different from the production server SSH key):
|
|
|
|
```bash
|
|
# Generate SSH key for Git
|
|
ssh-keygen -t ed25519 -f ~/.ssh/git_michaelschiemer -C "git@michaelschiemer.de" -N ""
|
|
|
|
# Set correct permissions
|
|
chmod 600 ~/.ssh/git_michaelschiemer
|
|
chmod 644 ~/.ssh/git_michaelschiemer.pub
|
|
```
|
|
|
|
### Step 0.2: Configure SSH Config
|
|
|
|
Add Git SSH configuration to `~/.ssh/config`:
|
|
|
|
```bash
|
|
# Edit SSH config
|
|
nano ~/.ssh/config
|
|
```
|
|
|
|
Add the following configuration:
|
|
|
|
```
|
|
Host git.michaelschiemer.de
|
|
HostName git.michaelschiemer.de
|
|
Port 2222
|
|
User git
|
|
IdentityFile ~/.ssh/git_michaelschiemer
|
|
StrictHostKeyChecking no
|
|
UserKnownHostsFile /dev/null
|
|
```
|
|
|
|
### Step 0.3: Add Public Key to Gitea
|
|
|
|
1. Display your public key:
|
|
```bash
|
|
cat ~/.ssh/git_michaelschiemer.pub
|
|
```
|
|
|
|
2. Copy the output (starts with `ssh-ed25519 ...`)
|
|
|
|
3. In Gitea:
|
|
- Go to **Settings** → **SSH / GPG Keys**
|
|
- Click **Add Key**
|
|
- Paste the public key
|
|
- Click **Add Key**
|
|
|
|
4. Verify the connection:
|
|
```bash
|
|
ssh -T git@git.michaelschiemer.de
|
|
```
|
|
|
|
Expected output: `Hi there! You've successfully authenticated...`
|
|
|
|
### Step 0.4: Update Git Remote (if needed)
|
|
|
|
If your `origin` remote uses HTTPS, switch it to SSH:
|
|
|
|
```bash
|
|
# Check current remote URL
|
|
git remote -v
|
|
|
|
# Update to SSH
|
|
git remote set-url origin git@git.michaelschiemer.de:michael/michaelschiemer.git
|
|
|
|
# Test push (should work without password prompt)
|
|
git push origin main
|
|
```
|
|
|
|
**Note**: This SSH key is separate from the production server SSH key (`~/.ssh/production`). The production key is used for Ansible/server access, while the Git key is only for repository operations.
|
|
|
|
---
|
|
|
|
## Phase 1: Gitea Runner Setup (Development Machine)
|
|
|
|
### Step 1.1: Get Gitea Registration Token
|
|
|
|
1. Navigate to Gitea admin panel:
|
|
```
|
|
https://git.michaelschiemer.de/admin/actions/runners
|
|
```
|
|
|
|
2. Click **"Create New Runner"**
|
|
|
|
3. Copy the registration token (format: `<long-random-string>`)
|
|
|
|
### Step 1.2: Configure Runner Environment
|
|
|
|
```bash
|
|
cd deployment/gitea-runner
|
|
|
|
# Copy environment template
|
|
cp .env.example .env
|
|
|
|
# Edit configuration
|
|
nano .env
|
|
```
|
|
|
|
**Required Configuration in `.env`:**
|
|
```bash
|
|
# Gitea Instance URL
|
|
GITEA_INSTANCE_URL=https://git.michaelschiemer.de
|
|
|
|
# Registration Token (from Step 1.1)
|
|
GITEA_RUNNER_REGISTRATION_TOKEN=<your-token-from-gitea>
|
|
|
|
# Runner Name (appears in Gitea UI)
|
|
GITEA_RUNNER_NAME=dev-runner-01
|
|
|
|
# Runner Labels (environments this runner supports)
|
|
GITEA_RUNNER_LABELS=ubuntu-latest:docker://node:20-bullseye,ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04
|
|
|
|
# Runner Capacity (concurrent jobs)
|
|
GITEA_RUNNER_CAPACITY=1
|
|
|
|
# Docker-in-Docker settings
|
|
DOCKER_HOST=tcp://docker-dind:2376
|
|
DOCKER_TLS_VERIFY=1
|
|
```
|
|
|
|
### Step 1.3: Register and Start Runner
|
|
|
|
```bash
|
|
# Register runner with Gitea
|
|
./register.sh
|
|
|
|
# Expected output:
|
|
# ✅ Starting Gitea Runner services...
|
|
# ✅ Runner registered successfully
|
|
# ✅ Runner is now active
|
|
|
|
# Verify runner is running
|
|
docker compose ps
|
|
|
|
# Check logs
|
|
docker compose logs -f gitea-runner
|
|
```
|
|
|
|
### Step 1.4: Verify Runner in Gitea
|
|
|
|
1. Go to: https://git.michaelschiemer.de/admin/actions/runners
|
|
2. You should see `dev-runner-01` listed as **"Idle"** or **"Active"**
|
|
3. Status should be green/online
|
|
|
|
**✅ Checkpoint**: Runner visible in Gitea UI and showing as "Idle"
|
|
|
|
---
|
|
|
|
## Phase 2: Ansible Vault Secrets Setup
|
|
|
|
### Step 2.1: Create Vault Password
|
|
|
|
```bash
|
|
cd deployment/ansible/secrets
|
|
|
|
# Create vault password file (gitignored)
|
|
echo "your-secure-vault-password-here" > .vault_pass
|
|
|
|
# Secure the file
|
|
chmod 600 .vault_pass
|
|
```
|
|
|
|
**⚠️ IMPORTANT**: Store this vault password in your password manager! You'll need it for all Ansible operations.
|
|
|
|
### Step 2.2: Create Production Secrets File
|
|
|
|
```bash
|
|
# Copy example template
|
|
cp production.vault.yml.example production.vault.yml
|
|
|
|
# Edit with your actual secrets
|
|
nano production.vault.yml
|
|
```
|
|
|
|
**Required Secrets in `production.vault.yml`:**
|
|
```yaml
|
|
---
|
|
# Docker Registry Credentials
|
|
docker_registry_user: "admin"
|
|
docker_registry_password: "your-registry-password"
|
|
|
|
# Application Environment Variables
|
|
app_key: "base64:generated-32-character-key"
|
|
app_env: "production"
|
|
app_debug: "false"
|
|
|
|
# Database Credentials
|
|
db_host: "postgres"
|
|
db_port: "5432"
|
|
db_name: "framework_production"
|
|
db_user: "framework_user"
|
|
db_password: "your-secure-db-password"
|
|
|
|
# Redis Configuration
|
|
redis_host: "redis"
|
|
redis_port: "6379"
|
|
redis_password: "your-secure-redis-password"
|
|
|
|
# Cache Configuration
|
|
cache_driver: "redis"
|
|
cache_prefix: "framework"
|
|
|
|
# Queue Configuration
|
|
queue_connection: "redis"
|
|
queue_name: "default"
|
|
|
|
# Session Configuration
|
|
session_driver: "redis"
|
|
session_lifetime: "120"
|
|
|
|
# Encryption Keys
|
|
encryption_key: "base64:your-32-byte-encryption-key"
|
|
state_encryption_key: "base64:your-32-byte-state-encryption-key"
|
|
|
|
# SMTP Configuration (Optional)
|
|
mail_mailer: "smtp"
|
|
mail_host: "smtp.example.com"
|
|
mail_port: "587"
|
|
mail_username: "noreply@michaelschiemer.de"
|
|
mail_password: "your-smtp-password"
|
|
mail_encryption: "tls"
|
|
mail_from_address: "noreply@michaelschiemer.de"
|
|
mail_from_name: "Framework"
|
|
|
|
# Admin IPs (comma-separated)
|
|
admin_allowed_ips: "127.0.0.1,::1"
|
|
|
|
# Rate Limiting
|
|
rate_limit_enabled: "true"
|
|
rate_limit_default: "60"
|
|
rate_limit_window: "60"
|
|
```
|
|
|
|
### Step 2.3: Generate Encryption Keys
|
|
|
|
```bash
|
|
# Generate app_key (32 bytes base64)
|
|
php -r "echo 'base64:' . base64_encode(random_bytes(32)) . PHP_EOL;"
|
|
|
|
# Generate encryption_key (32 bytes base64)
|
|
php -r "echo 'base64:' . base64_encode(random_bytes(32)) . PHP_EOL;"
|
|
|
|
# Generate state_encryption_key (32 bytes base64)
|
|
php -r "echo 'base64:' . base64_encode(random_bytes(32)) . PHP_EOL;"
|
|
|
|
# Copy these values into production.vault.yml
|
|
```
|
|
|
|
### Step 2.4: Encrypt Secrets File
|
|
|
|
```bash
|
|
# Encrypt the secrets file
|
|
ansible-vault encrypt production.vault.yml \
|
|
--vault-password-file .vault_pass
|
|
|
|
# Verify encryption worked
|
|
file production.vault.yml
|
|
# Should output: production.vault.yml: ASCII text
|
|
|
|
# View encrypted content (should show encrypted data)
|
|
cat production.vault.yml
|
|
|
|
# Test decryption (view content)
|
|
ansible-vault view production.vault.yml \
|
|
--vault-password-file .vault_pass
|
|
```
|
|
|
|
**✅ Checkpoint**: `production.vault.yml` is encrypted and can be decrypted with vault password
|
|
|
|
---
|
|
|
|
## Phase 3: Production Server Initial Setup
|
|
|
|
### Prerequisites
|
|
|
|
Before running Phase 3, ensure:
|
|
- ✅ SSH access to production server configured (`~/.ssh/production`)
|
|
- ✅ Repository cloned on production server at `~/deployment/stacks` (or adjust `stacks_base_path` in playbook)
|
|
- ✅ Ansible installed on your development machine: `pip install ansible`
|
|
- ✅ Ansible collections installed: `ansible-galaxy collection install community.docker`
|
|
|
|
### Step 3.1: Clone Repository on Production Server (if not already done)
|
|
|
|
**On Production Server:**
|
|
|
|
```bash
|
|
# SSH to production server
|
|
ssh deploy@94.16.110.151
|
|
|
|
# Clone repository (if not already present)
|
|
mkdir -p ~/deployment
|
|
cd ~/deployment
|
|
git clone git@git.michaelschiemer.de:michael/michaelschiemer.git . || git clone https://git.michaelschiemer.de/michael/michaelschiemer.git .
|
|
```
|
|
|
|
### Step 3.2: Deploy Infrastructure Stacks with Ansible
|
|
|
|
**On Development Machine:**
|
|
|
|
```bash
|
|
# Navigate to Ansible directory
|
|
cd deployment/ansible
|
|
|
|
# Run infrastructure deployment playbook
|
|
ansible-playbook playbooks/setup-infrastructure.yml \
|
|
-i inventory/production.yml
|
|
|
|
# The playbook will:
|
|
# 1. Create required Docker networks (traefik-public, app-internal)
|
|
# 2. Deploy Traefik (Reverse Proxy & SSL)
|
|
# 3. Deploy PostgreSQL (Database)
|
|
# 4. Deploy Docker Registry (Private Registry)
|
|
# 5. Deploy Gitea (Git Server + PostgreSQL)
|
|
# 6. Deploy Monitoring (Portainer + Grafana + Prometheus)
|
|
# 7. Wait for all services to be healthy
|
|
# 8. Verify accessibility
|
|
```
|
|
|
|
**Expected output:**
|
|
- ✅ All stacks deployed successfully
|
|
- ✅ All services healthy
|
|
- ✅ Gitea accessible at https://git.michaelschiemer.de
|
|
|
|
**Note:** If monitoring passwords need to be stored in Vault (recommended for production), add them to `secrets/production.vault.yml`:
|
|
- `vault_grafana_admin_password`
|
|
- `vault_prometheus_password`
|
|
|
|
Then run the playbook with vault:
|
|
```bash
|
|
ansible-playbook playbooks/setup-infrastructure.yml \
|
|
-i inventory/production.yml \
|
|
--vault-password-file secrets/.vault_pass
|
|
```
|
|
|
|
### Step 3.3: Configure Gitea (Manual Step)
|
|
|
|
1. Access Gitea: https://git.michaelschiemer.de
|
|
2. Complete initial setup wizard (first-time only):
|
|
- **Database Type**: PostgreSQL
|
|
- **Database Host**: `postgres:5432`
|
|
- **Database User**: `gitea`
|
|
- **Database Password**: `gitea_password` (or check `deployment/stacks/gitea/docker-compose.yml`)
|
|
- **Database Name**: `gitea`
|
|
- **Admin Account**: Create your admin user
|
|
- **Repository Root**: `/data/git/repositories` (default)
|
|
3. **Enable Actions** (required for Phase 1):
|
|
- Go to **Site Administration** → **Actions**
|
|
- Enable **Enable Actions** checkbox
|
|
- Save settings
|
|
|
|
### Step 3.4: Verify Docker Registry
|
|
|
|
The Ansible playbook automatically creates registry authentication. To retrieve credentials:
|
|
|
|
```bash
|
|
# SSH to production server
|
|
ssh deploy@94.16.110.151
|
|
|
|
# View registry htpasswd (contains username:password hash)
|
|
cat ~/deployment/stacks/registry/auth/htpasswd
|
|
|
|
# The default username is 'admin'
|
|
# Password hash can be used to login, or create new user:
|
|
cd ~/deployment/stacks/registry
|
|
docker compose exec registry htpasswd -Bbn <username> <password> >> auth/htpasswd
|
|
docker compose restart registry
|
|
|
|
# Test login
|
|
docker login registry.michaelschiemer.de
|
|
# Or if using port:
|
|
docker login registry.michaelschiemer.de
|
|
```
|
|
|
|
**✅ Checkpoint**: All infrastructure stacks running, Gitea accessible, Actions enabled
|
|
|
|
---
|
|
|
|
## Phase 4: Deploy Application Secrets
|
|
|
|
### Step 4.1: Deploy Secrets to Production
|
|
|
|
**On Development Machine:**
|
|
|
|
```bash
|
|
cd deployment/ansible
|
|
|
|
# Test Ansible connectivity
|
|
ansible production -m ping
|
|
|
|
# Deploy secrets to production server
|
|
ansible-playbook playbooks/setup-production-secrets.yml \
|
|
--vault-password-file secrets/.vault_pass
|
|
|
|
# Expected output:
|
|
# PLAY [Deploy Production Secrets] ***
|
|
# TASK [Ensure secrets directory exists] *** ok
|
|
# TASK [Deploy environment file] *** changed
|
|
# PLAY RECAP *** production: ok=2 changed=1
|
|
```
|
|
|
|
### Step 4.2: Verify Secrets Deployed
|
|
|
|
```bash
|
|
# SSH to production server
|
|
ssh deploy@94.16.110.151
|
|
|
|
# Check secrets directory
|
|
ls -la ~/secrets/
|
|
|
|
# Verify .env.production exists (do NOT cat - contains secrets!)
|
|
file ~/secrets/.env.production
|
|
# Should output: .env.production: ASCII text
|
|
|
|
# Check file permissions
|
|
stat ~/secrets/.env.production
|
|
# Should be 600 (readable only by deploy user)
|
|
```
|
|
|
|
**✅ Checkpoint**: Secrets deployed to production server in ~/secrets/.env.production
|
|
|
|
---
|
|
|
|
## Phase 5: Setup Gitea Secrets for CI/CD
|
|
|
|
### Step 5.1: Configure Repository Secrets
|
|
|
|
1. Go to repository settings in Gitea:
|
|
```
|
|
https://git.michaelschiemer.de/<username>/michaelschiemer/settings/secrets
|
|
```
|
|
|
|
2. Add the following secrets:
|
|
|
|
**REGISTRY_USER**
|
|
```
|
|
admin
|
|
```
|
|
|
|
**REGISTRY_PASSWORD**
|
|
```
|
|
<your-registry-password>
|
|
```
|
|
|
|
**SSH_PRIVATE_KEY**
|
|
```
|
|
<content-of-~/.ssh/production>
|
|
```
|
|
|
|
**ANSIBLE_VAULT_PASSWORD**
|
|
```
|
|
<your-vault-password-from-step-2.1>
|
|
```
|
|
|
|
### Step 5.2: Verify Secrets in Gitea
|
|
|
|
1. Check secrets are visible in repository settings
|
|
2. Each secret should show "Hidden" value with green checkmark
|
|
|
|
**✅ Checkpoint**: All required secrets configured in Gitea repository
|
|
|
|
---
|
|
|
|
## Phase 6: First Deployment Test
|
|
|
|
### Step 6.1: Manual Deployment Dry-Run
|
|
|
|
**On Development Machine:**
|
|
|
|
```bash
|
|
cd deployment/ansible
|
|
|
|
# Test deployment (check mode - no changes)
|
|
ansible-playbook -i inventory/production.yml \
|
|
playbooks/deploy-update.yml \
|
|
-e "image_tag=test-$(date +%s)" \
|
|
-e "git_commit_sha=test123" \
|
|
-e "deployment_timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
-e "docker_registry_username=admin" \
|
|
-e "docker_registry_password=your-registry-password" \
|
|
--check
|
|
|
|
# Expected: Should show what would be changed
|
|
```
|
|
|
|
### Step 6.2: Trigger CI/CD Pipeline
|
|
|
|
**Option A: Push to main branch**
|
|
```bash
|
|
# Make a small change (add comment to file)
|
|
echo "# Deployment test $(date)" >> deployment/DEPLOYMENT_TEST.txt
|
|
|
|
# Commit and push to main
|
|
git add deployment/DEPLOYMENT_TEST.txt
|
|
git commit -m "test(deployment): trigger CI/CD pipeline"
|
|
git push origin main
|
|
```
|
|
|
|
**Option B: Manual trigger**
|
|
1. Go to Gitea repository: Actions tab
|
|
2. Select workflow: "Production Deployment Pipeline"
|
|
3. Click "Run workflow"
|
|
4. Select branch: main
|
|
5. Click "Run"
|
|
|
|
### Step 6.3: Monitor Pipeline Execution
|
|
|
|
1. Go to: https://git.michaelschiemer.de/<username>/michaelschiemer/actions
|
|
2. Find the running workflow
|
|
3. Click to view details
|
|
4. Monitor each job:
|
|
- ✅ Test: Tests & quality checks pass
|
|
- ✅ Build: Docker image built and pushed
|
|
- ✅ Deploy: Application deployed to production
|
|
|
|
### Step 6.4: Verify Deployment
|
|
|
|
```bash
|
|
# Test health endpoint
|
|
curl -k https://michaelschiemer.de/health
|
|
|
|
# Expected response:
|
|
# {"status":"healthy","timestamp":"2025-10-30T14:30:00Z"}
|
|
|
|
# Check application logs
|
|
ssh deploy@94.16.110.151 "docker compose -f ~/application/docker-compose.yml logs -f app-php"
|
|
```
|
|
|
|
**✅ Checkpoint**: CI/CD pipeline executed successfully, application running on production
|
|
|
|
---
|
|
|
|
## Phase 7: Monitoring & Health Checks
|
|
|
|
### Step 7.1: Access Monitoring Tools
|
|
|
|
**Portainer**
|
|
```
|
|
https://portainer.michaelschiemer.de
|
|
```
|
|
- View all running containers
|
|
- Monitor resource usage
|
|
- Check logs
|
|
|
|
**Grafana**
|
|
```
|
|
https://grafana.michaelschiemer.de
|
|
```
|
|
- Username: admin
|
|
- Password: (set during setup)
|
|
- View application metrics
|
|
- Setup alerts
|
|
|
|
**Prometheus**
|
|
```
|
|
https://prometheus.michaelschiemer.de
|
|
```
|
|
- Query metrics
|
|
- Check targets
|
|
- Verify scraping
|
|
|
|
### Step 7.2: Configure Alerting
|
|
|
|
**In Grafana:**
|
|
|
|
1. Go to Alerting > Contact points
|
|
2. Add email notification channel
|
|
3. Create alert rules:
|
|
- High CPU usage (>80% for 5 minutes)
|
|
- High memory usage (>80%)
|
|
- Application down (health check fails)
|
|
- Database connection failures
|
|
|
|
### Step 7.3: Setup Health Check Monitoring
|
|
|
|
```bash
|
|
# Create cron job on production server
|
|
ssh deploy@94.16.110.151
|
|
|
|
# Add health check script
|
|
crontab -e
|
|
|
|
# Add line:
|
|
*/5 * * * * curl -f https://michaelschiemer.de/health || echo "Health check failed" | mail -s "Production Health Check Failed" admin@michaelschiemer.de
|
|
```
|
|
|
|
**✅ Checkpoint**: Monitoring tools accessible, alerts configured
|
|
|
|
---
|
|
|
|
## Phase 8: Backup & Rollback Testing
|
|
|
|
### Step 8.1: Verify Backups
|
|
|
|
```bash
|
|
# SSH to production server
|
|
ssh deploy@94.16.110.151
|
|
|
|
# Check backup directory
|
|
ls -lh ~/backups/
|
|
|
|
# Should see backup folders with timestamps
|
|
# Example: 2025-10-30T14-30-00/
|
|
```
|
|
|
|
### Step 8.2: Test Rollback
|
|
|
|
```bash
|
|
# On development machine
|
|
cd deployment/ansible
|
|
|
|
# Rollback to previous version
|
|
ansible-playbook -i inventory/production.yml \
|
|
playbooks/rollback.yml
|
|
|
|
# Verify rollback worked
|
|
curl -k https://michaelschiemer.de/health
|
|
```
|
|
|
|
**✅ Checkpoint**: Backups created, rollback mechanism tested
|
|
|
|
---
|
|
|
|
## Verification Checklist
|
|
|
|
### Infrastructure
|
|
- [ ] Traefik running and routing HTTPS
|
|
- [ ] PostgreSQL accessible and accepting connections
|
|
- [ ] Docker Registry accessible at registry.michaelschiemer.de
|
|
- [ ] Gitea accessible at git.michaelschiemer.de
|
|
- [ ] Monitoring stack (Portainer, Grafana, Prometheus) running
|
|
|
|
### Deployment
|
|
- [ ] Gitea Runner registered and showing "Idle" in UI
|
|
- [ ] Ansible Vault secrets encrypted and deployable
|
|
- [ ] SSH access configured for Ansible
|
|
- [ ] Repository secrets configured in Gitea
|
|
- [ ] CI/CD pipeline runs successfully end-to-end
|
|
|
|
### Application
|
|
- [ ] Application accessible at https://michaelschiemer.de
|
|
- [ ] Health endpoint returns 200 OK
|
|
- [ ] Database migrations ran successfully
|
|
- [ ] Queue workers processing jobs
|
|
- [ ] Logs showing no errors
|
|
|
|
### Monitoring
|
|
- [ ] Portainer shows all containers running
|
|
- [ ] Grafana dashboards displaying metrics
|
|
- [ ] Prometheus scraping all targets
|
|
- [ ] Alerts configured and sending notifications
|
|
|
|
### Security
|
|
- [ ] All secrets encrypted with Ansible Vault
|
|
- [ ] SSH keys secured (600 permissions)
|
|
- [ ] Registry requires authentication
|
|
- [ ] HTTPS enforced on all public endpoints
|
|
- [ ] Firewall configured correctly
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Gitea Runner Not Registering
|
|
|
|
**Symptoms**: Runner not appearing in Gitea UI after running `./register.sh`
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check runner logs
|
|
docker compose logs gitea-runner
|
|
|
|
# Verify registration token is correct
|
|
nano .env
|
|
# Check GITEA_RUNNER_REGISTRATION_TOKEN
|
|
|
|
# Unregister and re-register
|
|
./unregister.sh
|
|
./register.sh
|
|
```
|
|
|
|
### Ansible Connection Failed
|
|
|
|
**Symptoms**: `Failed to connect to the host via ssh`
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Test SSH manually
|
|
ssh -i ~/.ssh/production deploy@94.16.110.151
|
|
|
|
# Check SSH key permissions
|
|
chmod 600 ~/.ssh/production
|
|
|
|
# Verify SSH key is added to server
|
|
ssh-copy-id -i ~/.ssh/production.pub deploy@94.16.110.151
|
|
```
|
|
|
|
### Docker Registry Authentication Failed
|
|
|
|
**Symptoms**: `unauthorized: authentication required`
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Verify credentials
|
|
docker login registry.michaelschiemer.de
|
|
# Username: admin
|
|
# Password: <your-registry-password>
|
|
|
|
# Check htpasswd file on server
|
|
ssh deploy@94.16.110.151 "cat ~/deployment/stacks/registry/auth/htpasswd"
|
|
```
|
|
|
|
### Deployment Health Check Failed
|
|
|
|
**Symptoms**: Health check returns 404 or times out
|
|
|
|
**Solutions**:
|
|
```bash
|
|
# Check application logs
|
|
ssh deploy@94.16.110.151 "docker compose -f ~/application/docker-compose.yml logs app-php"
|
|
|
|
# Verify application stack is running
|
|
ssh deploy@94.16.110.151 "docker ps"
|
|
|
|
# Check Traefik routing
|
|
ssh deploy@94.16.110.151 "docker compose -f ~/deployment/stacks/traefik/docker-compose.yml logs"
|
|
```
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
After successful deployment:
|
|
|
|
1. **Configure DNS**: Point michaelschiemer.de to 94.16.110.151
|
|
2. **SSL Certificates**: Traefik will automatically request Let's Encrypt certificates
|
|
3. **Monitoring**: Review Grafana dashboards and setup additional alerts
|
|
4. **Backups**: Configure automated database backups
|
|
5. **Performance**: Review application performance and optimize
|
|
6. **Documentation**: Update team documentation with production procedures
|
|
|
|
---
|
|
|
|
## Support Contacts
|
|
|
|
- **Infrastructure Issues**: Check Portainer logs
|
|
- **Deployment Issues**: Review Gitea Actions logs
|
|
- **Application Issues**: Check application logs in Portainer
|
|
- **Emergency Rollback**: Run `ansible-playbook playbooks/rollback.yml`
|
|
|
|
---
|
|
|
|
**Setup Status**: 🚧 In Progress
|
|
**Next Action**: Start with Phase 1 - Gitea Runner Setup
|