An open API service indexing awesome lists of open source software.

https://github.com/jaolmos/raspberry-python-lab-server

Servidor self-hosting Raspberry Pi 5 como laboratorio de desarrollo Python. Hardware, Nginx, Docker, Cloudflare Tunnel y seguridad. Sin puertos expuestos, SSL automático.
https://github.com/jaolmos/raspberry-python-lab-server

cloudflare-tunnel docker homelab linux nginx python raspberry-pi raspberry-pi-5 self-hosting tutorial

Last synced: about 1 month ago
JSON representation

Servidor self-hosting Raspberry Pi 5 como laboratorio de desarrollo Python. Hardware, Nginx, Docker, Cloudflare Tunnel y seguridad. Sin puertos expuestos, SSL automático.

Awesome Lists containing this project

README

          

# Servidor Web Self-Hosting Python con Raspberry Pi 5

> **Nota:** Este documento muestra la evolución del proyecto. La primera parte describe la configuración inicial. La sección "Actualización - Diciembre 2025" al final muestra la configuración actual.

Servidor self-hosting (autoalojado) usando una Raspberry Pi 5, diseñado como laboratorio de desarrollo y pruebas. El proyecto combina hardware optimizado (SSD, refrigeración activa) con una arquitectura de software moderna y segura (Nginx, Docker, Cloudflare Tunnel), creando una infraestructura flexible para alojar aplicaciones web Python tanto para acceso público (vía Internet) como privado (red local).

**Características principales:**
- Alto rendimiento con SSD y 8GB RAM
- Seguridad avanzada sin puertos expuestos
- Acceso público mediante Cloudflare Tunnel
- Acceso local en red doméstica
- Despliegue simplificado con Docker
- SSL/HTTPS automático
- Capacidad para múltiples aplicaciones simultáneas
- Entorno de laboratorio para experimentación

Esta configuración proporciona un entorno de self-hosting completo, escalable y seguro para desarrollar, probar y desplegar aplicaciones web desde casa, con la flexibilidad de ejecutar servicios tanto públicos como privados según las necesidades.

## Hardware utilizado

### Componentes principales
- **Raspberry Pi 5 (8GB RAM)**
- Procesador Broadcom BCM2712 Quad-Core Cortex-A76 a 2.4GHz
- 8GB de memoria RAM LPDDR4X
- Wi-Fi 802.11ac de doble banda
- Bluetooth 5.0
- 2 puertos USB 3.0 y 2 puertos USB 2.0
- 2 puertos micro-HDMI
- Puerto Gigabit Ethernet
- Conector GPIO de 40 pines

- **Sistema de refrigeración**
- Disipador de calor oficial Raspberry Pi Active Cooler
- Disipador térmico de aluminio anodizado de una sola pieza
- Ventilador controlado por temperatura
- Almohadillas térmicas preaplicadas para óptima transferencia de calor

- **Almacenamiento**
- Tarjeta microSD A1 de 256GB con velocidad de transferencia de 150MB/s

- **Carcasa protectora**
- Carcasa específica para Raspberry Pi 5 con acceso a todos los puertos
- Aberturas para ventilación adecuada

- **Alimentación**
- Cargador oficial Raspberry Pi de 27W (USB-C, 5.1V/5A)
- Cable USB-C de alta calidad para asegurar alimentación estable

### Imágenes del montaje
![Raspberry Pi 5 - Placa base](images/raspberry-pi5-base.jpg)
*La placa base de la Raspberry Pi 5 antes del montaje*

![Raspberry Pi 5 con sistema de refrigeración](images/raspberry-pi5-cooler.jpg)
*Raspberry Pi 5 con el disipador y ventilador instalados para mantener temperaturas óptimas durante cargas prolongadas*

![Raspberry Pi 5 en carcasa (abierta)](images/raspberry-pi5-case-open.jpg)
*Raspberry Pi 5 instalada en la carcasa con acceso a los componentes internos*

![Raspberry Pi 5 - Montaje completo](images/raspberry-pi5-case-closed.jpg)
*Montaje finalizado con la carcasa cerrada, lista para funcionar como servidor*

## Configuración Inicial de la Raspberry Pi

### Instalación del sistema operativo
- Descargamos el Raspberry Pi Imager desde la [página oficial](https://www.raspberrypi.com/software/)
- Utilizamos esta herramienta para instalar Raspberry Pi OS en la tarjeta SD de 256GB
- Durante la configuración en el imager, configuramos:
- Usuario y contraseña
- Conexión WiFi (opcional)
- Habilitamos SSH
- Configuramos zona horaria y teclado
- Conectamos la Raspberry Pi a la red mediante cable Ethernet

### Localización y conexión inicial por SSH
1. Primero localizamos la Raspberry Pi en nuestra red local usando:
```bash
ping raspberrypi.local -4
```
> Nota: Este comando nos mostrará la IP dinámica asignada por DHCP (en nuestro caso fue 192.168.1.118).
> Alternativamente, podemos usar aplicaciones como IP Scanner para Windows.

2. Nos conectamos por SSH usando la IP obtenida:
```bash
ssh [TU-USUARIO]@192.168.1.118
```
> Nota: En la primera conexión nos pedirá confirmar la autenticidad del host (escribimos 'yes') y luego introducimos nuestra contraseña. Una vez conectados, tendremos acceso remoto a la terminal de la Raspberry Pi desde nuestro ordenador.

### Configuración básica con raspi-config
```bash
sudo raspi-config
```
- Expandimos el sistema de archivos para usar toda la capacidad de la SD
- Configuramos el autologin para escritorio
- Habilitamos SSH y VNC para acceso remoto
- Configuramos idioma (es_ES.UTF-8), zona horaria (Europa/Madrid) y teclado español
- Configuramos el país (España) para WiFi

### Configuración de IP estática
```bash
sudo nmtui
```
1. Cambiamos la configuración IP de automático a manual
2. Configuramos la IP estática fuera del rango DHCP del router (100-200):
- IP: 192.168.1.20/24 (elegimos .20 por estar fuera del rango DHCP del router)
> Nota: El /24 indica que usamos una máscara de subred 255.255.255.0, lo que permite 254 dispositivos en nuestra red local
- Puerta de enlace: 192.168.1.1
- DNS: 8.8.8.8, 8.8.4.4
3. Reiniciamos la Raspberry:
```bash
sudo reboot
```
4. Verificamos la nueva IP:
```bash
ping 192.168.1.20
```
5. Nos conectamos por SSH a la nueva IP estática:
```bash
ssh [TU-USUARIO]@192.168.1.20
```

### Actualización del sistema
```bash
sudo apt update
sudo apt full-upgrade
```

## Instalación y Configuración del Servidor Web

### Instalación de nginx
```bash
sudo apt install nginx
```

### Verificación del funcionamiento
```bash
sudo systemctl status nginx
```

## Configuración de Seguridad

### Configuración del firewall (UFW)
```bash
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
```

### Instalación y configuración de fail2ban
```bash
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
```

Editar el archivo con la siguiente configuración:
```
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
```

Activar el servicio:
```bash
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
```

## Configuración de Acceso Remoto (No-IP)

### Creación de cuenta y hostname
- Creamos una cuenta en No-IP.com (usamos la versión gratuita)
- Configuramos un hostname: [TU-DOMINIO].ddns.net
> Nota: Con la cuenta gratuita:
> - Puedes usar dominios gratuitos como `.ddns.net`, `.hopto.org`, `.sytes.net`, etc.
> - Tienes un límite de 3 hostnames activos
> - Debes confirmar cada hostname cada 30 días para mantenerlos activos
> - Los dominios personalizados requieren una suscripción de pago

### Instalación del cliente DUC
```bash
cd /usr/local/src
sudo wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
sudo tar xzf noip-duc-linux.tar.gz
cd noip-*
sudo make
sudo make install
```
Durante la instalación configuramos las credenciales de la cuenta No-IP

### Configuración como servicio
```bash
sudo nano /etc/systemd/system/noip2.service
```

Contenido del archivo:
```
[Unit]
Description=No-IP Dynamic DNS Update Client
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/noip2
Restart=always

[Install]
WantedBy=multi-user.target
```

Activar el servicio:
```bash
sudo systemctl daemon-reload
sudo systemctl enable noip2
sudo systemctl start noip2
```

## Configuración del reenvío de puertos
- Accedemos a la interfaz del router
- Configuramos en IPv4 Port Mapping:
- Puerto 80 (HTTP): Redirigido a la IP local del servidor
- Puerto 443 (HTTPS): Redirigido a la IP local del servidor

## Verificación del Funcionamiento
Verificamos que el servidor es accesible desde Internet visitando:
- http://[TU-DOMINIO].ddns.net
- https://[TU-DOMINIO].ddns.net (después de configurar SSL)

## Configuración de HTTPS con Let's Encrypt
```bash
# Instalación de Certbot y el plugin para Nginx
sudo apt install certbot python3-certbot-nginx

# Obtención del certificado SSL y configuración automática de Nginx
sudo certbot --nginx -d [TU-DOMINIO].ddns.net
```

Durante el proceso de configuración:
- Proporcionamos una dirección de correo electrónico para notificaciones importantes
- Aceptamos los términos de servicio de Let's Encrypt
- El certificado se genera correctamente y se guarda en /etc/letsencrypt/live/[TU-DOMINIO].ddns.net/
- Certbot configura automáticamente Nginx para usar HTTPS

Para comprobar la configuración de renovación automática:
```bash
sudo certbot renew --dry-run
```

## Preparar entorno para futuras aplicaciones

Esta configuración proporciona un servidor web básico con Nginx. En futuros documentos o actualizaciones se detallará cómo:

- Configurar entornos virtuales para proyectos Python
- Instalar y configurar frameworks como Django o FastAPI
- Configurar servidores de aplicación como Gunicorn o Uvicorn
- Configurar Nginx como proxy inverso para estas aplicaciones

Esta primera fase se centra en tener un servidor web funcional y seguro con capacidad de servir contenido estático.

## Monitoreo y mantenimiento

### Configurar actualizaciones automáticas de seguridad:
```bash
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
```

## Notas Adicionales
- La Raspberry Pi 5 con 8GB de RAM puede manejar entre 6-8 aplicaciones web simultáneamente
- Se accede mediante SSH usando la IP local configurada
- El nombre de dominio configurado en No-IP apunta siempre a nuestra IP pública actual

---

## Actualización - Diciembre 2025

### Hardware actualizado

**Almacenamiento:** microSD 256GB → **SSD Lexar SL300 1TB (USB 3.0)**
- 10x más rápido (150 MB/s → 400-500 MB/s)
- Mayor durabilidad y capacidad

![Raspberry Pi 5 con SSD externo](images/raspberry-pi5-ssd.jpg)
*Raspberry Pi 5 con SSD Lexar SL300 1TB conectado vía USB 3.0*

### Cambios en la arquitectura

**ANTES:**
```
Internet → Router (puertos 80/443 abiertos) → No-IP → Nginx
```

**AHORA:**
```
Internet → Cloudflare Tunnel (cifrado) → Nginx → Docker
```

### Mejoras principales

| Aspecto | Antes | Ahora |
|---------|-------|-------|
| Almacenamiento | microSD 256GB | SSD Lexar 1TB |
| Dominio | No-IP (gratis) | Dominio propio |
| Puertos abiertos | 80, 443 | Ninguno |
| SSL | Let's Encrypt manual | Automático (Cloudflare) |
| Contenedores | No | Docker + Compose |
| Protección DDoS | No | Sí (Cloudflare) |

### Beneficios

- **Más seguro:** Sin puertos expuestos en el router
- **Más rápido:** SSD 10x más veloz que microSD
- **Más escalable:** Docker facilita despliegue de aplicaciones
- **SSL automático:** Sin configuración manual de certificados
- **Protección incluida:** DDoS y firewall de Cloudflare

### Configuración actual

**Acceso SSH:** `ssh [TU-USUARIO]@192.168.1.20`

**Servicios activos:**
- Nginx (puerto 80 interno)
- Docker y Docker Compose
- Cloudflare Tunnel
- UFW Firewall (solo SSH abierto)
- Fail2ban