Files
infra-selfhosted/primerboot/infraestructura_selfhosted_resumen_operativo_2026_05_05.md
T
jlcm 39d46f7011 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.
2026-05-05 23:38:05 +00:00

5.2 KiB

Resumen operativo — Infraestructura Self-Hosted

Fecha:

2026-05-05

Servidor:

Hetzner VPS
Ubuntu 24.04

DNS:

Cloudflare

Objetivo alcanzado

Infraestructura self-hosted funcional con:

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

Dominios

Gitea

https://git.carmona.digital

Vaultwarden

https://vault.carmona.digital

Arquitectura actual

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

Estructura filesystem

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

Componentes desplegados

Gitea

Contenedor:

gitea

Puerto SSH Git:

2222

PostgreSQL

Contenedor:

gitea-db

Persistencia local.


NGINX

Contenedor:

gitea-nginx

Funciones:

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

Vaultwarden

Contenedor:

vaultwarden

Funciones:

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

DNS Cloudflare

Tipo de registros

Todos:

A records

Subdominios

Subdominio Servicio
git Gitea
vault Vaultwarden

Configuración importante

Proxy = DNS only

Durante setup SSL.


Problemas encontrados

1. nginx restarting

Causa:

certificados inexistentes

Porque nginx intentaba cargar:

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

Cuando el dominio cambió a:

git.carmona.digital

Solución

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

2. Configuración nginx corrupta

Causa:

texto shell accidental dentro de gitea.conf

Ejemplo:

cat
EOF

Solución

Recrear archivo completamente.


3. Certbot fallaba

Causa:

nginx caído

Let's Encrypt no podía acceder a:

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

Solución

  • arreglar nginx
  • verificar puerto 80
  • regenerar certificado

4. Vaultwarden usuario existente

Causa:

persistencia SQLite

Usuarios guardados en:

/opt/gitea/vaultwarden/data

Solución

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

y recrear contenedor.


Configuración SSL

Certificados generados mediante:

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:

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:

/opt/gitea/nginx/conf.d/

Ejemplos:

gitea.conf
vaultwarden.conf

Estrategia arquitectónica elegida

Decisión

NO usar:

1 nginx por servicio

SÍ usar:

1 nginx compartido

Estrategia compose elegida

Mantener

1 docker-compose principal

en:

/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

docker compose logs nginx --tail=50

Reiniciar nginx

docker compose restart nginx

Ver contenedores

docker ps

Test SSL

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

Test DNS

dig git.carmona.digital

Renovación SSL

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

Backup mínimo obligatorio

Gitea

/opt/gitea/gitea

PostgreSQL

/opt/gitea/postgres

Vaultwarden

/opt/gitea/vaultwarden/data

Certificados

/opt/gitea/certbot/conf

Objetivo futuro

Construir una infraestructura:

  • reproducible
  • Git-native
  • AI-assisted
  • portable
  • documentada
  • fácilmente reconstruible desde prompts + contexto.