[{"data":1,"prerenderedAt":203},["ShallowReactive",2],{"seo-verification":3,"blog-python-3-10-fin-de-vida-migrar-aplicaciones-vps-es":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-python-3-10-fin-de-vida-migrar-aplicaciones-vps-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":30,"intro":33,"sections":34,"ctaTitle":147,"ctaBody":148,"ctaButton":149,"ctaUrl":150,"relatedPosts":151},558,"python-3-10-fin-de-vida-migrar-aplicaciones-vps",{"fr":12,"en":13,"ar":14,"es":10},"python-3-10-fin-de-vie-migrer-applications-vps","python-3-10-end-of-life-migrate-vps-applications","نهاية-دعم-python-3-10-ترقية-تطبيقات-vps","Python 3.10 sin soporte: migrar sus aplicaciones en un VPS","Python 3.10 llegó al fin de vida en octubre de 2026. Pase sus aplicaciones a 3.12 en un VPS: venv paralelo, pruebas, cambio y vuelta atrás.",9,0,false,"2026-11-01T00:00:00+00:00","2026-11-01T14:14:31+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},4,"Desarrollo","developpement","bg-warning\u002F10 text-warning","dev",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fpython-3-10-fin-de-vie-migrer-applications-vps-poster.svg","Python 3.10 llegó al fin de vida en octubre de 2026: ya no se publica ninguna corrección de seguridad para esta rama. Su aplicación Django o FastAPI sigue respondiendo, y nada indica que el intérprete esté congelado. El riesgo se acumula en silencio y la migración parece más pesada con cada mes de retraso. Este es un método que no toca lo existente: un segundo entorno con Python 3.12 junto al primero, dependencias bloqueadas y probadas, y un cambio reversible en una sola línea.",[35,39,48,80,83,86,89,114,117,120,129,132,140,144],{"type":36,"title":37,"body":38},"h2","Qué cambia con el fin de vida de Python 3.10","La guía del desarrollador de Python publica el calendario de cada rama. Python 3.10, lanzada en octubre de 2021, figura allí como fin de vida desde el 1 de octubre de 2026. En la práctica, la rama ya no recibe ninguna corrección, ni siquiera de seguridad: un fallo descubierto en el intérprete o en su biblioteca estándar seguirá abierto.\n\nSu código sigue funcionando y sus pruebas pasan, y eso es lo que hace engañosa la situación. El fin de vida no rompe nada el mismo día. Retira la red de seguridad para todos los días siguientes, mientras las distribuciones, las imágenes base y las bibliotecas de terceros se desentienden poco a poco.",{"type":40,"title":41,"items":42},"ul","Lo que cuesta un intérprete congelado",[43,44,45,46,47],"**Fallos sin corrección** — toda vulnerabilidad del intérprete publicada tras el fin de vida sigue abierta en la rama 3.10; solo una subida de versión la cierra.","**Dependencias que se descuelgan** — tarde o temprano las bibliotecas suben su versión mínima de Python; una instalación nueva acaba resolviendo versiones antiguas, o fallando.","**Imágenes base congeladas** — una imagen de contenedor construida sobre la rama 3.10 descansa en un intérprete sin correcciones de origen, y sus análisis de vulnerabilidades lo señalan en cada build.","**Auditorías bloqueadas** — un intérprete sin soporte es una línea roja en las revisiones de seguridad y los cuestionarios de proveedores de sus clientes.","**Migración forzada** — de 3.10 a 3.12 hay dos versiones menores de diferencia; cuanto más espere, más larga la lista de roturas, y un proyecto planificado cuesta menos que una urgencia tras un incidente.",{"type":49,"title":50,"headers":51,"rows":55},"comparison","Calendario de soporte de las ramas de Python",[52,53,54],"Versión","Fin de soporte","Lectura para su VPS",[56,60,64,68,72,76],[57,58,59],"3.9","octubre de 2025","Sin soporte desde hace más de un año: abandónela sin esperar",[61,62,63],"3.10","octubre de 2026","Sin soporte desde el 1 de octubre: ninguna corrección más",[65,66,67],"3.11","octubre de 2027","Escalón mínimo: resuelve el problema de hoy, no el del año próximo",[69,70,71],"3.12","octubre de 2028","Destino recomendado: dos años de margen y un ecosistema asentado",[73,74,75],"3.13","octubre de 2029","Con soporte aún más largo; adóptela cuando sus dependencias estén validadas",[77,78,79],"3.14","octubre de 2030","Rama más reciente de esta tabla, con el fin de soporte más lejano",{"type":36,"title":81,"body":82},"Qué versión de destino elegir","Python 3.12 es el destino que recomendamos para una aplicación existente: su fin de soporte está previsto para octubre de 2028, dos años de margen, y los frameworks habituales la admiten. Python 3.11 es un escalón mínimo que le devuelve a la misma migración en octubre de 2027.\n\nPython 3.13 tiene soporte aún más largo, hasta octubre de 2029. No la consideramos inadecuada: solo supone que cada una de sus dependencias publique paquetes para esa versión, algo que se comprueba en su entorno de pruebas. Recordatorio de la guía oficial: las fechas de las ramas aún activas son planificadas y pueden ajustarse, solo las de 3.9 y 3.10 están cerradas. Vuelva a leer la página antes de fijar su calendario.",{"type":36,"title":84,"body":85},"Saber qué intérprete sirve realmente la producción","`python3 --version` en su shell no dice qué intérprete sirve la aplicación. El servicio puede arrancar un entorno virtual creado hace años, un Python compilado a mano o una imagen congelada en un `FROM python:3.10`.\n\nInventaríe cada fuente: la línea `ExecStart` de la unidad systemd (`systemctl cat miapp`), el resultado de `\u002Fsrv\u002Fmiapp\u002Fvenv\u002Fbin\u002Fpython --version`, un `grep -rn \"FROM python\" .` sobre sus Dockerfiles, el campo `requires-python` de `pyproject.toml` y la versión que usa su CI. Anote también los workers y las tareas programadas: suelen tener su propio entorno y se quedan con el intérprete antiguo mucho después del sitio.",{"type":36,"title":87,"body":88},"Requisitos antes de empezar","Esta migración no exige una máquina especial, pero sí acceso completo al servidor y sitio para dos entornos en paralelo: el segundo ocupa tanto disco como el primero, más una caché de compilación si alguna dependencia no tiene paquete precompilado.\n\nNecesita un archivo de dependencias bloqueado con versiones exactas, una suite de pruebas ejecutable fuera de producción, una copia reciente de la base de datos y acceso root para instalar, si sus dependencias compiladas lo exigen, un compilador y las cabeceras de desarrollo. Una primera pasada en un VPS de pruebas, aunque sea efímero, vale más que un ensayo en el servidor de producción.",{"type":90,"title":91,"steps":92},"steps","Migrar sin interrumpir el servicio",[93,96,99,102,105,108,111],{"title":94,"body":95},"Congelar lo existente","Desde el entorno actual, exporte las versiones exactas: `\u002Fsrv\u002Fmiapp\u002Fvenv\u002Fbin\u002Fpip freeze > requirements.lock.txt`. Este archivo describe con precisión lo que funciona hoy; es su punto de retorno. Versiónelo antes de continuar.",{"title":97,"body":98},"Instalar Python 3.12 sin tocar el sistema","`uv python install 3.12` descarga un intérprete 3.12 gestionado por uv, sin sustituir el `python3` de la distribución, del que dependen sus propias herramientas. Si prefiere los paquetes de su distribución, instale la rama 3.12 desde un repositorio que la ofrezca y use `python3.12 -m venv`.",{"title":100,"body":101},"Crear el segundo entorno junto al primero","`uv venv --python 3.12 \u002Fsrv\u002Fmiapp\u002Fvenv312` crea el entorno nuevo; sin uv, `python3.12 -m venv \u002Fsrv\u002Fmiapp\u002Fvenv312` hace el mismo trabajo. El antiguo sigue sirviendo el tráfico: nada se modifica. Un entorno virtual no se mueve, por eso el nuevo lleva otro nombre.",{"title":103,"body":104},"Reinstalar desde el archivo bloqueado","`VIRTUAL_ENV=\u002Fsrv\u002Fmiapp\u002Fvenv312 uv pip sync requirements.lock.txt` instala exactamente las versiones listadas. Con pip: `\u002Fsrv\u002Fmiapp\u002Fvenv312\u002Fbin\u002Fpip install -r requirements.lock.txt`. Si una versión fijada no existe para 3.12 o se niega a compilar, la instalación se detiene aquí: es el objetivo, descubre la rotura antes de producción. Anote cada paquete que haya que subir.",{"title":106,"body":107},"Volver a ejecutar la suite de pruebas","Lance las pruebas con el intérprete nuevo: `\u002Fsrv\u002Fmiapp\u002Fvenv312\u002Fbin\u002Fpython -m pytest`, o `\u002Fsrv\u002Fmiapp\u002Fvenv312\u002Fbin\u002Fpython manage.py test` para Django, precedido de `manage.py check`. Lea el resumen de advertencias de obsolescencia: anuncian las roturas de la versión siguiente. Las pruebas deben pasar con los dos intérpretes antes de continuar.",{"title":109,"body":110},"Subir solo lo que se rompió","Liste los paquetes implicados, súbalos uno a uno y regenere el archivo bloqueado desde el entorno nuevo: `\u002Fsrv\u002Fmiapp\u002Fvenv312\u002Fbin\u002Fpip freeze > requirements.312.txt`. Conserve las dos listas, una por intérprete, mientras dure el cambio.",{"title":112,"body":113},"Arrancar la aplicación en paralelo en un puerto local","Lánzela con el entorno nuevo en un puerto libre, por ejemplo `\u002Fsrv\u002Fmiapp\u002Fvenv312\u002Fbin\u002Fgunicorn miapp.wsgi --bind 127.0.0.1:8001` (o `uvicorn` para FastAPI). Envíele peticiones reales con `curl`: página de inicio, inicio de sesión, una escritura en base de datos. El tráfico público sigue en el proceso antiguo; solo un resultado idéntico justifica pasar al cambio.",{"type":36,"title":115,"body":116},"Cambiar y volver atrás en una línea","El cambio debe modificar una sola ruta. Haga que la unidad systemd apunte a un enlace en lugar de al propio entorno: `ExecStart=\u002Fsrv\u002Fmiapp\u002Fvenv-activo\u002Fbin\u002Fgunicorn miapp.wsgi --bind 127.0.0.1:8000`. Cree primero el enlace al estado actual con `ln -sfn \u002Fsrv\u002Fmiapp\u002Fvenv \u002Fsrv\u002Fmiapp\u002Fvenv-activo`, luego `systemctl daemon-reload` y un reinicio que no cambia nada.\n\nEl cambio a 3.12 pasa a ser `ln -sfn \u002Fsrv\u002Fmiapp\u002Fvenv312 \u002Fsrv\u002Fmiapp\u002Fvenv-activo && systemctl restart miapp`, y la vuelta atrás es la misma línea con la ruta antigua. Para una aplicación en contenedor, la palanca es la imagen base: pase de `FROM python:3.10-slim` a `FROM python:3.12-slim`, reconstruya con `docker compose up -d --build` y vuelva atrás restableciendo la línea anterior.\n\nEn ambos casos, conserve el entorno o la imagen antiguos unos días y siga los registros con `journalctl -u miapp -f` durante la primera hora.",{"type":36,"title":118,"body":119},"Los puntos de rotura que hay que revisar","Entre 3.10 y 3.12, la rotura rara vez viene de su código y casi siempre de lo que lo rodea. Vuelven tres familias: los módulos retirados de la biblioteca estándar, las dependencias compiladas y la versión mínima de sus frameworks. Las notas de versión de Python 3.12 listan lo que desaparece; léalas con su archivo bloqueado abierto al lado.",{"type":40,"title":121,"items":122},"Lista de control antes del cambio",[123,124,125,126,127,128],"**Módulos retirados** — Python 3.12 elimina `distutils`, `asynchat`, `asyncore` e `imp`; `grep -rnE \"distutils|asyncore|asynchat|import imp\" .` localiza sus usos directos, la lista de dependencias revela los indirectos.","**setuptools ya no viene preinstalado** — los entornos creados con `venv` ya no lo incluyen en 3.12; un paquete que importa `pkg_resources` sin declararlo falla hasta que ejecute `pip install setuptools`.","**Paquetes precompilados** — las dependencias compiladas (controladores de base de datos, tratamiento de imagen, criptografía) deben publicar un paquete para 3.12; `pip install --only-binary=:all: -r requirements.lock.txt` falla rápido en lugar de lanzar una compilación.","**Versiones mínimas de los frameworks** — Django 4.2 solo admite Python 3.12 a partir de la 4.2.8, y Django 5.0 y las siguientes lo aceptan; para FastAPI, relea los classifiers de Python de la versión exacta que fije.","**Advertencias de obsolescencia** — `datetime.utcnow()` y `datetime.utcfromtimestamp()` están obsoletas en 3.12; sustitúyalas por `datetime.now(datetime.UTC)` y `datetime.fromtimestamp(ts, datetime.UTC)`.","**Bibliotecas del sistema compartidas** — el entorno paralelo aísla los paquetes de Python, no las bibliotecas del sistema operativo (el cliente de PostgreSQL, por ejemplo): anótelas, una actualización del sistema puede cambiarlas bajo sus pies.",{"type":36,"title":130,"body":131},"Solución de problemas: los errores que se repiten","Estos mensajes aparecen desde la primera ejecución de las pruebas con Python 3.12. Cada uno tiene una causa conocida y un remedio corto.",{"type":40,"title":133,"items":134},"Mensaje observado y remedio",[135,136,137,138,139],"**ModuleNotFoundError: No module named 'distutils'** — el módulo salió de la biblioteca estándar. Instale `setuptools` en el entorno, que sigue ofreciendo una versión, y luego suba la dependencia culpable.","**ModuleNotFoundError: No module named 'imp'** — `imp` está retirado y `importlib` lo sustituye. Si la importación viene de un paquete de terceros, suba ese paquete a una versión que ya no lo use.","**ModuleNotFoundError: No module named 'pkg_resources'** — setuptools ya no se instala de oficio en los entornos venv de 3.12. `pip install setuptools` restablece el módulo hasta que el paquete culpable prescinda de él.","**DeprecationWarning: datetime.datetime.utcnow() is deprecated** — no es un error sino una señal: sustituya la llamada por un objeto con zona horaria.","**Failed building wheel for \u003Cpaquete>** — este paquete no tiene versión precompilada para 3.12 y pip intenta compilarlo. Súbalo, o instale compilador y cabeceras de desarrollo si no es posible subirlo.",{"type":141,"title":142,"body":143},"tip","Fijar el destino, no solo migrar","Aproveche la migración para fijar el intérprete en lugar de padecerlo: `requires-python = \">=3.12\"` en `pyproject.toml`, una etiqueta de imagen precisa en lugar de `python:3` y la versión de Python en la matriz de su CI. Añada 3.13 a esa matriz como simple observación: sabrá de antemano si la próxima subida será sencilla.",{"type":36,"title":145,"body":146},"Hacer de la subida de versión un gesto habitual","Una rama de Python llega al fin de vida cada año, en octubre. El método descrito aquí (entorno paralelo, archivo bloqueado, pruebas, cambio reversible) no depende de ninguna versión concreta: se repite tal cual para 3.11 en octubre de 2027 y para 3.12 en octubre de 2028, según el calendario actual.\n\nSi su aplicación aún no está en un servidor cuyo intérprete controle, nuestra guía de despliegue de Django en un VPS cubre el primer despliegue. Las guías sobre el fin de vida de Node.js y de PHP siguen la misma lógica para los demás runtimes de un parque.","Un servidor donde probar la versión siguiente antes de cambiar","Un VPS con acceso root permite montar un segundo entorno de Python junto al primero, validar las pruebas y después cambiar. La elección del sistema operativo es libre y la capacidad crece en vertical; la opción de administración del VPS toma el relevo si no quiere llevar el servidor usted mismo.","Comparar los VPS","\u002Fvps-cloud",[152,169,185],{"id":153,"slug":154,"slugs":155,"title":159,"excerpt":160,"readTime":161,"views":162,"isPinned":19,"publishedAt":163,"updatedAt":164,"category":165,"categories":166,"featuredImage":30,"bgImage":31,"posterImage":168,"relatedSolution":30},223,"nodejs-20-fin-de-vida-migrar-vps",{"fr":156,"en":157,"ar":158,"es":154},"nodejs-20-fin-de-vie-migrer-vps","nodejs-20-end-of-life-migrating-your-vps","نهاية-دعم-nodejs-20-ترحيل-خادم-vps","Node.js 20 en fin de vida: migrar su VPS","Node.js 20 no recibe parches de seguridad desde el 30 de abril de 2026. Auditar sus servidores y migrar a Node.js 24 sin romper la producción.",5,2,"2026-08-05T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[167],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fnodejs-20-fin-de-vie-migrer-vps-poster.svg",{"id":170,"slug":171,"slugs":172,"title":176,"excerpt":177,"readTime":178,"views":179,"isPinned":19,"publishedAt":180,"updatedAt":164,"category":181,"categories":182,"featuredImage":30,"bgImage":31,"posterImage":184,"relatedSolution":30},206,"php-82-fin-de-vida-planificar-la-migracion",{"fr":173,"en":174,"ar":175,"es":171},"php-82-fin-de-vie-checklist-migration","php-82-end-of-life-planning-your-migration","نهاية-دعم-php-82-دليل-الترحيل","PHP 8.2 fin de vida: checklist de migración","PHP 8.2 llega al final de su ciclo de vida el 31 de diciembre de 2026. Inventaría tu stack, compara versiones y sigue una checklist detallada para migrar a PHP 8.3 o 8.4.",11,7,"2026-08-01T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[183],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fphp-82-fin-de-vie-checklist-migration-poster.svg",{"id":186,"slug":187,"slugs":188,"title":192,"excerpt":193,"readTime":194,"views":179,"isPinned":19,"publishedAt":195,"updatedAt":164,"category":196,"categories":197,"featuredImage":30,"bgImage":31,"posterImage":199,"relatedSolution":200},44,"desplegar-una-aplicacion-django-en-un-vps",{"fr":189,"en":190,"ar":191,"es":187},"deployer-django-vps","deploy-a-django-application-on-a-vps","نشر-تطبيق-django-على-vps","Desplegar una aplicación Django en un VPS","Despliegue Django en un VPS: Gunicorn, Nginx, PostgreSQL, Docker y SSL. Guía completa para desarrolladores Python que quieren autoalojar.",3,"2026-05-07T00:00:00+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[198],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fdeployer-django-vps-poster.svg",{"categorySlug":201,"appSlug":202},"desarrollo","django",1793543125647]