Add self-contained Gitea Git service with PostgreSQL integration
- Implements complete Gitea Git service following rick-infra self-contained architecture - Uses PostgreSQL infrastructure role as dependency and manages own database/user - Native Arch Linux installation via pacman packages - Automatic database setup (gitea database and user creation) - SystemD service with security hardening and proper dependency management - Caddy reverse proxy integration deployed to sites-enabled directory - SSH server on port 2222 with automatic host key generation - Production-ready with LFS support, security headers, and HTTPS via Caddy - Follows simplified configuration approach with essential variables only - Self-contained pattern: service manages complete setup independently
This commit is contained in:
70
roles/gitea/README.md
Normal file
70
roles/gitea/README.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Gitea Git Service Role
|
||||||
|
|
||||||
|
Self-contained Gitea Git service for rick-infra following the established architectural patterns.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- ✅ **Self-contained**: Manages its own database and configuration
|
||||||
|
- ✅ **Native Arch installation**: Uses pacman packages
|
||||||
|
- ✅ **PostgreSQL integration**: Uses shared PostgreSQL infrastructure
|
||||||
|
- ✅ **Caddy integration**: Deploys reverse proxy configuration
|
||||||
|
- ✅ **Security hardened**: SystemD restrictions and secure defaults
|
||||||
|
- ✅ **Production ready**: HTTPS, SSH access, LFS support
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- **Dependencies**: PostgreSQL infrastructure role
|
||||||
|
- **Database**: Self-managed gitea database and user
|
||||||
|
- **Network**: HTTP on :3000, SSH on :2222 (localhost)
|
||||||
|
- **Web access**: https://git.domain.com (via Caddy)
|
||||||
|
- **SSH access**: ssh://git@git.domain.com:2222
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Key variables (defaults in `defaults/main.yml`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Service
|
||||||
|
gitea_service_enabled: true
|
||||||
|
gitea_http_port: 3000
|
||||||
|
gitea_ssh_port: 2222
|
||||||
|
|
||||||
|
# Domain
|
||||||
|
gitea_subdomain: "git"
|
||||||
|
gitea_domain: "{{ caddy_domain }}"
|
||||||
|
|
||||||
|
# Database (self-managed)
|
||||||
|
gitea_db_name: "gitea"
|
||||||
|
gitea_db_user: "gitea"
|
||||||
|
gitea_db_password: "{{ vault_gitea_db_password }}"
|
||||||
|
|
||||||
|
# Application
|
||||||
|
gitea_app_name: "Gitea: Git with a cup of tea"
|
||||||
|
gitea_disable_registration: false
|
||||||
|
gitea_enable_lfs: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. **Add vault password**: Set `vault_gitea_db_password` in host_vars vault
|
||||||
|
2. **Deploy**: `ansible-playbook site.yml --tags gitea`
|
||||||
|
3. **Access**: Visit https://git.yourdomain.com to set up admin account
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- PostgreSQL infrastructure role (auto-included)
|
||||||
|
- Caddy web server (for HTTPS access)
|
||||||
|
- Vault password: `vault_gitea_db_password`
|
||||||
|
|
||||||
|
## Self-Contained Design
|
||||||
|
|
||||||
|
This role follows rick-infra's self-contained service pattern:
|
||||||
|
- Creates its own database and user via PostgreSQL infrastructure
|
||||||
|
- Manages its own configuration and data
|
||||||
|
- Deploys its own Caddy reverse proxy config
|
||||||
|
- Independent lifecycle from other services
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Rick-Infra Gitea Service**
|
||||||
|
Git repository management with integrated CI/CD capabilities.
|
||||||
76
roles/gitea/defaults/main.yml
Normal file
76
roles/gitea/defaults/main.yml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
# =================================================================
|
||||||
|
# Gitea Git Service Role - Simplified Configuration
|
||||||
|
# =================================================================
|
||||||
|
# Self-contained Gitea installation that manages its own database
|
||||||
|
# Follows rick-infra patterns for pragmatic service deployment
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Service Configuration
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# Service Management
|
||||||
|
gitea_service_enabled: true
|
||||||
|
gitea_service_state: "started"
|
||||||
|
|
||||||
|
# User and Paths (Arch Linux defaults)
|
||||||
|
gitea_user: "git"
|
||||||
|
gitea_group: "git"
|
||||||
|
gitea_home: "/var/lib/gitea"
|
||||||
|
|
||||||
|
# Network Configuration
|
||||||
|
gitea_http_port: 3000
|
||||||
|
gitea_ssh_port: 2222
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Domain and Caddy Integration
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# Domain setup (follows rick-infra pattern)
|
||||||
|
gitea_subdomain: "git"
|
||||||
|
gitea_domain: "{{ caddy_domain | default('localhost') }}"
|
||||||
|
gitea_full_domain: "{{ gitea_subdomain }}.{{ gitea_domain }}"
|
||||||
|
|
||||||
|
# Caddy integration
|
||||||
|
caddy_sites_enabled_dir: "/etc/caddy/sites-enabled"
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Database Configuration (Self-Contained)
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# Gitea manages its own database
|
||||||
|
gitea_db_type: "postgres"
|
||||||
|
gitea_db_host: "127.0.0.1"
|
||||||
|
gitea_db_port: 5432
|
||||||
|
gitea_db_name: "gitea"
|
||||||
|
gitea_db_user: "gitea"
|
||||||
|
gitea_db_password: "{{ vault_gitea_db_password }}"
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Application Settings
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# Basic Gitea configuration
|
||||||
|
gitea_app_name: "Gitea: Git with a cup of tea"
|
||||||
|
gitea_run_mode: "prod"
|
||||||
|
|
||||||
|
# Repository settings
|
||||||
|
gitea_default_branch: "main"
|
||||||
|
gitea_enable_lfs: true
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
gitea_disable_registration: false
|
||||||
|
gitea_require_signin: false
|
||||||
|
|
||||||
|
# SSH settings
|
||||||
|
gitea_start_ssh_server: true
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Rick-Infra Integration Notes
|
||||||
|
# =================================================================
|
||||||
|
# This role:
|
||||||
|
# - Depends on PostgreSQL infrastructure role
|
||||||
|
# - Creates its own database and user
|
||||||
|
# - Deploys Caddy configuration to sites-enabled
|
||||||
|
# - Uses native Arch Linux Gitea package
|
||||||
|
# - Follows self-contained service pattern
|
||||||
18
roles/gitea/handlers/main.yml
Normal file
18
roles/gitea/handlers/main.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
# Gitea Role Handlers
|
||||||
|
|
||||||
|
- name: reload systemd
|
||||||
|
systemd:
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: restart gitea
|
||||||
|
systemd:
|
||||||
|
name: gitea
|
||||||
|
state: restarted
|
||||||
|
when: gitea_service_state == "started"
|
||||||
|
|
||||||
|
- name: reload caddy
|
||||||
|
systemd:
|
||||||
|
name: caddy
|
||||||
|
state: reloaded
|
||||||
|
when: caddy_service_enabled | default(false)
|
||||||
29
roles/gitea/meta/main.yml
Normal file
29
roles/gitea/meta/main.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Rick's Infrastructure Team
|
||||||
|
description: Self-contained Gitea Git service for rick-infra
|
||||||
|
company: Personal Infrastructure
|
||||||
|
|
||||||
|
license: MIT
|
||||||
|
|
||||||
|
min_ansible_version: "2.9"
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: ArchLinux
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- git
|
||||||
|
- gitea
|
||||||
|
- development
|
||||||
|
- archlinux
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- role: postgresql
|
||||||
|
tags: ['postgresql', 'infrastructure']
|
||||||
|
- role: caddy
|
||||||
|
tags: ['caddy']
|
||||||
|
|
||||||
|
# Self-contained Gitea service
|
||||||
|
# Manages its own database using PostgreSQL infrastructure
|
||||||
114
roles/gitea/tasks/main.yml
Normal file
114
roles/gitea/tasks/main.yml
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
# Gitea Service Role - Self-Contained Implementation
|
||||||
|
# Manages Gitea Git service with own database
|
||||||
|
|
||||||
|
- name: Install Gitea from Arch repository
|
||||||
|
pacman:
|
||||||
|
name: gitea
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Git (required for Gitea)
|
||||||
|
pacman:
|
||||||
|
name: git
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create Gitea user and group
|
||||||
|
user:
|
||||||
|
name: "{{ gitea_user }}"
|
||||||
|
group: "{{ gitea_group }}"
|
||||||
|
system: yes
|
||||||
|
shell: /bin/bash
|
||||||
|
home: "{{ gitea_home }}"
|
||||||
|
create_home: yes
|
||||||
|
|
||||||
|
- name: Create Gitea directories
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ gitea_user }}"
|
||||||
|
group: "{{ gitea_group }}"
|
||||||
|
mode: '0755'
|
||||||
|
loop:
|
||||||
|
- "{{ gitea_home }}"
|
||||||
|
- "{{ gitea_home }}/data"
|
||||||
|
- "{{ gitea_home }}/repositories"
|
||||||
|
- "{{ gitea_home }}/log"
|
||||||
|
- /etc/gitea
|
||||||
|
|
||||||
|
- name: Create Gitea SSH directory with proper permissions
|
||||||
|
file:
|
||||||
|
path: "{{ gitea_home }}/.ssh"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ gitea_user }}"
|
||||||
|
group: "{{ gitea_group }}"
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
# Self-contained database management
|
||||||
|
- name: Create Gitea database user
|
||||||
|
postgresql_user:
|
||||||
|
name: "{{ gitea_db_user }}"
|
||||||
|
password: "{{ gitea_db_password }}"
|
||||||
|
encrypted: yes
|
||||||
|
become: yes
|
||||||
|
become_user: postgres
|
||||||
|
|
||||||
|
- name: Create Gitea database
|
||||||
|
postgresql_db:
|
||||||
|
name: "{{ gitea_db_name }}"
|
||||||
|
owner: "{{ gitea_db_user }}"
|
||||||
|
encoding: UTF8
|
||||||
|
template: template0
|
||||||
|
become: yes
|
||||||
|
become_user: postgres
|
||||||
|
|
||||||
|
- name: Deploy Gitea configuration
|
||||||
|
template:
|
||||||
|
src: app.ini.j2
|
||||||
|
dest: /etc/gitea/app.ini
|
||||||
|
owner: "{{ gitea_user }}"
|
||||||
|
group: "{{ gitea_group }}"
|
||||||
|
mode: '0600'
|
||||||
|
notify: restart gitea
|
||||||
|
|
||||||
|
- name: Deploy Gitea systemd service file
|
||||||
|
template:
|
||||||
|
src: gitea.service.j2
|
||||||
|
dest: /etc/systemd/system/gitea.service
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- reload systemd
|
||||||
|
- restart gitea
|
||||||
|
|
||||||
|
- name: Deploy Caddy configuration for Gitea
|
||||||
|
template:
|
||||||
|
src: gitea.caddy.j2
|
||||||
|
dest: "{{ caddy_sites_enabled_dir }}/gitea.caddy"
|
||||||
|
mode: '0644'
|
||||||
|
notify: reload caddy
|
||||||
|
when: caddy_sites_enabled_dir is defined
|
||||||
|
|
||||||
|
- name: Enable and start Gitea service
|
||||||
|
systemd:
|
||||||
|
name: gitea
|
||||||
|
enabled: "{{ gitea_service_enabled }}"
|
||||||
|
state: "{{ gitea_service_state }}"
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: Wait for Gitea to be ready
|
||||||
|
wait_for:
|
||||||
|
port: "{{ gitea_http_port }}"
|
||||||
|
host: "127.0.0.1"
|
||||||
|
timeout: 30
|
||||||
|
when: gitea_service_state == "started"
|
||||||
|
|
||||||
|
- name: Display Gitea service status
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
✅ Gitea Git service deployed successfully!
|
||||||
|
|
||||||
|
🌐 Web Interface: https://{{ gitea_full_domain }}
|
||||||
|
🔗 SSH Clone: ssh://git@{{ gitea_full_domain }}:{{ gitea_ssh_port }}
|
||||||
|
📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }}
|
||||||
|
🗄️ Database: {{ gitea_db_name }} (self-managed)
|
||||||
|
|
||||||
|
🏗️ Self-contained service ready for Git repositories!
|
||||||
60
roles/gitea/templates/app.ini.j2
Normal file
60
roles/gitea/templates/app.ini.j2
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Gitea Configuration - Rick-Infra
|
||||||
|
# Generated by Ansible Gitea role
|
||||||
|
|
||||||
|
[DEFAULT]
|
||||||
|
APP_NAME = {{ gitea_app_name }}
|
||||||
|
RUN_MODE = {{ gitea_run_mode }}
|
||||||
|
|
||||||
|
[repository]
|
||||||
|
ROOT = {{ gitea_home }}/repositories
|
||||||
|
DEFAULT_BRANCH = {{ gitea_default_branch }}
|
||||||
|
|
||||||
|
[server]
|
||||||
|
PROTOCOL = http
|
||||||
|
DOMAIN = {{ gitea_full_domain }}
|
||||||
|
HTTP_PORT = {{ gitea_http_port }}
|
||||||
|
ROOT_URL = https://{{ gitea_full_domain }}/
|
||||||
|
DISABLE_SSH = false
|
||||||
|
START_SSH_SERVER = {{ gitea_start_ssh_server | lower }}
|
||||||
|
SSH_DOMAIN = {{ gitea_full_domain }}
|
||||||
|
SSH_PORT = {{ gitea_ssh_port }}
|
||||||
|
SSH_LISTEN_PORT = {{ gitea_ssh_port }}
|
||||||
|
LOCAL_ROOT_URL = http://127.0.0.1:{{ gitea_http_port }}/
|
||||||
|
APP_DATA_PATH = {{ gitea_home }}/data
|
||||||
|
|
||||||
|
[database]
|
||||||
|
DB_TYPE = {{ gitea_db_type }}
|
||||||
|
HOST = {{ gitea_db_host }}:{{ gitea_db_port }}
|
||||||
|
NAME = {{ gitea_db_name }}
|
||||||
|
USER = {{ gitea_db_user }}
|
||||||
|
PASSWD = {{ gitea_db_password }}
|
||||||
|
SSL_MODE = disable
|
||||||
|
CHARSET = utf8
|
||||||
|
|
||||||
|
[security]
|
||||||
|
INSTALL_LOCK = true
|
||||||
|
SECRET_KEY = {{ ansible_machine_id }}{{ gitea_db_password | hash('sha256') }}
|
||||||
|
INTERNAL_TOKEN = {{ (ansible_machine_id + gitea_db_password) | hash('sha256') }}
|
||||||
|
|
||||||
|
[service]
|
||||||
|
DISABLE_REGISTRATION = {{ gitea_disable_registration | lower }}
|
||||||
|
REQUIRE_SIGNIN_VIEW = {{ gitea_require_signin | lower }}
|
||||||
|
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
||||||
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
|
NO_REPLY_ADDRESS = noreply.{{ gitea_domain }}
|
||||||
|
|
||||||
|
[log]
|
||||||
|
MODE = console
|
||||||
|
LEVEL = Info
|
||||||
|
ROOT_PATH = {{ gitea_home }}/log
|
||||||
|
|
||||||
|
{% if gitea_enable_lfs %}
|
||||||
|
[lfs]
|
||||||
|
START_SERVER = true
|
||||||
|
CONTENT_PATH = {{ gitea_home }}/data/lfs
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
[git]
|
||||||
|
PATH = /usr/bin/git
|
||||||
|
|
||||||
|
# Rick-Infra: Simplified Gitea configuration for self-contained service
|
||||||
32
roles/gitea/templates/gitea.caddy.j2
Normal file
32
roles/gitea/templates/gitea.caddy.j2
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Gitea Caddy Configuration - Rick-Infra
|
||||||
|
# Generated by Ansible Gitea role
|
||||||
|
# Deployed to {{ caddy_sites_enabled_dir }}/gitea.caddy
|
||||||
|
|
||||||
|
{{ gitea_full_domain }} {
|
||||||
|
# Reverse proxy to Gitea
|
||||||
|
reverse_proxy 127.0.0.1:{{ gitea_http_port }}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
header {
|
||||||
|
# Enable HSTS
|
||||||
|
Strict-Transport-Security max-age=31536000;
|
||||||
|
# Prevent embedding in frames
|
||||||
|
X-Frame-Options DENY
|
||||||
|
# Prevent content type sniffing
|
||||||
|
X-Content-Type-Options nosniff
|
||||||
|
# XSS protection
|
||||||
|
X-XSS-Protection "1; mode=block"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/gitea_access.log
|
||||||
|
}
|
||||||
|
|
||||||
|
# Optional: Custom error pages
|
||||||
|
handle_errors {
|
||||||
|
respond "Git service temporarily unavailable" 503
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rick-Infra: Self-contained Gitea service with Caddy reverse proxy
|
||||||
33
roles/gitea/templates/gitea.service.j2
Normal file
33
roles/gitea/templates/gitea.service.j2
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Gitea SystemD Service - Rick-Infra
|
||||||
|
# Generated by Ansible Gitea role
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Gitea Git with a cup of tea
|
||||||
|
After=network.target postgresql.service
|
||||||
|
Wants=postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User={{ gitea_user }}
|
||||||
|
Group={{ gitea_group }}
|
||||||
|
WorkingDirectory={{ gitea_home }}
|
||||||
|
ExecStart=/usr/bin/gitea web --config /etc/gitea/app.ini
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectHome=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ReadWritePaths={{ gitea_home }}
|
||||||
|
ReadWritePaths=/etc/gitea
|
||||||
|
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
|
||||||
|
|
||||||
|
# Process limits
|
||||||
|
LimitNOFILE=65536
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
# Rick-Infra: Self-contained Gitea service with security hardening
|
||||||
44
site.yml
44
site.yml
@@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
# Core infrastructure deployment with security hardening first
|
|
||||||
|
|
||||||
# Security hardening establishes secure foundation before web services
|
# Security hardening establishes secure foundation before web services
|
||||||
# - import_playbook: playbooks/security.yml
|
# - import_playbook: playbooks/security.yml
|
||||||
|
|
||||||
@@ -10,36 +8,14 @@
|
|||||||
gather_facts: yes
|
gather_facts: yes
|
||||||
|
|
||||||
roles:
|
roles:
|
||||||
# Infrastructure services
|
# # Infrastructure services
|
||||||
- role: postgresql
|
# - role: postgresql
|
||||||
tags: ['postgresql', 'infrastructure', 'database']
|
# tags: ['postgresql', 'infrastructure', 'database']
|
||||||
# - role: caddy
|
# # - role: caddy
|
||||||
# tags: ['caddy', 'infrastructure', 'web']
|
# # tags: ['caddy', 'infrastructure', 'web']
|
||||||
|
#
|
||||||
# Application services
|
# Application services
|
||||||
- role: sigvild-gallery
|
- role: gitea
|
||||||
tags: ['sigvild', 'gallery', 'wedding']
|
tags: ['gitea', 'git', 'development']
|
||||||
|
# - role: sigvild-gallery
|
||||||
post_tasks:
|
# tags: ['sigvild', 'gallery', 'wedding']
|
||||||
- name: Verify Caddy API is accessible
|
|
||||||
uri:
|
|
||||||
url: "http://{{ caddy_admin_listen }}/config/"
|
|
||||||
method: GET
|
|
||||||
status_code: 200
|
|
||||||
retries: 5
|
|
||||||
delay: 2
|
|
||||||
|
|
||||||
- name: Display infrastructure status
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
✅ Core infrastructure deployment completed!
|
|
||||||
|
|
||||||
🌐 Primary domain: {{ caddy_domain }}
|
|
||||||
🔒 HTTPS: {{ 'Enabled with DNS challenge (' + caddy_dns_provider + ')' if caddy_dns_provider else 'Enabled with HTTP challenge' }}
|
|
||||||
🚀 API registration: {{ 'Ready' if caddy_api_enabled else 'Disabled' }}
|
|
||||||
|
|
||||||
📍 Admin API: http://{{ caddy_admin_listen }} (localhost only)
|
|
||||||
📁 Web root: {{ caddy_web_root }}
|
|
||||||
📝 Logs: {{ caddy_log_dir }}
|
|
||||||
|
|
||||||
📖 Documentation: docs/caddy-api-registration.md
|
|
||||||
|
|||||||
Reference in New Issue
Block a user