{"id":29748068,"url":"https://github.com/jaolmos/raspberry-python-lab-server","last_synced_at":"2026-02-17T00:30:57.093Z","repository":{"id":286306071,"uuid":"961026736","full_name":"Jaolmos/raspberry-python-lab-server","owner":"Jaolmos","description":"Servidor self-hosting Raspberry Pi 5 como laboratorio de desarrollo Python. Hardware, Nginx, Docker, Cloudflare Tunnel y seguridad. Sin puertos expuestos, SSL automático.","archived":false,"fork":false,"pushed_at":"2025-12-07T22:23:05.000Z","size":1200,"stargazers_count":41,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-29T23:59:47.635Z","etag":null,"topics":["cloudflare-tunnel","docker","homelab","linux","nginx","python","raspberry-pi","raspberry-pi-5","self-hosting","tutorial"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jaolmos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-05T15:41:12.000Z","updated_at":"2026-01-11T12:03:30.000Z","dependencies_parsed_at":"2025-04-05T16:30:27.523Z","dependency_job_id":"e5dfca05-97bc-4027-a2ca-ad423a83d683","html_url":"https://github.com/Jaolmos/raspberry-python-lab-server","commit_stats":null,"previous_names":["jaolmos/raspberry-python-lab-server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Jaolmos/raspberry-python-lab-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaolmos%2Fraspberry-python-lab-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaolmos%2Fraspberry-python-lab-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaolmos%2Fraspberry-python-lab-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaolmos%2Fraspberry-python-lab-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jaolmos","download_url":"https://codeload.github.com/Jaolmos/raspberry-python-lab-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jaolmos%2Fraspberry-python-lab-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29526628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T21:45:09.491Z","status":"ssl_error","status_checked_at":"2026-02-16T21:44:58.452Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-tunnel","docker","homelab","linux","nginx","python","raspberry-pi","raspberry-pi-5","self-hosting","tutorial"],"created_at":"2025-07-26T09:39:25.316Z","updated_at":"2026-02-17T00:30:57.079Z","avatar_url":"https://github.com/Jaolmos.png","language":null,"readme":"# Servidor Web Self-Hosting Python con Raspberry Pi 5\n\n\u003e **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.\n\nServidor 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).\n\n**Características principales:**\n- Alto rendimiento con SSD y 8GB RAM\n- Seguridad avanzada sin puertos expuestos\n- Acceso público mediante Cloudflare Tunnel\n- Acceso local en red doméstica\n- Despliegue simplificado con Docker\n- SSL/HTTPS automático\n- Capacidad para múltiples aplicaciones simultáneas\n- Entorno de laboratorio para experimentación\n\nEsta 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.\n\n## Hardware utilizado\n\n### Componentes principales\n- **Raspberry Pi 5 (8GB RAM)**\n  - Procesador Broadcom BCM2712 Quad-Core Cortex-A76 a 2.4GHz\n  - 8GB de memoria RAM LPDDR4X\n  - Wi-Fi 802.11ac de doble banda\n  - Bluetooth 5.0\n  - 2 puertos USB 3.0 y 2 puertos USB 2.0\n  - 2 puertos micro-HDMI\n  - Puerto Gigabit Ethernet\n  - Conector GPIO de 40 pines\n\n- **Sistema de refrigeración**\n  - Disipador de calor oficial Raspberry Pi Active Cooler\n  - Disipador térmico de aluminio anodizado de una sola pieza\n  - Ventilador controlado por temperatura\n  - Almohadillas térmicas preaplicadas para óptima transferencia de calor\n\n- **Almacenamiento**\n  - Tarjeta microSD A1 de 256GB con velocidad de transferencia de 150MB/s\n\n- **Carcasa protectora**\n  - Carcasa específica para Raspberry Pi 5 con acceso a todos los puertos\n  - Aberturas para ventilación adecuada\n\n- **Alimentación**\n  - Cargador oficial Raspberry Pi de 27W (USB-C, 5.1V/5A)\n  - Cable USB-C de alta calidad para asegurar alimentación estable\n\n### Imágenes del montaje\n![Raspberry Pi 5 - Placa base](images/raspberry-pi5-base.jpg)\n*La placa base de la Raspberry Pi 5 antes del montaje*\n\n![Raspberry Pi 5 con sistema de refrigeración](images/raspberry-pi5-cooler.jpg)\n*Raspberry Pi 5 con el disipador y ventilador instalados para mantener temperaturas óptimas durante cargas prolongadas*\n\n![Raspberry Pi 5 en carcasa (abierta)](images/raspberry-pi5-case-open.jpg)\n*Raspberry Pi 5 instalada en la carcasa con acceso a los componentes internos*\n\n![Raspberry Pi 5 - Montaje completo](images/raspberry-pi5-case-closed.jpg)\n*Montaje finalizado con la carcasa cerrada, lista para funcionar como servidor*\n\n## Configuración Inicial de la Raspberry Pi\n\n### Instalación del sistema operativo\n- Descargamos el Raspberry Pi Imager desde la [página oficial](https://www.raspberrypi.com/software/)\n- Utilizamos esta herramienta para instalar Raspberry Pi OS en la tarjeta SD de 256GB\n- Durante la configuración en el imager, configuramos:\n  - Usuario y contraseña\n  - Conexión WiFi (opcional)\n  - Habilitamos SSH\n  - Configuramos zona horaria y teclado\n- Conectamos la Raspberry Pi a la red mediante cable Ethernet\n\n### Localización y conexión inicial por SSH\n1. Primero localizamos la Raspberry Pi en nuestra red local usando:\n```bash\nping raspberrypi.local -4\n```\n\u003e Nota: Este comando nos mostrará la IP dinámica asignada por DHCP (en nuestro caso fue 192.168.1.118). \n\u003e Alternativamente, podemos usar aplicaciones como IP Scanner para Windows.\n\n2. Nos conectamos por SSH usando la IP obtenida:\n```bash\nssh [TU-USUARIO]@192.168.1.118\n```\n\u003e 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.\n\n### Configuración básica con raspi-config\n```bash\nsudo raspi-config\n```\n- Expandimos el sistema de archivos para usar toda la capacidad de la SD\n- Configuramos el autologin para escritorio\n- Habilitamos SSH y VNC para acceso remoto\n- Configuramos idioma (es_ES.UTF-8), zona horaria (Europa/Madrid) y teclado español\n- Configuramos el país (España) para WiFi\n\n### Configuración de IP estática\n```bash\nsudo nmtui\n```\n1. Cambiamos la configuración IP de automático a manual\n2. Configuramos la IP estática fuera del rango DHCP del router (100-200):\n   - IP: 192.168.1.20/24 (elegimos .20 por estar fuera del rango DHCP del router)\n     \u003e Nota: El /24 indica que usamos una máscara de subred 255.255.255.0, lo que permite 254 dispositivos en nuestra red local\n   - Puerta de enlace: 192.168.1.1\n   - DNS: 8.8.8.8, 8.8.4.4\n3. Reiniciamos la Raspberry:\n```bash\nsudo reboot\n```\n4. Verificamos la nueva IP:\n```bash\nping 192.168.1.20\n```\n5. Nos conectamos por SSH a la nueva IP estática:\n```bash\nssh [TU-USUARIO]@192.168.1.20\n```\n\n### Actualización del sistema\n```bash\nsudo apt update\nsudo apt full-upgrade\n```\n\n## Instalación y Configuración del Servidor Web\n\n### Instalación de nginx\n```bash\nsudo apt install nginx\n```\n\n### Verificación del funcionamiento\n```bash\nsudo systemctl status nginx\n```\n\n## Configuración de Seguridad\n\n### Configuración del firewall (UFW)\n```bash\nsudo apt install ufw\nsudo ufw default deny incoming\nsudo ufw default allow outgoing\nsudo ufw allow ssh\nsudo ufw allow 80/tcp\nsudo ufw allow 443/tcp\nsudo ufw enable\n```\n\n### Instalación y configuración de fail2ban\n```bash\nsudo apt install fail2ban\nsudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local\nsudo nano /etc/fail2ban/jail.local\n```\n\nEditar el archivo con la siguiente configuración:\n```\n[DEFAULT]\nbantime = 1h\nfindtime = 10m\nmaxretry = 5\n\n[sshd]\nenabled = true\n```\n\nActivar el servicio:\n```bash\nsudo systemctl enable fail2ban\nsudo systemctl start fail2ban\n```\n\n## Configuración de Acceso Remoto (No-IP)\n\n### Creación de cuenta y hostname\n- Creamos una cuenta en No-IP.com (usamos la versión gratuita)\n- Configuramos un hostname: [TU-DOMINIO].ddns.net\n  \u003e Nota: Con la cuenta gratuita:\n  \u003e - Puedes usar dominios gratuitos como `.ddns.net`, `.hopto.org`, `.sytes.net`, etc.\n  \u003e - Tienes un límite de 3 hostnames activos\n  \u003e - Debes confirmar cada hostname cada 30 días para mantenerlos activos\n  \u003e - Los dominios personalizados requieren una suscripción de pago\n\n### Instalación del cliente DUC\n```bash\ncd /usr/local/src\nsudo wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz\nsudo tar xzf noip-duc-linux.tar.gz\ncd noip-*\nsudo make\nsudo make install\n```\nDurante la instalación configuramos las credenciales de la cuenta No-IP\n\n### Configuración como servicio\n```bash\nsudo nano /etc/systemd/system/noip2.service\n```\n\nContenido del archivo:\n```\n[Unit]\nDescription=No-IP Dynamic DNS Update Client\nAfter=network.target\n\n[Service]\nType=forking\nExecStart=/usr/local/bin/noip2\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n```\n\nActivar el servicio:\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable noip2\nsudo systemctl start noip2\n```\n\n## Configuración del reenvío de puertos\n- Accedemos a la interfaz del router\n- Configuramos en IPv4 Port Mapping:\n  - Puerto 80 (HTTP): Redirigido a la IP local del servidor\n  - Puerto 443 (HTTPS): Redirigido a la IP local del servidor\n\n## Verificación del Funcionamiento\nVerificamos que el servidor es accesible desde Internet visitando:\n- http://[TU-DOMINIO].ddns.net\n- https://[TU-DOMINIO].ddns.net (después de configurar SSL)\n\n## Configuración de HTTPS con Let's Encrypt\n```bash\n# Instalación de Certbot y el plugin para Nginx\nsudo apt install certbot python3-certbot-nginx\n\n# Obtención del certificado SSL y configuración automática de Nginx\nsudo certbot --nginx -d [TU-DOMINIO].ddns.net\n```\n\nDurante el proceso de configuración:\n- Proporcionamos una dirección de correo electrónico para notificaciones importantes\n- Aceptamos los términos de servicio de Let's Encrypt\n- El certificado se genera correctamente y se guarda en /etc/letsencrypt/live/[TU-DOMINIO].ddns.net/\n- Certbot configura automáticamente Nginx para usar HTTPS\n\nPara comprobar la configuración de renovación automática:\n```bash\nsudo certbot renew --dry-run\n```\n\n## Preparar entorno para futuras aplicaciones\n\nEsta configuración proporciona un servidor web básico con Nginx. En futuros documentos o actualizaciones se detallará cómo:\n\n- Configurar entornos virtuales para proyectos Python\n- Instalar y configurar frameworks como Django o FastAPI\n- Configurar servidores de aplicación como Gunicorn o Uvicorn\n- Configurar Nginx como proxy inverso para estas aplicaciones\n\nEsta primera fase se centra en tener un servidor web funcional y seguro con capacidad de servir contenido estático.\n\n## Monitoreo y mantenimiento\n\n### Configurar actualizaciones automáticas de seguridad:\n```bash\nsudo apt install unattended-upgrades\nsudo dpkg-reconfigure unattended-upgrades\n```\n\n## Notas Adicionales\n- La Raspberry Pi 5 con 8GB de RAM puede manejar entre 6-8 aplicaciones web simultáneamente\n- Se accede mediante SSH usando la IP local configurada\n- El nombre de dominio configurado en No-IP apunta siempre a nuestra IP pública actual\n\n---\n\n## Actualización - Diciembre 2025\n\n### Hardware actualizado\n\n**Almacenamiento:** microSD 256GB → **SSD Lexar SL300 1TB (USB 3.0)**\n- 10x más rápido (150 MB/s → 400-500 MB/s)\n- Mayor durabilidad y capacidad\n\n![Raspberry Pi 5 con SSD externo](images/raspberry-pi5-ssd.jpg)\n*Raspberry Pi 5 con SSD Lexar SL300 1TB conectado vía USB 3.0*\n\n### Cambios en la arquitectura\n\n**ANTES:**\n```\nInternet → Router (puertos 80/443 abiertos) → No-IP → Nginx\n```\n\n**AHORA:**\n```\nInternet → Cloudflare Tunnel (cifrado) → Nginx → Docker\n```\n\n### Mejoras principales\n\n| Aspecto | Antes | Ahora |\n|---------|-------|-------|\n| Almacenamiento | microSD 256GB | SSD Lexar 1TB |\n| Dominio | No-IP (gratis) | Dominio propio |\n| Puertos abiertos | 80, 443 | Ninguno |\n| SSL | Let's Encrypt manual | Automático (Cloudflare) |\n| Contenedores | No | Docker + Compose |\n| Protección DDoS | No | Sí (Cloudflare) |\n\n### Beneficios\n\n- **Más seguro:** Sin puertos expuestos en el router\n- **Más rápido:** SSD 10x más veloz que microSD\n- **Más escalable:** Docker facilita despliegue de aplicaciones\n- **SSL automático:** Sin configuración manual de certificados\n- **Protección incluida:** DDoS y firewall de Cloudflare\n\n### Configuración actual\n\n**Acceso SSH:** `ssh [TU-USUARIO]@192.168.1.20`\n\n**Servicios activos:**\n- Nginx (puerto 80 interno)\n- Docker y Docker Compose\n- Cloudflare Tunnel\n- UFW Firewall (solo SSH abierto)\n- Fail2ban\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaolmos%2Fraspberry-python-lab-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaolmos%2Fraspberry-python-lab-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaolmos%2Fraspberry-python-lab-server/lists"}