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.
- Host: GitHub
- URL: https://github.com/jaolmos/raspberry-python-lab-server
- Owner: Jaolmos
- Created: 2025-04-05T15:41:12.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-12-07T22:23:05.000Z (4 months ago)
- Last Synced: 2026-01-29T23:59:47.635Z (about 2 months ago)
- Topics: cloudflare-tunnel, docker, homelab, linux, nginx, python, raspberry-pi, raspberry-pi-5, self-hosting, tutorial
- Homepage:
- Size: 1.14 MB
- Stars: 41
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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

*La placa base de la Raspberry Pi 5 antes del montaje*

*Raspberry Pi 5 con el disipador y ventilador instalados para mantener temperaturas óptimas durante cargas prolongadas*

*Raspberry Pi 5 instalada en la carcasa con acceso a los componentes internos*

*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 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