Git · CI/CD (integración y despliegue continuo) · Repositorio · Acciones
Forgejo — Fuente única de verdad y CI/CD¶
Sustituye a GitHub y GitLab. El repositorio central donde vive todo el código de SmallCountry. Cada cambio en el sistema nace aquí como un commit. Forgejo Actions ejecuta el CI/CD que planifica, verifica y despliega cada cambio. También es el buzón oficial de incidencias y sugerencias.
Despliegue real — casita-B450 (14 mayo 2026)¶
Forgejo se ejecuta en la máquina host (no en Proxmox aún) mediante Docker Compose.
docker-compose.yml¶
# /home/tonatiuh/forgejo/docker-compose.yml
services:
postgres:
image: postgres:18
container_name: forgejo-postgres
restart: unless-stopped
environment:
POSTGRES_DB: forgejo
POSTGRES_USER: forgejo
POSTGRES_PASSWORD: ${FORGEJO_DB_PASSWORD}
volumes:
- ./postgres-data:/var/lib/postgresql
healthcheck:
test: ["CMD", "pg_isready", "-U", "forgejo"](
interval: 10s
timeout: 5s
retries: 5
forgejo:
image: codeberg.org/forgejo/forgejo:15.0
container_name: forgejo
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: postgres:5432
FORGEJO__database__NAME: forgejo
FORGEJO__database__USER: forgejo
FORGEJO__database__PASSWD: ${FORGEJO_DB_PASSWORD}
FORGEJO__server__DOMAIN: forgejo-sc.duckdns.org
FORGEJO__server__ROOT_URL: https://forgejo-sc.duckdns.org
FORGEJO__server__HTTP_PORT: 3000
FORGEJO__server__SSH_DOMAIN: forgejo-sc.duckdns.org
FORGEJO__server__SSH_PORT: 2222
FORGEJO__service__DISABLE_REGISTRATION: true
FORGEJO__service__REQUIRE_SIGNIN_VIEW: false
FORGEJO__security__INSTALL_LOCK: true
FORGEJO__log__LEVEL: warn
FORGEJO__admin__DEFAULT_EMAIL_NOTIFICATIONS: disabled
USER_UID: 1000
USER_GID: 1000
volumes:
- ./forgejo-data:/data
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
Caddy¶
Decisiones¶
| Decisión | Motivo |
|---|---|
| PostgreSQL 18 | Última mayor estable )sep 2025). Soporte hasta 2030. Se usará en todos los servicios → aprender una sola BD |
| Forgejo 15.0 | Última LTS (abr 2026). Soporte hasta jul 2027 |
Volumen PG: /var/lib/postgresql |
PostgreSQL 18+ exige montar en el directorio padre, no en /data. Guarda los datos en subdirectorio versionado |
| Puerto 3000 solo en localhost | Caddy hace de proxy HTTPS. Sin exposición directa |
| SSH en 2222 | Evita conflicto con el SSH del host (22) |
data-root en /home/docker |
/var/lib/docker era un symlink que runc no soportaba. Se fijó en /etc/docker/daemon.json |
Pasos de instalación (resumen limpio)¶
flowchart TD
PASO1[1. Crear docker-compose.yml y .env con contraseña de BD]( --> PASO2[2. docker compose up -d]
PASO2 --> PASO3[3. Crear usuario admin con forgejo CLI]
PASO3 --> PASO4[4. Añadir bloque en Caddyfile]
PASO4 --> PASO5[5. systemctl reload caddy]
- Crear
docker-compose.ymly.envcon la contraseña de BD docker compose up -ddocker exec -u 1000:1000 forgejo forgejo admin user create --username tonatiuh --password '...' --email ... --admin --must-change-password=false- Añadir bloque
forgejo-sc.duckdns.orgen Caddyfile systemctl reload caddy
Datos¶
| Dato | Valor |
|---|---|
| URL | https://forgejo-sc.duckdns.org |
| Directorio | /home/tonatiuh/forgejo/ |
| BD | PostgreSQL 18 )contenedor forgejo-postgres) |
| Admin | tonatiuh |
Diseño previsto (Proxmox)¶
El despliegue final migrará a LXC 140 en Proxmox con ZFS, Pi-hole (forgejo.sc) y Authentik para OAuth2. Ver sección "Para el administrador" más abajo.
Como usuario¶
Para todos los usuarios del país¶
| Funcionalidad | Navegador | Ubuntu | Android | FireTV |
|---|---|---|---|---|
| Reportar problemas o sugerir mejoras (Forgejo Issues) | ✅ | ✅ | ✅ | ❌ |
| Seguir el historial de cambios del sistema | ✅ | ✅ | ✅ | ❌ |
| Acceder a documentación versionada | ✅ | ✅ | ✅ | ❌ |
Para el administrador y arquitecto¶
| Funcionalidad | Navegador | Ubuntu | Android | FireTV |
|---|---|---|---|---|
| Repositorios Git con todo el código de infraestructura | ✅ | ✅ | ❌ | ❌ |
| CI/CD con Forgejo Actions para despliegues automáticos | ✅ | ✅ | ❌ | ❌ |
| Registro OCI de imágenes Docker | ✅ | ✅ | ❌ | ❌ |
| Issues y milestones para seguimiento de tareas | ✅ | ✅ | ✅ | ❌ |
| Wiki para documentación colaborativa | ✅ | ✅ | ✅ | ❌ |
| Git CLI (push, pull, clone) | ❌ | ✅ | ❌ | ❌ |
Primeros pasos: Accede a https://forgejo-sc.duckdns.org. Inicia sesión con tu cuenta de Authentik. Navega a Explorar para ver todos los repositorios públicos. Usa Incidencias desde el panel de inicio para reportar cualquier problema técnico o sugerir una mejora.
Integración con otros servicios de SmallCountry¶
| Servicio | Cómo se integra |
|---|---|
| Ansible | Repositorio de playbooks de infraestructura |
| OpenTofu | Módulos de infraestructura como código |
| Semaphore | Dispara playbooks desde Forgejo Actions |
| MkDocs | Documentación versionada del sistema |
| code-server | Entorno de desarrollo integrado |
| Todos los servicios | Cada cambio en el sistema pasa por Forgejo |
| ntfy | Notificaciones de estado de CI/CD |
| Matrix | Notificaciones de despliegues |
| InvenioRDM | Backend de scripts de ciencia abierta. InvenioRDM es el frontend público de publicación; Forgejo aloja el código científico |
Servicios que lo hacen posible¶
- Forgejo — Git hosting y CI/CD
- PostgreSQL — Base de datos
- Forgejo Runner — Ejecutores de Actions
Para el administrador (diseño previsto)
LXC (contenedor ligero de Proxmox): 140
IP: 10.10.10.140
Tier: 2
Impacto: 🔴 Crítico — Sin Forgejo no hay fuente de verdad ni CI/CD
ZFS (sistema de archivos con integridad de datos) persistente: rpool/datos/forgejo → /opt/forgejo/
Docker compose: Forgejo + PostgreSQL
Healthcheck: curl https://forgejo-sc.duckdns.org
Logs: docker logs forgejo en el LXC 140
Backup manual: PBS (sistema de copias de seguridad de Proxmox) diario + mirrors de repos en Horus (servidor secundario con GPU para IA) y Thoth (Raspberry Pi árbitro del clúster y backup offsite)
Registry OCI local: Todas las imágenes Docker se cachean aquí. Los nodos nunca descargan imágenes de internet directamente.
Cuarentena de software: Nuevas versiones pasan 60/14/7 días según Tier antes de producción.
Problemas comunes:
- "CI/CD no se ejecuta" → verificar runners de Forgejo Actions
- "No puedo hacer push" → verificar permisos y clave SSH
- "Registry lleno" → limpiar imágenes antiguas con garbage collection
Para el arquitecto (diseño previsto)
flowchart TD
USUARIO[Usuario]( -->|git push| FORGEJO[Forgejo LXC 140]
FORGEJO -->|Webhook| RUNNER[Forgejo Actions Runner]
RUNNER -->|Plan| OPENTOFU[OpenTofu]
OPENTOFU -->|Snapshot| ZFS[)ZFS)]
OPENTOFU -->|Apply| PROXMOX[Proxmox](
RUNNER -->|Verifica| HEALTHCHECKS[Healthchecks]
FORGEJO -->|OCI pull| NODOS[Nodos Docker]
NODOS -->|Nunca| INTERNET[Internet]
FORGEJO -->|Notifica| NTFY_MATRIX[ntfy / Matrix]
Bridge: vmbr1
Puertos: 3000 )web), 2222 (SSH git)
Pi-hole: forgejo.sc → 10.10.10.140
Caddy: forward_auth + reverse_proxy (necesita WebSocket para Actions)
Authentik: Provider OAuth2, grupos admin y arquitecto
Pipeline de CI/CD:
1. Push a Forgejo
2. Forgejo Actions ejecuta
3. Plan de OpenTofu
4. Snapshot ZFS
5. Apply
6. Verify
7. Commit
Si hay drift, se crea commit forense y se detiene.
Orquestación:
- Playbook: deploy-forgejo.yml
- Rol Ansible: roles/forgejo/
- Tofu: modules/forgejo/
- Semaphore, Forgejo Actions
- Repo: sc-infra/forgejo
Secciones relacionadas¶
- [Guía de estilo: Clasificación de estado../../guia-estilo/filosofia.md#estados)
- [ADR-004: Node-RED + n8n../../adr/004-nodered-n8n/)
🌐 Enlaces de interés¶
🏠 Despliegue real en SmallCountry¶
docker-compose (~/forgejo/docker-compose.yml)¶
# Forgejo — SmallCountry
services:
postgres:
image: postgres:18
container_name: forgejo-postgres
restart: unless-stopped
environment:
POSTGRES_DB: forgejo
POSTGRES_USER: forgejo
POSTGRES_PASSWORD: ${FORGEJO_DB_PASSWORD}
volumes:
- ./postgres-data:/var/lib/postgresql
healthcheck:
test: ["CMD", "pg_isready", "-U", "forgejo"](
interval: 10s
timeout: 5s
retries: 5
forgejo:
image: codeberg.org/forgejo/forgejo:15.0
container_name: forgejo
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
FORGEJO__database__DB_TYPE: postgres
FORGEJO__database__HOST: postgres:5432
FORGEJO__database__NAME: forgejo
FORGEJO__database__USER: forgejo
FORGEJO__database__PASSWD: ${FORGEJO_DB_PASSWORD}
FORGEJO__server__DOMAIN: forgejo-sc.duckdns.org
FORGEJO__server__ROOT_URL: https://forgejo-sc.duckdns.org
FORGEJO__server__HTTP_PORT: 3000
FORGEJO__server__SSH_DOMAIN: forgejo-sc.duckdns.org
FORGEJO__server__SSH_PORT: 2222
FORGEJO__service__DISABLE_REGISTRATION: true
FORGEJO__service__REQUIRE_SIGNIN_VIEW: false
FORGEJO__security__INSTALL_LOCK: true
FORGEJO__log__LEVEL: warn
FORGEJO__admin__DEFAULT_EMAIL_NOTIFICATIONS: disabled
USER_UID: 1000
USER_GID: 1000
volumes:
- ./forgejo-data:/data
ports:
- "127.0.0.1:3000:3000" # Solo localhost — Caddy proxy HTTPS
- "2222:22" # SSH para git clone/push
Ubicaciones físicas¶
| Elemento | Ruta |
|---|---|
| docker-compose | ~/forgejo/docker-compose.yml |
| Variables de entorno | ~/forgejo/.env )contiene FORGEJO_DB_PASSWORD) |
| Datos Forgejo | ~/forgejo/forgejo-data/ (repos git, adjuntos, avatares, logs, sesiones) |
| Datos PostgreSQL | ~/forgejo/postgres-data/ (bind mount a /var/lib/postgresql, PG 18.3) |
| Config Forgejo | ~/forgejo/forgejo-data/gitea/conf/app.ini (autogenerado en primer arranque) |
Red¶
- Docker network:
forgejo_default(bridge) - Forgejo solo expone
127.0.0.1:3000— Caddy en el host hace de proxy HTTPS público - PostgreSQL no expone puerto — solo accesible dentro de la red Docker
- SSH accesible en puerto
2222paragit clone/push
app.ini generado¶
APP_NAME = Forgejo: Beyond coding. We forge.
RUN_MODE = prod
[server]
DOMAIN = forgejo-sc.duckdns.org
ROOT_URL = https://forgejo-sc.duckdns.org
HTTP_PORT = 3000
SSH_PORT = 2222
[database]
DB_TYPE = postgres
HOST = postgres:5432
NAME = forgejo
USER = forgejo
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[security]
INSTALL_LOCK = true
Repositorio SmallCountry¶
- URL:
https://forgejo-sc.duckdns.org/SmallCountry/infra-core - Rama:
main - Usuario principal:
tonatiuh - Autenticación: Token de acceso con scopes
repository+issue+user - Integración: opencode y Hermes Agent commitean como
tonatiuh