Upload files to "primerboot"

# Resumen operativo — Infraestructura Self-Hosted

Fecha:

```text
2026-05-05
```

Servidor:

```text
Hetzner VPS
Ubuntu 24.04
```

DNS:

```text
Cloudflare
```

---

# Objetivo alcanzado

Infraestructura self-hosted funcional con:

- Gitea
- Vaultwarden
- NGINX
- Certbot
- HTTPS válido
- Docker Compose
- Cloudflare DNS
- arquitectura reproducible

---

# Dominios

## Gitea

```text
https://git.carmona.digital
```

---

## Vaultwarden

```text
https://vault.carmona.digital
```

---

# Arquitectura actual

```text
Internet
   ↓
NGINX reverse proxy
   ↓
Docker network
   ├── Gitea
   ├── Vaultwarden
   └── PostgreSQL
```

---

# Estructura filesystem

```text
/opt/gitea
├── docker-compose.yml
├── nginx/
│   └── conf.d/
├── certbot/
│   ├── conf/
│   └── www/
├── gitea/
├── postgres/
└── vaultwarden/
    └── data/
```

---

# Componentes desplegados

## Gitea

Contenedor:

```text
gitea
```

Puerto SSH Git:

```text
2222
```

---

## PostgreSQL

Contenedor:

```text
gitea-db
```

Persistencia local.

---

## NGINX

Contenedor:

```text
gitea-nginx
```

Funciones:

- reverse proxy
- HTTPS termination
- routing subdominios
- ACME challenge

---

## Vaultwarden

Contenedor:

```text
vaultwarden
```

Funciones:

- password manager
- secrets manager
- TOTP
- secure notes
- API keys
- SSH keys

---

# DNS Cloudflare

## Tipo de registros

Todos:

```text
A records
```

---

## Subdominios

| Subdominio | Servicio |
|---|---|
| git | Gitea |
| vault | Vaultwarden |

---

## Configuración importante

```text
Proxy = DNS only
```

Durante setup SSL.

---

# Problemas encontrados

## 1. nginx restarting

Causa:

```text
certificados inexistentes
```

Porque nginx intentaba cargar:

```text
/etc/letsencrypt/live/git.blocaolabs.com/
```

Cuando el dominio cambió a:

```text
git.carmona.digital
```

---

## Solución

- eliminar HTTPS temporalmente
- usar nginx HTTP-only
- generar certificados
- reactivar HTTPS

---

## 2. Configuración nginx corrupta

Causa:

```text
texto shell accidental dentro de gitea.conf
```

Ejemplo:

```text
cat
EOF
```

---

## Solución

Recrear archivo completamente.

---

## 3. Certbot fallaba

Causa:

```text
nginx caído
```

Let's Encrypt no podía acceder a:

```text
http://git.carmona.digital/.well-known/acme-challenge/
```

---

## Solución

- arreglar nginx
- verificar puerto 80
- regenerar certificado

---

## 4. Vaultwarden usuario existente

Causa:

```text
persistencia SQLite
```

Usuarios guardados en:

```text
/opt/gitea/vaultwarden/data
```

---

## Solución

```bash
rm -rf /opt/gitea/vaultwarden/data/*
```

y recrear contenedor.

---

# Configuración SSL

Certificados generados mediante:

```bash
docker compose run --rm certbot certonly \
  --webroot \
  --webroot-path=/var/www/certbot \
  --email digitalcarmona@gmail.com \
  --agree-tos \
  --no-eff-email \
  -d DOMINIO
```

---

# Renovación automática SSL

Cron configurado:

```cron
0 3 * * * cd /opt/gitea && docker compose run --rm certbot renew && docker compose restart nginx
```

---

# Configuración nginx

## Estrategia final

Un único nginx centralizado.

Virtual hosts separados:

```text
/opt/gitea/nginx/conf.d/
```

Ejemplos:

```text
gitea.conf
vaultwarden.conf
```

---

# Estrategia arquitectónica elegida

## Decisión

NO usar:

```text
1 nginx por servicio
```

SÍ usar:

```text
1 nginx compartido
```

---

# Estrategia compose elegida

## Mantener

```text
1 docker-compose principal
```

