ansible
This commit is contained in:
parent
b81f7e15b2
commit
67414814c0
23 changed files with 310 additions and 190 deletions
|
|
@ -179,7 +179,7 @@ git clone git@git.asxp.io:asxpi/infrastructure.git
|
||||||
ansible-playbook playbooks/wireguard.yaml
|
ansible-playbook playbooks/wireguard.yaml
|
||||||
ansible-playbook playbooks/wireguard-client.yaml
|
ansible-playbook playbooks/wireguard-client.yaml
|
||||||
|
|
||||||
# 2. Harden SSH
|
# 2. Harden SSH (Switch to WireGuard IP's in hosts.yaml before applying)
|
||||||
ansible-playbook playbooks/ssh-harden.yaml
|
ansible-playbook playbooks/ssh-harden.yaml
|
||||||
|
|
||||||
# 3. Deploy reverse proxy
|
# 3. Deploy reverse proxy
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ forgejo_ssh_port: 2222 # External port (container uses 22)
|
||||||
forgejo_runner_version: "11"
|
forgejo_runner_version: "11"
|
||||||
forgejo_runner_capacity: 1
|
forgejo_runner_capacity: 1
|
||||||
forgejo_runner_timeout: 3h
|
forgejo_runner_timeout: 3h
|
||||||
|
forgejo_runner_token: "***REDACTED***"
|
||||||
|
|
||||||
# Backup configuration
|
# Backup configuration
|
||||||
backup_dest_dir: /tmp/forgejo-backups
|
backup_dest_dir: /opt/forgejo-backup
|
||||||
backup_old_server: 10.0.0.1
|
backup_old_server: asxpio-old
|
||||||
|
|
@ -45,3 +45,11 @@ wireguard_dns_servers:
|
||||||
# SSH Hardening Configuration
|
# SSH Hardening Configuration
|
||||||
# Allow public SSH access for Forgejo git operations
|
# Allow public SSH access for Forgejo git operations
|
||||||
ssh_allow_public_git: true
|
ssh_allow_public_git: true
|
||||||
|
ssh_git_user: git
|
||||||
|
|
||||||
|
# Forgejo secrets (from old server)
|
||||||
|
forgejo_secret_key: "***REDACTED***"
|
||||||
|
forgejo_internal_token: "***REDACTED***"
|
||||||
|
forgejo_jwt_secret: "***REDACTED***"
|
||||||
|
forgejo_lfs_jwt_secret: "***REDACTED***"
|
||||||
|
letsencrypt_email: "me@asxp.io"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ all:
|
||||||
ops_servers:
|
ops_servers:
|
||||||
hosts:
|
hosts:
|
||||||
asxpio-ops:
|
asxpio-ops:
|
||||||
ansible_host: 10.20.0.10 #65.109.14.216
|
ansible_host: 10.20.0.10
|
||||||
|
#ansible_host: 65.109.14.216
|
||||||
server_role: ops
|
server_role: ops
|
||||||
server_type: cx22
|
server_type: cx22
|
||||||
services:
|
services:
|
||||||
|
|
@ -32,7 +33,8 @@ all:
|
||||||
services_servers:
|
services_servers:
|
||||||
hosts:
|
hosts:
|
||||||
asxpio-services:
|
asxpio-services:
|
||||||
ansible_host: 10.20.0.20 #95.217.15.42
|
ansible_host: 10.20.0.20
|
||||||
|
#ansible_host: 95.217.15.42
|
||||||
server_role: services
|
server_role: services
|
||||||
server_type: cx43
|
server_type: cx43
|
||||||
services:
|
services:
|
||||||
|
|
@ -43,3 +45,10 @@ all:
|
||||||
- factorio
|
- factorio
|
||||||
- prosody
|
- prosody
|
||||||
- coturn
|
- coturn
|
||||||
|
|
||||||
|
old_servers:
|
||||||
|
hosts:
|
||||||
|
asxpio-old:
|
||||||
|
ansible_host: asxp.io
|
||||||
|
server_role: legacy
|
||||||
|
ansible_user: asxpi
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: Backup Forgejo from old server
|
- name: Backup Forgejo from old server
|
||||||
hosts: "{{ backup_old_server }}"
|
hosts: asxpio-old
|
||||||
become: true
|
become: true
|
||||||
vars:
|
|
||||||
ansible_host: "{{ backup_old_server }}"
|
|
||||||
roles:
|
roles:
|
||||||
- forgejo_backup
|
- forgejo_backup
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: Harden SSH configuration
|
- name: Harden SSH configuration
|
||||||
hosts: asxpio
|
hosts: asxpio:!old_servers
|
||||||
become: true
|
become: true
|
||||||
roles:
|
roles:
|
||||||
- ssh_hardening
|
- ssh_hardening
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,8 @@
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: /opt/forgejo
|
project_src: /opt/forgejo
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
|
- name: Reload SSH daemon
|
||||||
|
systemd:
|
||||||
|
name: sshd
|
||||||
|
state: reloaded
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
---
|
---
|
||||||
|
- name: Configure SSH passthrough
|
||||||
|
import_tasks: ssh-passthrough.yaml
|
||||||
|
|
||||||
- name: Create Forgejo directories
|
- name: Create Forgejo directories
|
||||||
file:
|
file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
|
|
|
||||||
45
ansible/roles/forgejo/tasks/ssh-passthrough.yaml
Normal file
45
ansible/roles/forgejo/tasks/ssh-passthrough.yaml
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
---
|
||||||
|
- name: Create git user on host
|
||||||
|
user:
|
||||||
|
name: git
|
||||||
|
comment: "Forgejo Git User"
|
||||||
|
home: /var/lib/git
|
||||||
|
shell: /usr/local/bin/forgejo-shell
|
||||||
|
system: yes
|
||||||
|
create_home: yes
|
||||||
|
|
||||||
|
- name: Deploy forgejo-shell wrapper script
|
||||||
|
template:
|
||||||
|
src: forgejo-shell.j2
|
||||||
|
dest: /usr/local/bin/forgejo-shell
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create .ssh directory for git user
|
||||||
|
file:
|
||||||
|
path: /var/lib/git/.ssh
|
||||||
|
state: directory
|
||||||
|
owner: git
|
||||||
|
group: git
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: Deploy SSH daemon configuration for Forgejo passthrough
|
||||||
|
template:
|
||||||
|
src: sshd-forgejo.conf.j2
|
||||||
|
dest: /etc/ssh/sshd_config.d/forgejo.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
notify: Reload SSH daemon
|
||||||
|
|
||||||
|
- name: Ensure docker group exists
|
||||||
|
group:
|
||||||
|
name: docker
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add git user to docker group
|
||||||
|
user:
|
||||||
|
name: git
|
||||||
|
groups: docker
|
||||||
|
append: yes
|
||||||
|
|
@ -8,15 +8,15 @@ ROOT_URL = https://{{ forgejo_domain }}/
|
||||||
HTTP_PORT = 3000
|
HTTP_PORT = 3000
|
||||||
DISABLE_SSH = false
|
DISABLE_SSH = false
|
||||||
SSH_DOMAIN = {{ forgejo_domain }}
|
SSH_DOMAIN = {{ forgejo_domain }}
|
||||||
SSH_PORT = {{ forgejo_ssh_port }}
|
SSH_PORT = 22
|
||||||
SSH_LISTEN_PORT = 22
|
SSH_LISTEN_PORT = 22
|
||||||
START_SSH_SERVER = true
|
START_SSH_SERVER = false
|
||||||
LFS_START_SERVER = true
|
LFS_START_SERVER = true
|
||||||
OFFLINE_MODE = false
|
OFFLINE_MODE = false
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
DB_TYPE = sqlite3
|
DB_TYPE = sqlite3
|
||||||
PATH = /data/gitea/gitea.db
|
PATH = /data/gitea.db
|
||||||
LOG_SQL = false
|
LOG_SQL = false
|
||||||
|
|
||||||
[repository]
|
[repository]
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ services:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "{{ forgejo_http_port }}:3000"
|
- "{{ forgejo_http_port }}:3000"
|
||||||
- "{{ forgejo_ssh_port }}:22"
|
|
||||||
networks:
|
networks:
|
||||||
- {{ traefik_network }}
|
- {{ traefik_network }}
|
||||||
labels:
|
labels:
|
||||||
|
|
|
||||||
4
ansible/roles/forgejo/templates/forgejo-shell.j2
Normal file
4
ansible/roles/forgejo/templates/forgejo-shell.j2
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Forgejo SSH passthrough wrapper
|
||||||
|
# Relays SSH commands to Forgejo container
|
||||||
|
docker exec -i -u git --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" forgejo sh "$@"
|
||||||
6
ansible/roles/forgejo/templates/sshd-forgejo.conf.j2
Normal file
6
ansible/roles/forgejo/templates/sshd-forgejo.conf.j2
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Forgejo SSH passthrough configuration
|
||||||
|
# Delegates SSH key authentication for git user to Forgejo container
|
||||||
|
|
||||||
|
Match User git
|
||||||
|
AuthorizedKeysCommand /usr/bin/docker exec -i -u git forgejo /usr/local/bin/forgejo keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k
|
||||||
|
AuthorizedKeysCommandUser git
|
||||||
|
|
@ -1,79 +1,67 @@
|
||||||
---
|
---
|
||||||
- name: Create local backup directory
|
- name: Create backup directory on ops server
|
||||||
file:
|
file:
|
||||||
path: "{{ backup_dest_dir }}"
|
path: "{{ backup_dest_dir }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
delegate_to: localhost
|
owner: asxpi
|
||||||
become: false
|
group: asxpi
|
||||||
|
delegate_to: asxpio-ops
|
||||||
|
become: true
|
||||||
|
|
||||||
- name: Check if Forgejo service is running on old server
|
- name: Find existing Forgejo dump files on old server
|
||||||
systemd:
|
|
||||||
name: forgejo
|
|
||||||
register: forgejo_service
|
|
||||||
|
|
||||||
- name: Stop Forgejo service temporarily for backup
|
|
||||||
systemd:
|
|
||||||
name: forgejo
|
|
||||||
state: stopped
|
|
||||||
when: forgejo_service.status.ActiveState == "active"
|
|
||||||
|
|
||||||
- name: Create Forgejo dump backup
|
|
||||||
command: >
|
|
||||||
/usr/bin/forgejo dump
|
|
||||||
-c /etc/forgejo/app.ini
|
|
||||||
-w /srv/gitea
|
|
||||||
--tempdir /tmp
|
|
||||||
args:
|
|
||||||
chdir: /srv/gitea
|
|
||||||
register: dump_output
|
|
||||||
|
|
||||||
- name: Get dump filename
|
|
||||||
find:
|
find:
|
||||||
paths: /srv/gitea
|
paths: /srv/gitea
|
||||||
patterns: "gitea-dump-*.zip"
|
patterns: "*.zip"
|
||||||
register: dump_file
|
file_type: file
|
||||||
|
register: existing_dumps
|
||||||
|
|
||||||
- name: Create additional backup archive
|
- name: Create backup archive from old server
|
||||||
archive:
|
archive:
|
||||||
path:
|
path:
|
||||||
- /srv/gitea/gitea.db
|
- /srv/gitea/gitea.db
|
||||||
- /srv/gitea/data
|
- /srv/gitea/data/avatars
|
||||||
- /var/lib/forgejo/.ssh
|
- /srv/gitea/data/repo-avatars
|
||||||
- /var/lib/forgejo-runner/.runner
|
- /srv/gitea/data/repo-archive
|
||||||
dest: /tmp/forgejo-additional-{{ ansible_date_time.date }}.tar.gz
|
- /srv/gitea/data/attachments
|
||||||
|
- /srv/gitea/data/gitea-repositories
|
||||||
|
dest: /tmp/forgejo-full-backup-{{ ansible_date_time.date }}.tar.gz
|
||||||
format: gz
|
format: gz
|
||||||
ignore_errors: true
|
become: true
|
||||||
|
|
||||||
- name: Fetch dump file to local machine
|
- name: Display found backup files
|
||||||
fetch:
|
|
||||||
src: "{{ dump_file.files[0].path }}"
|
|
||||||
dest: "{{ backup_dest_dir }}/"
|
|
||||||
flat: true
|
|
||||||
when: dump_file.files | length > 0
|
|
||||||
|
|
||||||
- name: Fetch additional backup to local machine
|
|
||||||
fetch:
|
|
||||||
src: /tmp/forgejo-additional-{{ ansible_date_time.date }}.tar.gz
|
|
||||||
dest: "{{ backup_dest_dir }}/"
|
|
||||||
flat: true
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Start Forgejo service
|
|
||||||
systemd:
|
|
||||||
name: forgejo
|
|
||||||
state: started
|
|
||||||
when: forgejo_service.status.ActiveState == "active"
|
|
||||||
|
|
||||||
- name: Display backup information
|
|
||||||
debug:
|
debug:
|
||||||
msg: |
|
msg: |
|
||||||
Forgejo backup completed successfully!
|
Found {{ existing_dumps.files | length }} dump files
|
||||||
|
Created full backup archive: /tmp/forgejo-full-backup-{{ ansible_date_time.date }}.tar.gz
|
||||||
|
|
||||||
Backup files saved to: {{ backup_dest_dir }}/
|
- name: Fetch dump file to ops server (if exists)
|
||||||
- Forgejo dump: {{ dump_file.files[0].path | basename }}
|
synchronize:
|
||||||
- Additional data: forgejo-additional-{{ ansible_date_time.date }}.tar.gz
|
mode: pull
|
||||||
|
src: "{{ (existing_dumps.files | sort(attribute='mtime', reverse=true) | first).path }}"
|
||||||
|
dest: /opt/forgejo-backup/
|
||||||
|
delegate_to: asxpio-ops
|
||||||
|
when: existing_dumps.files | length > 0
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
Next steps:
|
- name: Fetch full backup archive to ops server
|
||||||
1. Verify backup integrity
|
synchronize:
|
||||||
2. Run restore playbook: ansible-playbook playbooks/restore-forgejo.yaml
|
mode: pull
|
||||||
|
src: /tmp/forgejo-full-backup-{{ ansible_date_time.date }}.tar.gz
|
||||||
|
dest: /opt/forgejo-backup/
|
||||||
|
delegate_to: asxpio-ops
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Display backup location
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
Backup files transferred to asxpio-ops:/opt/forgejo-backup/
|
||||||
|
|
||||||
|
Files:
|
||||||
|
- forgejo-full-backup-{{ ansible_date_time.date }}.tar.gz (complete backup)
|
||||||
|
{% if existing_dumps.files | length > 0 %}
|
||||||
|
- {{ (existing_dumps.files | sort(attribute='mtime', reverse=true) | first).path | basename }} (dump file)
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Next step: Run restore playbook
|
||||||
|
ansible-playbook playbooks/restore-forgejo.yaml
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,112 @@
|
||||||
---
|
---
|
||||||
|
- name: Find backup files on server
|
||||||
|
find:
|
||||||
|
paths: "{{ backup_dest_dir }}"
|
||||||
|
patterns: "forgejo-full-backup-*.tar.gz"
|
||||||
|
register: server_backup_files
|
||||||
|
|
||||||
|
- name: Fail if no backup files found
|
||||||
|
fail:
|
||||||
|
msg: "No backup files found in {{ backup_dest_dir }}. Please run backup-forgejo.yaml first."
|
||||||
|
when: server_backup_files.files | length == 0
|
||||||
|
|
||||||
|
- name: Select most recent backup file
|
||||||
|
set_fact:
|
||||||
|
backup_file: "{{ (server_backup_files.files | sort(attribute='mtime', reverse=true) | first).path }}"
|
||||||
|
|
||||||
|
- name: Display backup file to be restored
|
||||||
|
debug:
|
||||||
|
msg: "Restoring from: {{ backup_file }}"
|
||||||
|
|
||||||
- name: Stop Forgejo container
|
- name: Stop Forgejo container
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: /opt/forgejo
|
project_src: /opt/forgejo
|
||||||
state: stopped
|
state: stopped
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Find backup dump file locally
|
- name: Backup current Forgejo data (if exists)
|
||||||
find:
|
archive:
|
||||||
paths: "{{ backup_dest_dir }}"
|
path: /opt/forgejo/data
|
||||||
patterns: "gitea-dump-*.zip"
|
dest: "/opt/forgejo/data-backup-{{ ansible_date_time.epoch }}.tar.gz"
|
||||||
delegate_to: localhost
|
format: gz
|
||||||
become: false
|
ignore_errors: true
|
||||||
register: local_dump_file
|
|
||||||
|
|
||||||
- name: Find additional backup file locally
|
- name: Remove old data directory
|
||||||
find:
|
|
||||||
paths: "{{ backup_dest_dir }}"
|
|
||||||
patterns: "forgejo-additional-*.tar.gz"
|
|
||||||
delegate_to: localhost
|
|
||||||
become: false
|
|
||||||
register: local_additional_file
|
|
||||||
|
|
||||||
- name: Fail if no backup files found
|
|
||||||
fail:
|
|
||||||
msg: "No backup files found in {{ backup_dest_dir }}. Please run backup-forgejo.yaml first."
|
|
||||||
when: local_dump_file.files | length == 0
|
|
||||||
|
|
||||||
- name: Copy dump backup to server
|
|
||||||
copy:
|
|
||||||
src: "{{ local_dump_file.files[0].path }}"
|
|
||||||
dest: /tmp/forgejo-dump.zip
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
- name: Copy additional backup to server
|
|
||||||
copy:
|
|
||||||
src: "{{ local_additional_file.files[0].path }}"
|
|
||||||
dest: /tmp/forgejo-additional.tar.gz
|
|
||||||
mode: '0644'
|
|
||||||
when: local_additional_file.files | length > 0
|
|
||||||
|
|
||||||
- name: Extract Forgejo dump
|
|
||||||
unarchive:
|
|
||||||
src: /tmp/forgejo-dump.zip
|
|
||||||
dest: /opt/forgejo/
|
|
||||||
remote_src: true
|
|
||||||
creates: /opt/forgejo/app.ini
|
|
||||||
|
|
||||||
- name: Extract additional backup
|
|
||||||
unarchive:
|
|
||||||
src: /tmp/forgejo-additional.tar.gz
|
|
||||||
dest: /tmp/forgejo-restore/
|
|
||||||
remote_src: true
|
|
||||||
when: local_additional_file.files | length > 0
|
|
||||||
|
|
||||||
- name: Ensure data directory exists
|
|
||||||
file:
|
file:
|
||||||
path: /opt/forgejo/data
|
path: /opt/forgejo/data
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Create fresh data directory structure
|
||||||
|
file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
owner: 1000
|
||||||
|
group: 1000
|
||||||
|
mode: "{{ item.mode | default('0755') }}"
|
||||||
|
loop:
|
||||||
|
- { path: '/opt/forgejo/data' }
|
||||||
|
- { path: '/opt/forgejo/data/gitea' }
|
||||||
|
- { path: '/opt/forgejo/data/gitea/data' }
|
||||||
|
- { path: '/opt/forgejo/data/git' }
|
||||||
|
- { path: '/opt/forgejo/data/git/repositories' }
|
||||||
|
- { path: '/opt/forgejo/data/git/.ssh', mode: '0700' }
|
||||||
|
|
||||||
|
- name: Create temporary restore directory
|
||||||
|
file:
|
||||||
|
path: /tmp/forgejo-restore
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
- name: Copy database from dump to data directory
|
- name: Extract backup to temporary location
|
||||||
copy:
|
unarchive:
|
||||||
src: /opt/forgejo/data/gitea.db
|
src: "{{ backup_file }}"
|
||||||
dest: /opt/forgejo/data/gitea.db
|
dest: /tmp/forgejo-restore/
|
||||||
remote_src: true
|
remote_src: true
|
||||||
force: true
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Copy repository data from additional backup
|
- name: Copy database from backup
|
||||||
|
copy:
|
||||||
|
src: /tmp/forgejo-restore/gitea.db
|
||||||
|
dest: /opt/forgejo/data/gitea/gitea.db
|
||||||
|
remote_src: true
|
||||||
|
owner: 1000
|
||||||
|
group: 1000
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Copy avatars from backup
|
||||||
synchronize:
|
synchronize:
|
||||||
src: /tmp/forgejo-restore/srv/gitea/data/
|
src: /tmp/forgejo-restore/data/avatars/
|
||||||
dest: /opt/forgejo/data/
|
dest: /opt/forgejo/data/gitea/data/avatars/
|
||||||
delegate_to: "{{ inventory_hostname }}"
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
when: local_additional_file.files | length > 0
|
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Copy SSH keys from additional backup
|
- name: Copy repo-avatars from backup
|
||||||
synchronize:
|
synchronize:
|
||||||
src: /tmp/forgejo-restore/var/lib/forgejo/.ssh/
|
src: /tmp/forgejo-restore/data/repo-avatars/
|
||||||
dest: /opt/forgejo/data/.ssh/
|
dest: /opt/forgejo/data/gitea/data/repo-avatars/
|
||||||
delegate_to: "{{ inventory_hostname }}"
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
when: local_additional_file.files | length > 0
|
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Set correct ownership for Forgejo data
|
- name: Copy repo-archive from backup
|
||||||
|
synchronize:
|
||||||
|
src: /tmp/forgejo-restore/data/repo-archive/
|
||||||
|
dest: /opt/forgejo/data/gitea/data/repo-archive/
|
||||||
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Copy attachments from backup
|
||||||
|
synchronize:
|
||||||
|
src: /tmp/forgejo-restore/data/attachments/
|
||||||
|
dest: /opt/forgejo/data/gitea/data/attachments/
|
||||||
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Copy repositories from backup
|
||||||
|
synchronize:
|
||||||
|
src: /tmp/forgejo-restore/data/gitea-repositories/
|
||||||
|
dest: /opt/forgejo/data/git/repositories/
|
||||||
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
|
|
||||||
|
- name: Set correct ownership for all Forgejo data
|
||||||
file:
|
file:
|
||||||
path: /opt/forgejo/data
|
path: /opt/forgejo/data
|
||||||
owner: 1000
|
owner: 1000
|
||||||
|
|
@ -96,34 +119,37 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Wait for Forgejo to be healthy
|
- name: Wait for Forgejo to be healthy
|
||||||
uri:
|
wait_for:
|
||||||
url: http://localhost:{{ forgejo_http_port }}/
|
host: localhost
|
||||||
status_code: 200
|
port: "{{ forgejo_http_port }}"
|
||||||
retries: 15
|
timeout: 60
|
||||||
delay: 5
|
delay: 5
|
||||||
register: result
|
|
||||||
until: result.status == 200
|
|
||||||
|
|
||||||
- name: Clean up temporary files
|
- name: Clean up temporary files
|
||||||
file:
|
file:
|
||||||
path: "{{ item }}"
|
path: /tmp/forgejo-restore
|
||||||
state: absent
|
state: absent
|
||||||
loop:
|
|
||||||
- /tmp/forgejo-dump.zip
|
- name: Verify users in database
|
||||||
- /tmp/forgejo-additional.tar.gz
|
shell: docker exec -u git forgejo forgejo admin user list
|
||||||
- /tmp/forgejo-restore
|
register: user_list
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Display restore information
|
- name: Display restore information
|
||||||
debug:
|
debug:
|
||||||
msg: |
|
msg: |
|
||||||
Forgejo restore completed successfully!
|
Forgejo restore completed successfully!
|
||||||
|
|
||||||
|
Users:
|
||||||
|
{{ user_list.stdout }}
|
||||||
|
|
||||||
Forgejo is now running at:
|
Forgejo is now running at:
|
||||||
- Internal: http://localhost:{{ forgejo_http_port }}
|
- Internal: http://localhost:{{ forgejo_http_port }}
|
||||||
- External: https://{{ forgejo_domain }}
|
- External: https://{{ forgejo_domain }}
|
||||||
|
|
||||||
Next steps:
|
Next steps:
|
||||||
1. Test git operations: git clone https://{{ forgejo_domain }}/user/repo.git
|
1. Test web interface: https://{{ forgejo_domain }}
|
||||||
2. Test SSH access: git clone git@{{ forgejo_domain }}:user/repo.git
|
2. Verify avatars and images are visible
|
||||||
3. Test web interface at https://{{ forgejo_domain }}
|
3. Test login with your credentials
|
||||||
4. Register runners with the new instance
|
4. Test git clone: git clone https://{{ forgejo_domain }}/user/repo.git
|
||||||
|
5. Check logs: docker logs forgejo
|
||||||
|
|
|
||||||
|
|
@ -29,17 +29,58 @@
|
||||||
state: present
|
state: present
|
||||||
register: runner_output
|
register: runner_output
|
||||||
|
|
||||||
- name: Display runner registration instructions
|
- name: Check if runner is already registered
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /opt/forgejo-runner/data/.runner
|
||||||
|
register: runner_registered
|
||||||
|
|
||||||
|
- name: Set permissions on data directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /opt/forgejo-runner/data
|
||||||
|
state: directory
|
||||||
|
mode: '0777'
|
||||||
|
recurse: true
|
||||||
|
when: not runner_registered.stat.exists
|
||||||
|
|
||||||
|
- name: Stop runner for registration
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: /opt/forgejo-runner
|
||||||
|
state: stopped
|
||||||
|
when: not runner_registered.stat.exists
|
||||||
|
|
||||||
|
- name: Register runner with Forgejo
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
docker run --rm
|
||||||
|
-v /opt/forgejo-runner/data:/data
|
||||||
|
-v /opt/forgejo-runner/config/config.yaml:/config.yaml
|
||||||
|
code.forgejo.org/forgejo/runner:{{ forgejo_runner_version }}
|
||||||
|
forgejo-runner register
|
||||||
|
--no-interactive
|
||||||
|
--token {{ forgejo_runner_token }}
|
||||||
|
--name runner-{{ inventory_hostname }}
|
||||||
|
--instance http://10.10.0.10:{{ forgejo_http_port }}
|
||||||
|
--labels ubuntu-latest:docker://node:20-bookworm,ubuntu-22.04:docker://node:20-bookworm,ubuntu-24.04:docker://node:22-bookworm,debian-latest:docker://debian:bookworm,debian-12:docker://debian:bookworm,debian-11:docker://debian:bullseye,arch-latest:docker://archlinux:latest,nginx-latest:docker://nginx:latest,nginx-alpine:docker://nginx:alpine,node-20:docker://node:20,node-22:docker://node:22,python-3.11:docker://python:3.11,python-3.12:docker://python:3.12,alpine-latest:docker://alpine:latest
|
||||||
|
when: not runner_registered.stat.exists
|
||||||
|
register: registration_result
|
||||||
|
|
||||||
|
- name: Start runner after registration
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: /opt/forgejo-runner
|
||||||
|
state: present
|
||||||
|
when: not runner_registered.stat.exists
|
||||||
|
|
||||||
|
- name: Display runner status
|
||||||
debug:
|
debug:
|
||||||
msg: |
|
msg: |
|
||||||
Forgejo Runner deployed successfully!
|
Forgejo Runner deployed successfully!
|
||||||
|
|
||||||
To register the runner with Forgejo:
|
Runner name: runner-{{ inventory_hostname }}
|
||||||
1. Log in to Forgejo at https://{{ forgejo_domain }}
|
Forgejo instance: http://10.10.0.10:{{ forgejo_http_port }}
|
||||||
2. Go to Site Administration > Actions > Runners
|
{% if runner_registered.stat.exists %}
|
||||||
3. Generate a registration token
|
Status: Already registered (using existing registration)
|
||||||
4. Run: docker exec -it forgejo-runner forgejo-runner register --no-interactive \
|
{% else %}
|
||||||
--token YOUR_TOKEN \
|
Status: Newly registered
|
||||||
--name runner-{{ inventory_hostname }} \
|
{% endif %}
|
||||||
--instance http://10.10.0.10:{{ forgejo_http_port }}
|
|
||||||
5. Restart the runner: cd /opt/forgejo-runner && docker compose restart
|
Check runner status: docker logs forgejo-runner
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ services:
|
||||||
image: code.forgejo.org/forgejo/runner:{{ forgejo_runner_version }}
|
image: code.forgejo.org/forgejo/runner:{{ forgejo_runner_version }}
|
||||||
container_name: forgejo-runner
|
container_name: forgejo-runner
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
user: "0:0" # Run as root to access docker socket
|
||||||
|
command: forgejo-runner daemon
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/data
|
- ./data:/data
|
||||||
- ./config/config.yaml:/config.yaml
|
- ./config/config.yaml:/config.yaml
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ ssh_shell_users:
|
||||||
- root
|
- root
|
||||||
|
|
||||||
# Git user for Forgejo (allowed from anywhere when ssh_allow_public_git is true)
|
# Git user for Forgejo (allowed from anywhere when ssh_allow_public_git is true)
|
||||||
ssh_git_user: forgejo
|
ssh_git_user: git
|
||||||
|
|
||||||
# SSH hardening settings
|
# SSH hardening settings
|
||||||
ssh_max_auth_tries: 3
|
ssh_max_auth_tries: 3
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,8 @@
|
||||||
register: traefik_output
|
register: traefik_output
|
||||||
|
|
||||||
- name: Wait for Traefik to be healthy
|
- name: Wait for Traefik to be healthy
|
||||||
uri:
|
wait_for:
|
||||||
url: http://localhost:8080/ping
|
host: "{{ wireguard_ipv4 }}"
|
||||||
status_code: 200
|
port: 8080
|
||||||
retries: 10
|
timeout: 30
|
||||||
delay: 3
|
delay: 3
|
||||||
register: result
|
|
||||||
until: result.status == 200
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
- "10.20.0.10:8080:8080" # Dashboard only on WireGuard IP
|
- "{{ wireguard_ipv4 }}:8080:8080" # Dashboard only on WireGuard IP
|
||||||
environment:
|
environment:
|
||||||
- TZ=UTC
|
- TZ=UTC
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
||||||
|
|
@ -106,12 +106,6 @@ runcmd:
|
||||||
# Fix home directory ownership for deploy user
|
# Fix home directory ownership for deploy user
|
||||||
- chown deploy:deploy /home/deploy
|
- chown deploy:deploy /home/deploy
|
||||||
|
|
||||||
# Create directory structure for services
|
|
||||||
- mkdir -p /opt/{traefik,forgejo,grafana,prometheus,loki,promtail,static-sites}
|
|
||||||
- mkdir -p /opt/traefik/config
|
|
||||||
- mkdir -p /opt/static-sites/{asxp.io,czsk.it,childfr.ee,builds,upload}
|
|
||||||
- chown -R asxpi:asxpi /opt/*
|
|
||||||
|
|
||||||
# Set up weekly Docker image pruning
|
# Set up weekly Docker image pruning
|
||||||
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,13 +106,6 @@ runcmd:
|
||||||
# Fix home directory ownership for deploy user
|
# Fix home directory ownership for deploy user
|
||||||
- chown deploy:deploy /home/deploy
|
- chown deploy:deploy /home/deploy
|
||||||
|
|
||||||
# Create directory structure for services
|
|
||||||
- mkdir -p /opt/{forgejo-runner,immich,minecraft,valheim,factorio,prosody,coturn}
|
|
||||||
- mkdir -p /opt/minecraft/{data,backups}
|
|
||||||
- mkdir -p /opt/valheim/data
|
|
||||||
- mkdir -p /opt/factorio/data
|
|
||||||
- chown -R asxpi:asxpi /opt/*
|
|
||||||
|
|
||||||
# Set up weekly Docker image pruning
|
# Set up weekly Docker image pruning
|
||||||
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
- echo '0 3 * * 1 docker image prune -af > /var/log/docker-prune.log 2>&1' | crontab -
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,19 @@
|
||||||
# - czsk.it: @
|
# - czsk.it: @
|
||||||
# - childfr.ee: @
|
# - childfr.ee: @
|
||||||
|
|
||||||
resource "hcloud_zone" "czsk_it" {
|
#resource "hcloud_zone" "czsk_it" {
|
||||||
name = "czsk.it"
|
# name = "czsk.it"
|
||||||
mode = "primary"
|
# mode = "primary"
|
||||||
labels = {
|
# labels = {
|
||||||
managed_by = "terraform"
|
# managed_by = "terraform"
|
||||||
}
|
# }
|
||||||
}
|
#}
|
||||||
|
|
||||||
resource "hcloud_zone_rrset" "apex_a" {
|
#resource "hcloud_zone_rrset" "apex_a" {
|
||||||
zone = hcloud_zone.czsk_it.name
|
# zone = hcloud_zone.czsk_it.name
|
||||||
name = "test"
|
# name = "test"
|
||||||
type = "A"
|
# type = "A"
|
||||||
records = [
|
# records = [
|
||||||
{ value = "127.0.0.1", comment = "test" },
|
# { value = "127.0.0.1", comment = "test" },
|
||||||
]
|
# ]
|
||||||
}
|
#}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue