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.
569 lines
14 KiB
Markdown
569 lines
14 KiB
Markdown
# Configuration Reference
|
|
|
|
This document explains all configuration options for the Forgejo self-hosting setup.
|
|
|
|
## Table of Contents
|
|
|
|
- [Domain Configuration](#domain-configuration)
|
|
- [Secrets (Vault Variables)](#secrets-vault-variables)
|
|
- [Feature Flags](#feature-flags)
|
|
- [Security (Tailscale + UFW)](#security-tailscale--ufw)
|
|
- [S3/Object Storage](#s3object-storage)
|
|
- [Database Configuration](#database-configuration)
|
|
- [Email Configuration](#email-configuration)
|
|
- [Monitoring (Prometheus)](#monitoring-prometheus)
|
|
- [Backup Configuration](#backup-configuration)
|
|
|
|
---
|
|
|
|
## Domain Configuration
|
|
|
|
The domain is configured in **one primary location**:
|
|
|
|
**File:** `ansible/inventory/production/hosts.yml`
|
|
|
|
```yaml
|
|
forgejo_domain: git.yourdomain.com
|
|
```
|
|
|
|
This domain is used for:
|
|
|
|
- HTTPS certificate (automatically obtained via Caddy/Let's Encrypt)
|
|
- Forgejo web interface URL
|
|
- Git clone URLs: `https://git.yourdomain.com/user/repo.git`
|
|
- SSH clone URLs: `git@git.yourdomain.com:user/repo.git`
|
|
- Email "From" addresses
|
|
|
|
**Before deployment**, ensure your DNS is configured:
|
|
|
|
```
|
|
git.yourdomain.com. IN A <server-ipv4>
|
|
git.yourdomain.com. IN AAAA <server-ipv6>
|
|
```
|
|
|
|
---
|
|
|
|
## Secrets (Vault Variables)
|
|
|
|
All secrets are stored in `ansible/playbooks/vars/secrets.yml` encrypted with Ansible Vault.
|
|
|
|
### How to Set Up Secrets
|
|
|
|
```bash
|
|
# 1. Copy the example file
|
|
cp ansible/playbooks/vars/secrets.yml.example ansible/playbooks/vars/secrets.yml
|
|
|
|
# 2. Edit with your values
|
|
nano ansible/playbooks/vars/secrets.yml
|
|
|
|
# 3. Encrypt it
|
|
ansible-vault encrypt ansible/playbooks/vars/secrets.yml
|
|
|
|
# 4. To edit later
|
|
ansible-vault edit ansible/playbooks/vars/secrets.yml
|
|
```
|
|
|
|
### Secret Variables Explained
|
|
|
|
| Variable | Purpose | How to Generate |
|
|
|----------|---------|-----------------|
|
|
| `vault_forgejo_db_password` | PostgreSQL database password for Forgejo | `openssl rand -base64 32` |
|
|
| `vault_forgejo_admin_password` | Initial admin account password | Choose a strong password |
|
|
| `vault_forgejo_secret_key` | Used for CSRF tokens, session cookies, and encryption. Must be 64+ characters. | `openssl rand -base64 48` |
|
|
| `vault_forgejo_internal_token` | Used for internal API calls between Forgejo components | `openssl rand -base64 48` |
|
|
| `vault_forgejo_jwt_secret` | Signs JWT tokens for OAuth2 and API authentication | `openssl rand -base64 32` |
|
|
| `vault_forgejo_metrics_token` | Required to access `/metrics` endpoint (if Prometheus enabled) | `openssl rand -base64 32` |
|
|
| `vault_email_password` | SMTP password (if email enabled) | Your email provider password |
|
|
| `vault_s3_access_key` | S3-compatible storage access key (if S3 enabled) | From your cloud provider |
|
|
| `vault_s3_secret_key` | S3-compatible storage secret key (if S3 enabled) | From your cloud provider |
|
|
|
|
### Example secrets.yml
|
|
|
|
```yaml
|
|
---
|
|
vault_forgejo_db_password: "xK9mN2pL8qR5tW7vY3zB1cD4fG6hJ0kM"
|
|
vault_forgejo_admin_password: "MySecureAdminPassword123!"
|
|
vault_forgejo_secret_key: "aB3cD5eF7gH9iJ1kL3mN5oP7qR9sT1uV3wX5yZ7aB9cD1eF3gH5iJ7kL9mN1oP"
|
|
vault_forgejo_internal_token: "qW2eR4tY6uI8oP0aS2dF4gH6jK8lZ0xC2vB4nM6qW8eR0tY2uI4oP6aS8dF0g"
|
|
vault_forgejo_jwt_secret: "mN3bV5cX7zL9kJ1hG3fD5sA7pO9iU1yT"
|
|
vault_forgejo_metrics_token: "pR0mE7hEuS_t0K3n_H3r3"
|
|
vault_email_password: ""
|
|
vault_s3_access_key: ""
|
|
vault_s3_secret_key: ""
|
|
```
|
|
|
|
---
|
|
|
|
## Feature Flags
|
|
|
|
Configure features in `ansible/inventory/production/hosts.yml`:
|
|
|
|
### Core Features
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `forgejo_enable_letsencrypt` | `true` | Automatic HTTPS via Let's Encrypt (handled by Caddy) |
|
|
| `forgejo_enable_lfs` | `true` | Git Large File Storage support |
|
|
| `forgejo_enable_2fa` | `true` | Allow users to enable Two-Factor Authentication |
|
|
| `forgejo_use_redis` | `true` | Use Redis for caching (recommended for performance) |
|
|
| `forgejo_enable_backups` | `true` | Enable automated daily backups |
|
|
| `forgejo_enable_prometheus` | `false` | Enable internal Prometheus metrics collection |
|
|
|
|
### Access Control
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `forgejo_disable_registration` | `false` | Disable public user registration (invite-only) |
|
|
| `forgejo_require_signin_view` | `false` | Require login to view public repositories |
|
|
|
|
### Optional Services
|
|
|
|
| Flag | Default | Description |
|
|
|------|---------|-------------|
|
|
| `forgejo_enable_email` | `false` | Enable email notifications (requires SMTP config) |
|
|
| `forgejo_enable_s3` | `false` | Use S3-compatible storage for LFS and attachments |
|
|
|
|
### Example Configuration
|
|
|
|
```yaml
|
|
# In ansible/inventory/production/hosts.yml
|
|
forgejo_prod:
|
|
# ... other settings ...
|
|
|
|
# Enable all recommended features
|
|
forgejo_enable_letsencrypt: true
|
|
forgejo_enable_lfs: true
|
|
forgejo_enable_2fa: true
|
|
forgejo_use_redis: true
|
|
forgejo_enable_backups: true
|
|
|
|
# Enable monitoring
|
|
forgejo_enable_prometheus: true
|
|
|
|
# Private instance (no public registration)
|
|
forgejo_disable_registration: true
|
|
forgejo_require_signin_view: false
|
|
```
|
|
|
|
---
|
|
|
|
## Security (Tailscale + UFW)
|
|
|
|
This setup uses Tailscale VPN and UFW firewall to secure your Forgejo instance:
|
|
|
|
- **SSH access**: Only via Tailscale (not exposed to the public internet)
|
|
- **Git SSH (port 2222)**: Only via Tailscale
|
|
- **Web interface**: Public via HTTPS (ports 80/443)
|
|
- **Internal services**: Only via Tailscale (Prometheus, database, etc.)
|
|
|
|
### Enable Security Features
|
|
|
|
```yaml
|
|
# In ansible/inventory/production/hosts.yml
|
|
forgejo_enable_tailscale: true
|
|
forgejo_enable_ufw: true
|
|
```
|
|
|
|
### How It Works
|
|
|
|
1. **Tailscale** creates a secure mesh VPN network
|
|
2. **UFW** is configured to:
|
|
- Allow all traffic on the `tailscale0` interface
|
|
- Allow only HTTP/HTTPS (80/443) from the public internet
|
|
- Block SSH from the public internet
|
|
|
|
### Post-Deployment: Authenticate Tailscale
|
|
|
|
After deployment, SSH into the server (while SSH is still open) and authenticate Tailscale:
|
|
|
|
```bash
|
|
# SSH into server (before UFW locks down SSH)
|
|
ssh root@<server-public-ip>
|
|
|
|
# Authenticate Tailscale
|
|
sudo tailscale up --ssh
|
|
|
|
# This will print a URL - open it in your browser to authenticate
|
|
```
|
|
|
|
For headless/automated setup, use an auth key:
|
|
|
|
```bash
|
|
sudo tailscale up --authkey=tskey-auth-XXXXX
|
|
```
|
|
|
|
Generate auth keys at: https://login.tailscale.com/admin/settings/keys
|
|
|
|
### Accessing Your Server After Setup
|
|
|
|
Once UFW is configured, SSH is only accessible via Tailscale:
|
|
|
|
```bash
|
|
# Via Tailscale IP
|
|
ssh root@100.x.x.x
|
|
|
|
# Via Tailscale hostname (from admin console)
|
|
ssh root@your-server.tailnet-name.ts.net
|
|
|
|
# Via Tailscale SSH (if enabled with --ssh)
|
|
tailscale ssh root@your-server
|
|
```
|
|
|
|
### Git Clone URLs
|
|
|
|
| Method | URL | Access |
|
|
|--------|-----|--------|
|
|
| HTTPS | `https://git.yourdomain.com/user/repo.git` | Public |
|
|
| SSH | `git@<tailscale-hostname>:user/repo.git` | Tailscale only |
|
|
|
|
### Firewall Rules Summary
|
|
|
|
| Port | Protocol | Access | Purpose |
|
|
|------|----------|--------|---------|
|
|
| 80 | TCP | Public | HTTP (redirects to HTTPS) |
|
|
| 443 | TCP | Public | HTTPS (Forgejo web) |
|
|
| 22 | TCP | Tailscale only | System SSH |
|
|
| 2222 | TCP | Tailscale only | Git SSH |
|
|
| 3000 | TCP | Tailscale only | Forgejo internal |
|
|
| 9090 | TCP | Tailscale only | Prometheus |
|
|
|
|
### Disabling Security Features
|
|
|
|
If you need public SSH access (not recommended):
|
|
|
|
```yaml
|
|
forgejo_enable_tailscale: false
|
|
forgejo_enable_ufw: false
|
|
```
|
|
|
|
Or configure UFW manually after deployment.
|
|
|
|
---
|
|
|
|
## S3/Object Storage
|
|
|
|
S3-compatible object storage can be used for:
|
|
|
|
1. **Git LFS** - Large file storage
|
|
2. **Backups** - Off-site backup storage
|
|
3. **Attachments** - Issue/PR attachments (future)
|
|
|
|
### What is S3?
|
|
|
|
S3 (Simple Storage Service) is an object storage protocol. Both **Scaleway** and **Hetzner** offer S3-compatible storage:
|
|
|
|
- **Scaleway**: Object Storage (S3-compatible)
|
|
- **Hetzner**: Object Storage (S3-compatible, in beta)
|
|
|
|
### Setting Up S3 Storage
|
|
|
|
#### For Scaleway
|
|
|
|
1. **Create storage via Terraform** (already included):
|
|
|
|
```bash
|
|
make terraform-apply PROVIDER=scaleway
|
|
```
|
|
|
|
2. **Get credentials from Terraform output**:
|
|
|
|
```bash
|
|
cd terraform/scaleway/storage
|
|
terragrunt output access_key
|
|
terragrunt output secret_key
|
|
```
|
|
|
|
3. **Configure in inventory**:
|
|
|
|
```yaml
|
|
forgejo_enable_s3: true
|
|
forgejo_s3_endpoint: https://s3.fr-par.scw.cloud
|
|
forgejo_s3_bucket: your-project-production-lfs
|
|
forgejo_s3_region: fr-par
|
|
```
|
|
|
|
4. **Add credentials to secrets.yml**:
|
|
|
|
```yaml
|
|
vault_s3_access_key: "SCWXXXXXXXXXXXXXXXXX"
|
|
vault_s3_secret_key: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
```
|
|
|
|
#### For Hetzner
|
|
|
|
Hetzner Object Storage is S3-compatible:
|
|
|
|
1. **Create a storage box** in Hetzner Cloud Console
|
|
|
|
2. **Configure in inventory**:
|
|
|
|
```yaml
|
|
forgejo_enable_s3: true
|
|
forgejo_s3_endpoint: https://fsn1.your-objectstorage.com
|
|
forgejo_s3_bucket: forgejo-lfs
|
|
forgejo_s3_region: fsn1
|
|
```
|
|
|
|
3. **Add credentials to secrets.yml**
|
|
|
|
### S3 for Backups
|
|
|
|
To upload backups to S3:
|
|
|
|
```yaml
|
|
# In inventory
|
|
forgejo_backup_to_s3: true
|
|
forgejo_backup_s3_bucket: your-project-production-backups
|
|
```
|
|
|
|
Then run:
|
|
|
|
```bash
|
|
make backup-to-s3
|
|
```
|
|
|
|
---
|
|
|
|
## Database Configuration
|
|
|
|
PostgreSQL is the recommended database.
|
|
|
|
### Settings
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `forgejo_db_type` | `postgres` | Database type (postgres recommended) |
|
|
| `forgejo_db_host` | `localhost` | Database host |
|
|
| `forgejo_db_port` | `5432` | Database port |
|
|
| `forgejo_db_name` | `forgejo` | Database name |
|
|
| `forgejo_db_user` | `forgejo` | Database user |
|
|
|
|
The password is in `vault_forgejo_db_password`.
|
|
|
|
### PostgreSQL Tuning
|
|
|
|
Default tuning in `ansible/roles/forgejo/defaults/main.yml`:
|
|
|
|
```yaml
|
|
postgres_version: "16"
|
|
postgres_max_connections: 100
|
|
postgres_shared_buffers: "256MB"
|
|
postgres_effective_cache_size: "1GB"
|
|
```
|
|
|
|
For larger instances, adjust these based on available RAM.
|
|
|
|
---
|
|
|
|
## Email Configuration
|
|
|
|
Enable email for notifications, password resets, and registration confirmation.
|
|
|
|
### Settings
|
|
|
|
```yaml
|
|
# In inventory
|
|
forgejo_enable_email: true
|
|
forgejo_email_host: smtp.example.com
|
|
forgejo_email_port: 587
|
|
forgejo_email_user: noreply@yourdomain.com
|
|
|
|
# In secrets.yml
|
|
vault_email_password: "your-smtp-password"
|
|
```
|
|
|
|
### Common SMTP Providers
|
|
|
|
**Gmail (with App Password)**:
|
|
|
|
```yaml
|
|
forgejo_email_host: smtp.gmail.com
|
|
forgejo_email_port: 587
|
|
forgejo_email_user: your-email@gmail.com
|
|
```
|
|
|
|
**Mailgun**:
|
|
|
|
```yaml
|
|
forgejo_email_host: smtp.mailgun.org
|
|
forgejo_email_port: 587
|
|
forgejo_email_user: postmaster@your-domain.mailgun.org
|
|
```
|
|
|
|
**SendGrid**:
|
|
|
|
```yaml
|
|
forgejo_email_host: smtp.sendgrid.net
|
|
forgejo_email_port: 587
|
|
forgejo_email_user: apikey
|
|
# vault_email_password should be your SendGrid API key
|
|
```
|
|
|
|
---
|
|
|
|
## Monitoring (Prometheus)
|
|
|
|
Internal Prometheus monitoring for your Forgejo instance.
|
|
|
|
### Enable Monitoring
|
|
|
|
```yaml
|
|
# In inventory
|
|
forgejo_enable_prometheus: true
|
|
```
|
|
|
|
### What Gets Monitored
|
|
|
|
- **Forgejo metrics**: HTTP requests, Git operations, users, repos, issues
|
|
- **Prometheus self-monitoring**: Scrape health
|
|
|
|
### Accessing Metrics
|
|
|
|
Prometheus is **internal only** (bound to localhost:9090). To access:
|
|
|
|
1. **SSH tunnel**:
|
|
|
|
```bash
|
|
ssh -L 9090:localhost:9090 root@your-server
|
|
```
|
|
|
|
Then open http://localhost:9090
|
|
|
|
2. **Forgejo metrics endpoint**:
|
|
|
|
```
|
|
https://git.yourdomain.com/metrics?token=YOUR_METRICS_TOKEN
|
|
```
|
|
|
|
The token is `vault_forgejo_metrics_token`.
|
|
|
|
### Adding Grafana (Optional)
|
|
|
|
To add Grafana dashboards, extend the monitoring setup:
|
|
|
|
```yaml
|
|
# Create docker-compose.grafana.yml manually
|
|
services:
|
|
grafana:
|
|
image: grafana/grafana:latest
|
|
container_name: grafana
|
|
ports:
|
|
- "127.0.0.1:3001:3000"
|
|
volumes:
|
|
- grafana-data:/var/lib/grafana
|
|
environment:
|
|
- GF_SECURITY_ADMIN_PASSWORD=your-grafana-password
|
|
networks:
|
|
- forgejo-network
|
|
```
|
|
|
|
---
|
|
|
|
## Backup Configuration
|
|
|
|
### Settings
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `forgejo_enable_backups` | `true` | Enable automated backups |
|
|
| `forgejo_backup_schedule` | `0 2 * * *` | Cron schedule (default: 2 AM daily) |
|
|
| `forgejo_backup_retention_days` | `30` | Days to keep local backups |
|
|
| `forgejo_backup_to_s3` | `false` | Upload backups to S3 |
|
|
| `forgejo_backup_s3_bucket` | `""` | S3 bucket for backups |
|
|
|
|
### What Gets Backed Up
|
|
|
|
1. **PostgreSQL database** - Full SQL dump
|
|
2. **Git repositories** - All repository data
|
|
3. **Configuration** - app.ini, docker-compose.yml
|
|
4. **User data** - Attachments, LFS files, avatars
|
|
|
|
### Backup Commands
|
|
|
|
```bash
|
|
# Manual backup
|
|
make backup
|
|
|
|
# Backup and upload to S3
|
|
make backup-to-s3
|
|
|
|
# Restore from backup
|
|
make restore
|
|
# You'll be prompted for the backup timestamp
|
|
```
|
|
|
|
### Backup Location
|
|
|
|
Local backups are stored in: `/opt/forgejo/backups/`
|
|
|
|
Files:
|
|
|
|
- `database-TIMESTAMP.sql.gz`
|
|
- `repositories-TIMESTAMP.tar.gz`
|
|
- `config-TIMESTAMP.tar.gz`
|
|
- `data-TIMESTAMP.tar.gz`
|
|
|
|
---
|
|
|
|
## Quick Reference: Enable Everything
|
|
|
|
For a fully-featured setup with all options enabled:
|
|
|
|
```yaml
|
|
# ansible/inventory/production/hosts.yml
|
|
forgejo-prod:
|
|
ansible_host: YOUR_SERVER_IP
|
|
ansible_user: root
|
|
|
|
# Domain
|
|
forgejo_domain: git.yourdomain.com
|
|
|
|
# Core
|
|
forgejo_version: "9.0.2"
|
|
forgejo_enable_letsencrypt: true
|
|
forgejo_enable_lfs: true
|
|
forgejo_enable_2fa: true
|
|
forgejo_use_redis: true
|
|
|
|
# Database
|
|
forgejo_db_type: postgres
|
|
|
|
# Backups
|
|
forgejo_enable_backups: true
|
|
forgejo_backup_retention_days: 30
|
|
forgejo_backup_to_s3: true
|
|
forgejo_backup_s3_bucket: your-backup-bucket
|
|
|
|
# S3 Storage
|
|
forgejo_enable_s3: true
|
|
forgejo_s3_endpoint: https://s3.fr-par.scw.cloud
|
|
forgejo_s3_bucket: your-lfs-bucket
|
|
forgejo_s3_region: fr-par
|
|
|
|
# Email
|
|
forgejo_enable_email: true
|
|
forgejo_email_host: smtp.mailgun.org
|
|
forgejo_email_port: 587
|
|
forgejo_email_user: noreply@yourdomain.com
|
|
|
|
# Monitoring
|
|
forgejo_enable_prometheus: true
|
|
|
|
# Access
|
|
forgejo_disable_registration: false # Set to true for invite-only
|
|
forgejo_require_signin_view: false
|
|
```
|
|
|
|
Then in `ansible/playbooks/vars/secrets.yml`:
|
|
|
|
```yaml
|
|
vault_forgejo_db_password: "GENERATED_PASSWORD"
|
|
vault_forgejo_admin_password: "YOUR_ADMIN_PASSWORD"
|
|
vault_forgejo_secret_key: "64_CHAR_GENERATED_KEY"
|
|
vault_forgejo_internal_token: "GENERATED_TOKEN"
|
|
vault_forgejo_jwt_secret: "GENERATED_SECRET"
|
|
vault_forgejo_metrics_token: "GENERATED_TOKEN"
|
|
vault_email_password: "YOUR_SMTP_PASSWORD"
|
|
vault_s3_access_key: "YOUR_S3_ACCESS_KEY"
|
|
vault_s3_secret_key: "YOUR_S3_SECRET_KEY"
|
|
```
|