en:

```text
/opt/gitea
```

---

# Razón

Más simple para:

- bootstrap
- recovery
- reproducibilidad
- AI-assisted operations

---

# Servicios futuros recomendados

## Prioridad 1

### Authentik

Objetivo:

- SSO
- MFA
- OAuth2
- central auth

---

## Prioridad 2

### Uptime Kuma

Objetivo:

- monitoring
- alertas
- uptime checks

---

## Prioridad 3

### Nextcloud

Objetivo:

- almacenamiento
- colaboración
- documentos

---

## Prioridad 4

### Grafana

Objetivo:

- métricas
- dashboards
- observabilidad

---

## Prioridad 5

### MinIO

Objetivo:

- S3 storage
- backups
- artefactos

---

# Decisiones importantes tomadas

## Cloudflare

Usado como DNS principal.

---

## HTTPS

Gestionado localmente mediante:

- nginx
- certbot

NO mediante Cloudflare SSL.

---

## Secrets

Vaultwarden elegido frente a:

- Hashicorp Vault
- Doppler
- Infisical

por simplicidad operacional.

---

# Comandos críticos de operación

## Ver logs nginx

```bash
docker compose logs nginx --tail=50
```

---

## Reiniciar nginx

```bash
docker compose restart nginx
```

---

## Ver contenedores

```bash
docker ps
```

---

## Test SSL

```bash
curl -I https://git.carmona.digital
```

---

## Test DNS

```bash
dig git.carmona.digital
```

---

## Renovación SSL

```bash
cd /opt/gitea
docker compose run --rm certbot renew --dry-run
```

---

# Backup mínimo obligatorio

## Gitea

```text
/opt/gitea/gitea
```

---

## PostgreSQL

```text
/opt/gitea/postgres
```

---

## Vaultwarden

```text
/opt/gitea/vaultwarden/data
```

---

## Certificados

```text
/opt/gitea/certbot/conf
```

---

# Objetivo futuro

Construir una infraestructura:

