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:
2025-11-18 22:32:31 +01:00
parent 762d00eebf
commit ddbdefd27f
9 changed files with 442 additions and 34 deletions

70
roles/gitea/README.md Normal file
View 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.

View 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

View 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
View 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
View 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!

View 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

View 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

View 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