Backport fixes from version in production
Per file detail:
backup.yml
- Added role defaults loading with proper precedence (inventory > vars > defaults)
- Fixed pg_dump permissions: now dumps to /tmp first, then moves to backup directory
update.yml
- Added role defaults loading with proper precedence
- Fixed docker exec commands to use --user {{ forgejo_user }}
- Added monitoring compose file detection and handling
restore.yml
- Added role defaults loading with proper precedence
- Added monitoring compose file detection and handling
- Fixed docker exec for doctor command to use --user {{ forgejo_user }}
Makefile
- Updated .PHONY with new targets
- Replaced auto-generated help with structured categorized help
- Added backup-cron and backup-cron-s3 targets for non-interactive backups
- Added cron job example in help output
This commit is contained in:
parent
dff39e3d36
commit
c09bf58ea7
4 changed files with 143 additions and 20 deletions
86
Makefile
86
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
# Forgejo Self-Hosting Automation Makefile
|
||||
# Provides convenient commands for deployment, updates, backups, and maintenance
|
||||
|
||||
.PHONY: help install deploy update backup restore ssh terraform-init terraform-plan terraform-apply terraform-destroy ansible-ping ansible-setup check-deps
|
||||
.PHONY: help install deploy update backup backup-cron backup-to-s3 backup-cron-s3 restore ssh terraform-init terraform-plan terraform-apply terraform-destroy ansible-ping ansible-setup check-deps
|
||||
|
||||
# Default target
|
||||
.DEFAULT_GOAL := help
|
||||
|
|
@ -28,20 +28,80 @@ NC := \033[0m # No Color
|
|||
|
||||
# Help target
|
||||
help: ## Show this help message
|
||||
@echo "$(GREEN)════════════════════════════════════════════════════════════════════$(NC)"
|
||||
@echo "$(GREEN) Forgejo Self-Hosting - Available Commands$(NC)"
|
||||
@echo "$(GREEN)════════════════════════════════════════════════════════════════════$(NC)"
|
||||
@echo ""
|
||||
@echo "$(YELLOW)First time? Run:$(NC) ./setup-wizard.sh"
|
||||
@echo ""
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " $(YELLOW)%-20s$(NC) %s\n", $$1, $$2}'
|
||||
@echo "$(GREEN)── SETUP & INSTALLATION ──$(NC)"
|
||||
@echo " $(YELLOW)wizard$(NC) Run interactive setup wizard (first-time setup)"
|
||||
@echo " $(YELLOW)check-deps$(NC) Verify all required tools are installed"
|
||||
@echo " $(YELLOW)install$(NC) Full install: create infrastructure + deploy Forgejo"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── DEPLOYMENT ──$(NC)"
|
||||
@echo " $(YELLOW)deploy$(NC) Deploy/update Forgejo configuration (full)"
|
||||
@echo " $(YELLOW)deploy-quick$(NC) Quick deploy without dependency checks"
|
||||
@echo " $(YELLOW)deploy-tags$(NC) Deploy specific components (TAGS=forgejo,caddy,ufw)"
|
||||
@echo " $(YELLOW)deploy-check$(NC) Dry-run deployment (no changes made)"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── INFRASTRUCTURE (Terraform) ──$(NC)"
|
||||
@echo " $(YELLOW)terraform-init$(NC) Initialize Terraform/Terragrunt"
|
||||
@echo " $(YELLOW)terraform-plan$(NC) Preview infrastructure changes"
|
||||
@echo " $(YELLOW)terraform-apply$(NC) Create/update cloud infrastructure"
|
||||
@echo " $(YELLOW)terraform-output$(NC) Show infrastructure details (IPs, etc.)"
|
||||
@echo " $(YELLOW)terraform-destroy$(NC) Destroy all infrastructure (DANGEROUS!)"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── BACKUP & RESTORE ──$(NC)"
|
||||
@echo " $(YELLOW)backup$(NC) Create backup (interactive)"
|
||||
@echo " $(YELLOW)backup-cron$(NC) Create backup (non-interactive, for cron jobs)"
|
||||
@echo " $(YELLOW)backup-to-s3$(NC) Create backup and upload to S3 (interactive)"
|
||||
@echo " $(YELLOW)backup-cron-s3$(NC) Create backup and upload to S3 (for cron jobs)"
|
||||
@echo " $(YELLOW)restore$(NC) Restore from backup (interactive)"
|
||||
@echo " $(YELLOW)restore-from-s3$(NC) Restore from S3 backup"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── UPDATES ──$(NC)"
|
||||
@echo " $(YELLOW)update$(NC) Update Forgejo to latest version (with backup)"
|
||||
@echo " $(YELLOW)update-no-backup$(NC) Update Forgejo without creating backup"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── MONITORING & MAINTENANCE ──$(NC)"
|
||||
@echo " $(YELLOW)status$(NC) Show Forgejo container status"
|
||||
@echo " $(YELLOW)health$(NC) Check Forgejo health endpoint"
|
||||
@echo " $(YELLOW)logs$(NC) View Forgejo logs (live, Ctrl+C to exit)"
|
||||
@echo " $(YELLOW)logs-caddy$(NC) View Caddy/HTTPS logs (live)"
|
||||
@echo " $(YELLOW)restart$(NC) Restart Forgejo container"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── SSH & CONNECTIVITY ──$(NC)"
|
||||
@echo " $(YELLOW)ssh$(NC) SSH into the Forgejo server"
|
||||
@echo " $(YELLOW)ssh-agent-start$(NC) Start SSH agent and load key"
|
||||
@echo " $(YELLOW)ssh-agent-check$(NC) Verify SSH agent has keys loaded"
|
||||
@echo " $(YELLOW)ansible-ping$(NC) Test Ansible connection to server"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── SECRETS & CONFIGURATION ──$(NC)"
|
||||
@echo " $(YELLOW)ansible-vault-edit$(NC) Edit encrypted secrets file"
|
||||
@echo " $(YELLOW)ansible-vault-create$(NC) Create new encrypted secrets file"
|
||||
@echo " $(YELLOW)validate$(NC) Validate all configuration files"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── INFORMATION ──$(NC)"
|
||||
@echo " $(YELLOW)info$(NC) Show current project configuration"
|
||||
@echo " $(YELLOW)version$(NC) Show versions of all tools"
|
||||
@echo " $(YELLOW)clean$(NC) Remove temporary/cache files"
|
||||
@echo ""
|
||||
@echo "$(GREEN)── DANGEROUS OPERATIONS ──$(NC)"
|
||||
@echo " $(YELLOW)rebuild$(NC) Destroy and recreate everything (DATA LOSS!)"
|
||||
@echo " $(YELLOW)terraform-destroy$(NC) Destroy all cloud infrastructure (DATA LOSS!)"
|
||||
@echo ""
|
||||
@echo "$(GREEN)════════════════════════════════════════════════════════════════════$(NC)"
|
||||
@echo "$(GREEN)Examples:$(NC)"
|
||||
@echo " ./setup-wizard.sh # Interactive first-time setup"
|
||||
@echo " make check-deps # Check all dependencies"
|
||||
@echo " make terraform-apply # Create infrastructure"
|
||||
@echo " make deploy # Deploy Forgejo"
|
||||
@echo " make update # Update Forgejo"
|
||||
@echo " make backup # Create backup"
|
||||
@echo " make PROVIDER=hetzner deploy # Deploy on Hetzner"
|
||||
@echo " ./setup-wizard.sh # First-time interactive setup"
|
||||
@echo " make deploy # Deploy configuration changes"
|
||||
@echo " make deploy-tags TAGS=forgejo # Update only Forgejo config"
|
||||
@echo " make backup-cron # Backup (for cron jobs)"
|
||||
@echo " make PROVIDER=hetzner terraform-plan # Plan Hetzner infrastructure"
|
||||
@echo ""
|
||||
@echo "$(GREEN)Cron example (daily backup at 2 AM):$(NC)"
|
||||
@echo " 0 2 * * * cd /path/to/forgejo-selfhosting && make backup-cron >> /var/log/forgejo-backup.log 2>&1"
|
||||
@echo ""
|
||||
|
||||
## Setup Wizard
|
||||
wizard: ## Run interactive setup wizard (recommended for first-time setup)
|
||||
|
|
@ -157,10 +217,18 @@ backup: ssh-agent-check ## Create backup of Forgejo
|
|||
@ansible-playbook -i $(INVENTORY) $(PLAYBOOK_DIR)/backup.yml --ask-vault-pass
|
||||
@echo "$(GREEN)✓ Backup complete$(NC)"
|
||||
|
||||
backup-cron: ## Create backup non-interactively (for cron jobs)
|
||||
@test -f $(VAULT_PASSWORD_FILE) || { echo "$(RED)Error: Vault password file not found at $(VAULT_PASSWORD_FILE)$(NC)"; echo "Create it with: echo 'your-vault-password' > $(VAULT_PASSWORD_FILE) && chmod 600 $(VAULT_PASSWORD_FILE)"; exit 1; }
|
||||
@ansible-playbook -i $(INVENTORY) $(PLAYBOOK_DIR)/backup.yml --vault-password-file $(VAULT_PASSWORD_FILE)
|
||||
|
||||
backup-to-s3: ssh-agent-check ## Create backup and upload to S3
|
||||
@echo "$(GREEN)Creating backup and uploading to S3...$(NC)"
|
||||
@ansible-playbook -i $(INVENTORY) $(PLAYBOOK_DIR)/backup.yml --ask-vault-pass --extra-vars "upload_to_s3=true"
|
||||
|
||||
backup-cron-s3: ## Create backup and upload to S3 (for cron jobs)
|
||||
@test -f $(VAULT_PASSWORD_FILE) || { echo "$(RED)Error: Vault password file not found at $(VAULT_PASSWORD_FILE)$(NC)"; exit 1; }
|
||||
@ansible-playbook -i $(INVENTORY) $(PLAYBOOK_DIR)/backup.yml --vault-password-file $(VAULT_PASSWORD_FILE) --extra-vars "upload_to_s3=true"
|
||||
|
||||
## Restore Commands
|
||||
restore: ssh-agent-check ## Restore Forgejo from backup
|
||||
@echo "$(RED)WARNING: This will restore from backup$(NC)"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,18 @@
|
|||
upload_to_s3: "{{ forgejo_backup_to_s3 | default(false) }}"
|
||||
|
||||
pre_tasks:
|
||||
- name: Load role defaults as fallback
|
||||
ansible.builtin.include_vars:
|
||||
file: ../roles/forgejo/defaults/main.yml
|
||||
name: role_defaults
|
||||
|
||||
- name: Apply all role defaults for undefined variables
|
||||
ansible.builtin.set_fact:
|
||||
"{{ item.key }}": "{{ vars[item.key] | default(item.value) }}"
|
||||
loop: "{{ role_defaults | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Display backup information
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
|
|
@ -37,10 +49,15 @@
|
|||
community.postgresql.postgresql_db:
|
||||
name: "{{ forgejo_db_name }}"
|
||||
state: dump
|
||||
target: "{{ forgejo_backup_path }}/database-{{ backup_timestamp }}.sql"
|
||||
target: "/tmp/database-{{ backup_timestamp }}.sql"
|
||||
become_user: postgres
|
||||
when: forgejo_db_type == 'postgres'
|
||||
|
||||
- name: Move database backup to backup directory
|
||||
ansible.builtin.command:
|
||||
cmd: mv /tmp/database-{{ backup_timestamp }}.sql {{ forgejo_backup_path }}/database-{{ backup_timestamp }}.sql
|
||||
when: forgejo_db_type == 'postgres'
|
||||
|
||||
- name: Compress database backup
|
||||
community.general.archive:
|
||||
path: "{{ forgejo_backup_path }}/database-{{ backup_timestamp }}.sql"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,18 @@
|
|||
force_restore: false
|
||||
|
||||
pre_tasks:
|
||||
- name: Load role defaults as fallback
|
||||
ansible.builtin.include_vars:
|
||||
file: ../roles/forgejo/defaults/main.yml
|
||||
name: role_defaults
|
||||
|
||||
- name: Apply all role defaults for undefined variables
|
||||
ansible.builtin.set_fact:
|
||||
"{{ item.key }}": "{{ vars[item.key] | default(item.value) }}"
|
||||
loop: "{{ role_defaults | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Validate backup timestamp
|
||||
ansible.builtin.fail:
|
||||
msg: "Please provide backup_timestamp via --extra-vars 'backup_timestamp=20240115T120000'"
|
||||
|
|
@ -100,9 +112,15 @@
|
|||
register: db_backup
|
||||
failed_when: not db_backup.stat.exists
|
||||
|
||||
- name: Check if monitoring compose file exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ forgejo_base_path }}/docker-compose.monitoring.yml"
|
||||
register: monitoring_compose
|
||||
|
||||
- name: Stop Forgejo service
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ forgejo_base_path }}"
|
||||
files: "{{ ['docker-compose.yml', 'docker-compose.monitoring.yml'] if monitoring_compose.stat.exists else ['docker-compose.yml'] }}"
|
||||
state: stopped
|
||||
|
||||
- name: Restore PostgreSQL database
|
||||
|
|
@ -180,6 +198,7 @@
|
|||
- name: Start Forgejo service
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ forgejo_base_path }}"
|
||||
files: "{{ ['docker-compose.yml', 'docker-compose.monitoring.yml'] if monitoring_compose.stat.exists else ['docker-compose.yml'] }}"
|
||||
state: present
|
||||
|
||||
- name: Wait for Forgejo to be ready
|
||||
|
|
@ -193,7 +212,7 @@
|
|||
|
||||
- name: Run integrity checks
|
||||
ansible.builtin.command:
|
||||
cmd: docker exec forgejo forgejo doctor check --all
|
||||
cmd: docker exec --user {{ forgejo_user }} forgejo forgejo doctor check --all
|
||||
register: integrity_check
|
||||
failed_when: false
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,18 @@
|
|||
skip_backup: false # Override with --extra-vars "skip_backup=true"
|
||||
|
||||
pre_tasks:
|
||||
- name: Load role defaults as fallback
|
||||
ansible.builtin.include_vars:
|
||||
file: ../roles/forgejo/defaults/main.yml
|
||||
name: role_defaults
|
||||
|
||||
- name: Apply all role defaults for undefined variables
|
||||
ansible.builtin.set_fact:
|
||||
"{{ item.key }}": "{{ vars[item.key] | default(item.value) }}"
|
||||
loop: "{{ role_defaults | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: Display update information
|
||||
ansible.builtin.debug:
|
||||
msg: |
|
||||
|
|
@ -24,7 +36,7 @@
|
|||
|
||||
- name: Check current Forgejo version
|
||||
ansible.builtin.command:
|
||||
cmd: docker exec forgejo forgejo --version
|
||||
cmd: docker exec --user {{ forgejo_user }} forgejo forgejo --version
|
||||
register: current_version
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
|
@ -46,9 +58,15 @@
|
|||
ansible.builtin.debug:
|
||||
msg: "Backup completed: {{ backup_result.stdout_lines[-1] if backup_result.stdout_lines else 'No output' }}"
|
||||
|
||||
- name: Check if monitoring compose file exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ forgejo_base_path }}/docker-compose.monitoring.yml"
|
||||
register: monitoring_compose
|
||||
|
||||
- name: Stop Forgejo service
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ forgejo_base_path }}"
|
||||
files: "{{ ['docker-compose.yml', 'docker-compose.monitoring.yml'] if monitoring_compose.stat.exists else ['docker-compose.yml'] }}"
|
||||
state: stopped
|
||||
|
||||
- name: Pull latest Forgejo image
|
||||
|
|
@ -68,6 +86,7 @@
|
|||
- name: Start Forgejo service
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ forgejo_base_path }}"
|
||||
files: "{{ ['docker-compose.yml', 'docker-compose.monitoring.yml'] if monitoring_compose.stat.exists else ['docker-compose.yml'] }}"
|
||||
state: present
|
||||
pull: always
|
||||
|
||||
|
|
@ -82,7 +101,7 @@
|
|||
|
||||
- name: Check updated version
|
||||
ansible.builtin.command:
|
||||
cmd: docker exec forgejo forgejo --version
|
||||
cmd: docker exec --user {{ forgejo_user }} forgejo forgejo --version
|
||||
register: updated_version
|
||||
changed_when: false
|
||||
|
||||
|
|
@ -92,7 +111,7 @@
|
|||
|
||||
- name: Run database migrations
|
||||
ansible.builtin.command:
|
||||
cmd: docker exec forgejo forgejo migrate
|
||||
cmd: docker exec --user {{ forgejo_user }} forgejo forgejo migrate
|
||||
register: migrate_result
|
||||
changed_when: "'No migration needed' not in migrate_result.stdout"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue