forgejo-autohebergement/docs/OPERATIONS.md
Horacio Duran 822e42dbb8 Add Template to deploy forgejo.
This template allows deploying a forgejo en either Scaleway or Hetzner
(untested) without much knowledge about them.
It DOES require knowledge about Terragrunt and ansible. A wizard of
sorts is provided but it will not guarantee success without some
knowledge about the underlying technology.
2026-01-09 16:07:44 +01:00

574 lines
9.8 KiB
Markdown

# Operations Guide - Forgejo Self-Hosting
Complete guide for day-to-day operations and maintenance.
## Table of Contents
1. [Daily Operations](#daily-operations)
2. [Backup & Recovery](#backup--recovery)
3. [Updates & Upgrades](#updates--upgrades)
4. [Monitoring](#monitoring)
5. [Troubleshooting](#troubleshooting)
6. [Security Operations](#security-operations)
7. [Scaling](#scaling)
8. [Disaster Recovery](#disaster-recovery)
## Daily Operations
### Health Checks
```bash
# Quick health check
make health
# Full status
make status
# View recent logs
make logs | tail -100
```
### User Management
```bash
# SSH into server
make ssh
# List users
docker exec --user git forgejo forgejo admin user list
# Create user
docker exec --user git forgejo forgejo admin user create \
--username newuser \
--password 'SecureP@ssw0rd' \
--email user@example.com
# Change user password
docker exec --user git forgejo forgejo admin user change-password \
--username user \
--password 'NewP@ssw0rd'
# Make user admin
docker exec --user git forgejo forgejo admin user change-admin \
--username user \
--admin
```
### Repository Management
```bash
# Sync mirrors
docker exec --user git forgejo forgejo admin repo-sync-releases
# Rebuild indexes
docker exec --user git forgejo forgejo admin regenerate hooks
docker exec --user git forgejo forgejo admin regenerate keys
```
## Backup & Recovery
### Manual Backup
```bash
# Create immediate backup
make backup
# Backup with S3 upload
make backup-to-s3
# Verify backup
make ssh
ls -lh /opt/forgejo/backups/
```
### Automated Backups
Backups run automatically at 2 AM daily.
**Check backup status:**
```bash
make ssh
tail -f /var/log/forgejo-backup.log
```
**Modify schedule:**
```yaml
# In inventory or vars
forgejo_backup_schedule: "0 3 * * *" # 3 AM daily
```
### Restore from Backup
```bash
# List available backups
make ssh
ls /opt/forgejo/backups/
# Restore (timestamp format: 20240115T120000)
make restore
# Enter backup timestamp when prompted
# Force restore without confirmation
make restore-force
# Restore from S3
make restore-from-s3
```
### Backup Verification
```bash
# Test restore in separate environment
make ssh
cd /opt/forgejo/backups
# Verify database backup
gunzip -c database-TIMESTAMP.sql.gz | head -100
# Verify repositories backup
tar -tzf repositories-TIMESTAMP.tar.gz | head -20
```
## Updates & Upgrades
### Update Forgejo
```bash
# Standard update (includes backup)
make update
# Update without backup (not recommended)
make update-no-backup
```
**Update process:**
1. Creates pre-update backup
2. Stops Forgejo service
3. Pulls new Docker image
4. Starts service
5. Runs database migrations
6. Verifies health
### Update System Packages
```bash
make ssh
sudo apt update
sudo apt upgrade -y
sudo reboot # If kernel updated
```
### Update Infrastructure
```bash
# Review changes
make terraform-plan PROVIDER=scaleway
# Apply updates
make terraform-apply PROVIDER=scaleway
```
## Monitoring
### Log Management
```bash
# Forgejo logs
make logs
# Follow logs (real-time)
make logs | tail -f
# Nginx access logs
make logs-nginx
# System logs
make ssh
sudo journalctl -u forgejo -f
# Docker logs
docker logs forgejo --tail 100 -f
```
### Performance Monitoring
```bash
# Check resource usage
make ssh
# CPU and memory
htop
# Disk usage
df -h
du -sh /opt/forgejo/*
# Docker stats
docker stats forgejo
# PostgreSQL status
sudo systemctl status postgresql
```
### Database Monitoring
```bash
make ssh
# Connect to PostgreSQL
sudo -u postgres psql forgejo
# Check database size
SELECT pg_size_pretty(pg_database_size('forgejo'));
# Check table sizes
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC
LIMIT 10;
# Active connections
SELECT count(*) FROM pg_stat_activity;
```
## Troubleshooting
### Service Won't Start
```bash
# Check Docker status
make ssh
docker ps -a
docker logs forgejo
# Check system resources
free -h
df -h
# Restart service
make restart
# Full rebuild if needed
docker compose down
docker compose up -d
```
### Database Connection Issues
```bash
make ssh
# Check PostgreSQL
sudo systemctl status postgresql
# Check connections
sudo -u postgres psql -c "SELECT * FROM pg_stat_activity;"
# Restart PostgreSQL
sudo systemctl restart postgresql
# Check logs
sudo tail -f /var/log/postgresql/postgresql-16-main.log
```
### SSL Certificate Issues
```bash
make ssh
# Check certificate status
sudo certbot certificates
# Renew manually
sudo certbot renew --force-renewal
# Check Nginx configuration
sudo nginx -t
sudo systemctl restart nginx
# Check certificate files
sudo ls -la /etc/letsencrypt/live/git.yourdomain.com/
```
### Performance Issues
```bash
# Check slow queries
make ssh
sudo -u postgres psql forgejo
# Enable slow query logging
ALTER SYSTEM SET log_min_duration_statement = 1000;
SELECT pg_reload_conf();
# View slow queries
sudo tail -f /var/log/postgresql/postgresql-16-main.log
# Vacuum database
sudo -u postgres vacuumdb --analyze forgejo
```
### Disk Space Issues
```bash
make ssh
# Check space
df -h
# Find large directories
du -h /opt/forgejo | sort -rh | head -20
# Clean Docker
docker system prune -a
# Clean old backups
find /opt/forgejo/backups -type f -mtime +30 -delete
# Clean logs
sudo journalctl --vacuum-time=7d
```
## Security Operations
### Security Audit
```bash
make ssh
# Check for security updates
sudo apt update
sudo apt list --upgradable
# Review firewall rules
sudo ufw status verbose
# Check open ports
sudo netstat -tulpn
# Review SSH configuration
cat /etc/ssh/sshd_config
# Check failed login attempts
sudo grep "Failed password" /var/log/auth.log | tail -20
```
### Rotate Secrets
```bash
# Generate new secrets
openssl rand -base64 48
# Update vault
make ansible-vault-edit
# Redeploy with new secrets
make deploy
```
### SSL Certificate Renewal
```bash
# Auto-renewal is configured, but to force:
make ssh
sudo certbot renew --force-renewal
sudo systemctl reload nginx
```
### Security Updates
```bash
# Enable automatic security updates (already configured)
make ssh
sudo cat /etc/apt/apt.conf.d/50unattended-upgrades
# Check update history
sudo cat /var/log/unattended-upgrades/unattended-upgrades.log
```
## Scaling
### Vertical Scaling (More Resources)
```bash
# Update instance type
vim terraform/scaleway/compute/terraform.tfvars
# Change: instance_type = "DEV1-L" # 8GB RAM
make terraform-apply PROVIDER=scaleway
# Service restarts automatically
```
### Database Optimization
```bash
make ssh
sudo -u postgres psql forgejo
# Optimize settings
ALTER SYSTEM SET shared_buffers = '512MB';
ALTER SYSTEM SET effective_cache_size = '2GB';
ALTER SYSTEM SET maintenance_work_mem = '256MB';
SELECT pg_reload_conf();
```
### Add Storage Volume
```bash
# In inventory
forgejo_use_external_volume: true
forgejo_volume_device: /dev/sdb
# Redeploy
make deploy-tags TAGS=volume
```
## Disaster Recovery
### Complete Failure Recovery
```bash
# 1. Create new infrastructure
make terraform-apply PROVIDER=scaleway
# 2. Update inventory with new IP
vim ansible/inventory/production/hosts.yml
# 3. Update DNS records
# Point domain to new IP
# 4. Deploy with restore
# First, copy backup timestamp
make ssh
ls /opt/forgejo/backups/ # Note timestamp
# Then restore
make restore
# Enter timestamp when prompted
# 5. Verify
make health
```
### Backup Storage Migration
```bash
# Copy backups to new location
make ssh
rsync -avz /opt/forgejo/backups/ /new/backup/location/
# Update backup configuration
vim ansible/playbooks/vars/main.yml
# forgejo_backup_path: /new/backup/location
make deploy-tags TAGS=backup
```
### Database Recovery from Corruption
```bash
make ssh
# Stop Forgejo
docker compose down
# Backup corrupted database
sudo -u postgres pg_dump forgejo > /tmp/forgejo-corrupted.sql
# Drop and recreate
sudo -u postgres dropdb forgejo
sudo -u postgres createdb forgejo
# Restore from latest backup
gunzip -c /opt/forgejo/backups/database-TIMESTAMP.sql.gz | \
sudo -u postgres psql forgejo
# Restart Forgejo
docker compose up -d
```
## Best Practices
### Daily Checklist
- [ ] Check service health: `make health`
- [ ] Review logs for errors: `make logs | grep -i error`
- [ ] Verify backups ran: `ls -lt /opt/forgejo/backups/ | head -5`
- [ ] Check disk space: `df -h`
### Weekly Checklist
- [ ] Review security logs: `sudo grep "Failed" /var/log/auth.log`
- [ ] Check for updates: `sudo apt update && apt list --upgradable`
- [ ] Test backup restore (in dev environment)
- [ ] Review performance metrics
- [ ] Check SSL certificate expiry
### Monthly Checklist
- [ ] Full security audit
- [ ] Review and update firewall rules
- [ ] Rotate secrets if needed
- [ ] Review and optimize database
- [ ] Update documentation
- [ ] Test disaster recovery procedures
## Emergency Contacts
Keep these handy:
```bash
# Quick recovery commands
make health # Check status
make restart # Restart service
make logs # View logs
make backup # Create backup
make restore # Restore from backup
make ssh # SSH access
# Emergency rollback
make update # Includes backup
# If issues: make restore # Roll back
```
## Useful Scripts
### Health Check Script
```bash
#!/bin/bash
# Save as: health-check.sh
echo "=== Forgejo Health Check ==="
echo "Date: $(date)"
echo ""
echo "1. Service Status:"
docker ps | grep forgejo
echo ""
echo "2. Disk Space:"
df -h | grep -E "Filesystem|/dev/vda1|/dev/sda1"
echo ""
echo "3. Memory Usage:"
free -h
echo ""
echo "4. Latest Backup:"
ls -lth /opt/forgejo/backups/*.tar.gz | head -1
echo ""
echo "5. HTTP Status:"
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000
```
---
**Remember**: Always test procedures in a development environment first!