- reproducible
- Git-native
- AI-assisted
- portable
- documentada
- fácilmente reconstruible desde prompts + contexto.
This commit is contained in:
2026-05-05 23:38:05 +00:00
commit 39d46f7011
@@ -0,0 +1,574 @@
# Resumen operativo — Infraestructura Self-Hosted
Fecha:
```text
2026-05-05
```
Servidor:
```text
Hetzner VPS
Ubuntu 24.04
```
DNS:
```text
Cloudflare
```
---
# Objetivo alcanzado
Infraestructura self-hosted funcional con:
- Gitea
- Vaultwarden
- NGINX
- Certbot
- HTTPS válido
- Docker Compose
- Cloudflare DNS
- arquitectura reproducible
---
# Dominios
## Gitea
```text
https://git.carmona.digital
```
---
## Vaultwarden
```text
https://vault.carmona.digital
```
---
# Arquitectura actual
```text
Internet
NGINX reverse proxy
Docker network
├── Gitea
├── Vaultwarden
└── PostgreSQL
```
---
# Estructura filesystem
```text
/opt/gitea
├── docker-compose.yml
├── nginx/
│ └── conf.d/
├── certbot/
│ ├── conf/
│ └── www/
├── gitea/
├── postgres/
└── vaultwarden/
└── data/
```
---
# Componentes desplegados
## Gitea
Contenedor:
```text
gitea
```
Puerto SSH Git:
```text
2222
```
---
## PostgreSQL
Contenedor:
```text
gitea-db
```
Persistencia local.
---
## NGINX
Contenedor:
```text
gitea-nginx
```
Funciones:
- reverse proxy
- HTTPS termination
- routing subdominios
- ACME challenge
---
## Vaultwarden
Contenedor:
```text
vaultwarden
```
Funciones:
- password manager
- secrets manager
- TOTP
- secure notes
- API keys
- SSH keys
---
# DNS Cloudflare
## Tipo de registros
Todos:
```text
A records
```
---
## Subdominios
| Subdominio | Servicio |
|---|---|
| git | Gitea |
| vault | Vaultwarden |
---
## Configuración importante
```text
Proxy = DNS only
```
Durante setup SSL.
---
# Problemas encontrados
## 1. nginx restarting
Causa:
```text
certificados inexistentes
```
Porque nginx intentaba cargar:
```text
/etc/letsencrypt/live/git.blocaolabs.com/
```
Cuando el dominio cambió a:
```text
git.carmona.digital
```
---
## Solución
- eliminar HTTPS temporalmente
- usar nginx HTTP-only
- generar certificados
- reactivar HTTPS
---
## 2. Configuración nginx corrupta
Causa:
```text
texto shell accidental dentro de gitea.conf
```
Ejemplo:
```text
cat
EOF
```
---
## Solución
Recrear archivo completamente.
---
## 3. Certbot fallaba
Causa:
```text
nginx caído
```
Let's Encrypt no podía acceder a:
```text
http://git.carmona.digital/.well-known/acme-challenge/
```
---
## Solución
- arreglar nginx
- verificar puerto 80
- regenerar certificado
---
## 4. Vaultwarden usuario existente
Causa:
```text
persistencia SQLite
```
Usuarios guardados en:
```text
/opt/gitea/vaultwarden/data
```
---
## Solución
```bash
rm -rf /opt/gitea/vaultwarden/data/*
```
y recrear contenedor.
---
# Configuración SSL
Certificados generados mediante:
```bash
docker compose run --rm certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email digitalcarmona@gmail.com \
--agree-tos \
--no-eff-email \
-d DOMINIO
```
---
# Renovación automática SSL
Cron configurado:
```cron
0 3 * * * cd /opt/gitea && docker compose run --rm certbot renew && docker compose restart nginx
```
---
# Configuración nginx
## Estrategia final
Un único nginx centralizado.
Virtual hosts separados:
```text
/opt/gitea/nginx/conf.d/
```
Ejemplos:
```text
gitea.conf
vaultwarden.conf
```
---
# Estrategia arquitectónica elegida
## Decisión
NO usar:
```text
1 nginx por servicio
```
SÍ usar:
```text
1 nginx compartido
```
---
# Estrategia compose elegida
## Mantener
```text
1 docker-compose principal
```
en:
```text
/opt/gitea
```
---
# Razón
Más simple para:
- bootstrap
- recovery
- reproducibilidad
- AI-assisted operations
---
# Servicios futuros recomendados
## Prioridad 1
### Authentik
Objetivo:
- SSO
- MFA
- OAuth2
- central auth
---
## Prioridad 2
### Uptime Kuma
Objetivo:
- monitoring
- alertas
- uptime checks
---
## Prioridad 3
### Nextcloud
Objetivo:
- almacenamiento
- colaboración
- documentos
---
## Prioridad 4
### Grafana
Objetivo:
- métricas
- dashboards
- observabilidad
---
## Prioridad 5
### MinIO
Objetivo:
- S3 storage
- backups
- artefactos
---
# Decisiones importantes tomadas
## Cloudflare
Usado como DNS principal.
---
## HTTPS
Gestionado localmente mediante:
- nginx
- certbot
NO mediante Cloudflare SSL.
---
## Secrets
Vaultwarden elegido frente a:
- Hashicorp Vault
- Doppler
- Infisical
por simplicidad operacional.
---
# Comandos críticos de operación
## Ver logs nginx
```bash
docker compose logs nginx --tail=50
```
---
## Reiniciar nginx
```bash
docker compose restart nginx
```
---
## Ver contenedores
```bash
docker ps
```
---
## Test SSL
```bash
curl -I https://git.carmona.digital
```
---
## Test DNS
```bash
dig git.carmona.digital
```
---
## Renovación SSL
```bash
cd /opt/gitea
docker compose run --rm certbot renew --dry-run
```
---
# Backup mínimo obligatorio
## Gitea
```text
/opt/gitea/gitea
```
---
## PostgreSQL
```text
/opt/gitea/postgres
```
---
## Vaultwarden
```text
/opt/gitea/vaultwarden/data
```
---
## Certificados
```text
/opt/gitea/certbot/conf
```
---
# Objetivo futuro
Construir una infraestructura:
- reproducible
- Git-native
- AI-assisted
- portable
- documentada
- fácilmente reconstruible desde prompts + contexto.