Saltar al contenido principal

Python

Kubiy ejecuta aplicaciones Python dentro de un virtualenv persistente gestionado por systemd. El virtualenv se crea en el servidor y se reutiliza entre deploys, lo que hace que los deploys subsecuentes sean más rápidos.

Presets disponibles

python [archivo]

Ejecuta un archivo Python directamente. Útil para aplicaciones simples o scripts que incluyen su propio servidor HTTP (por ejemplo, con http.server o frameworks que usan app.run()).

ParámetroValor
startModepython
Target por defectomain.py
Build por defectopip install -r requirements.txt

Ejemplo de configuración:

Preset: python [archivo]
Archivo: app.py

El proceso arranca como: python app.py

Ejemplo de app Flask con este modo:

import os
from flask import Flask

app = Flask(__name__)

@app.route('/health')
def health():
return {'status': 'ok'}

if __name__ == '__main__':
port = int(os.environ.get('PORT', 8000))
app.run(host='0.0.0.0', port=port)
aviso

Este modo no es recomendable para producción con tráfico real. El servidor de desarrollo de Flask o Django no está diseñado para manejar concurrencia. Usa gunicorn o uvicorn en producción.

gunicorn

Ejecuta la app con Gunicorn, el servidor WSGI de referencia para Python. Ideal para aplicaciones Django, Flask o cualquier app compatible con WSGI.

ParámetroValor
startModegunicorn
Target por defectoapp:app
Build por defectopip install -r requirements.txt

Formato del target: modulo:variable_de_la_app

EjemploSignificado
app:appEn app.py, la variable app
myproject.wsgi:applicationDjango standard
src.main:create_app()App factory pattern

Ejemplo de configuración para Django:

Preset: gunicorn
Target: myproject.wsgi:application

Ejemplo de configuración para Flask:

Preset: gunicorn
Target: app:app

Kubiy ejecuta gunicorn con: gunicorn --bind 0.0.0.0:$PORT <target>

consejo

Gunicorn se instala automáticamente en el virtualenv de tu app, aunque no esté en tu requirements.txt. No necesitas agregarlo.

uvicorn

Ejecuta la app con Uvicorn, el servidor ASGI de alto rendimiento. Ideal para FastAPI, Starlette y cualquier app compatible con ASGI.

ParámetroValor
startModeuvicorn
Target por defectomain:app
Build por defectopip install -r requirements.txt

Formato del target: modulo:variable_de_la_app

EjemploSignificado
main:appEn main.py, la variable app
src.api.main:appEstructura de paquetes

Ejemplo de configuración para FastAPI:

Preset: uvicorn
Target: main:app

Kubiy ejecuta uvicorn con: uvicorn --host 0.0.0.0 --port $PORT <target>

consejo

Uvicorn se instala automáticamente en el virtualenv de tu app, aunque no esté en tu requirements.txt. No necesitas agregarlo.

Puerto

El puerto se pasa automáticamente a gunicorn y uvicorn. Para el modo python, debes leerlo desde la variable de entorno:

port = int(os.environ.get('PORT', 8000))

El puerto por defecto es 8000.

Virtualenv

Kubiy crea un virtualenv en el servidor la primera vez que haces deploy. Las instalaciones con pip van a ese virtualenv. En deploys subsecuentes, el virtualenv se reutiliza, por lo que solo se instalan las dependencias nuevas.

consejo

Si cambias la versión de Python o quieres un virtualenv limpio, contacta a soporte o reconecta la app (lo que recrea el entorno desde cero).

Requirements

El archivo requirements.txt debe estar en la raíz del proyecto (o en el subdirectorio configurado). El formato estándar funciona correctamente:

flask==3.0.0
sqlalchemy==2.0.23
psycopg2-binary==2.9.9

También puedes usar requirements-prod.txt u otro archivo cambiando el Build Command:

pip install -r requirements-prod.txt

Build Command

Si dejas el campo vacío, Kubiy ejecuta:

pip install -r requirements.txt

Si especificas un Build Command, ese comando reemplaza la instalación automática. Sin embargo, gunicorn y uvicorn siempre se instalan automáticamente en el virtualenv, independientemente del Build Command.

Ejemplos comunes:

# Instalar desde un archivo alternativo
pip install -r requirements/prod.txt

# Con upgrade de pip primero
pip install --upgrade pip && pip install -r requirements.txt

# Múltiples archivos de requirements
pip install -r requirements.txt -r requirements-extras.txt

Ver la referencia completa de Build Command.

Casos de uso comunes

FastAPI

# main.py
from fastapi import FastAPI
import os

app = FastAPI()

@app.get("/health")
def health():
return {"status": "ok"}
# requirements.txt
fastapi==0.104.0

Configuración en Kubiy:

Preset: uvicorn
Target: main:app
Health: /health

Uvicorn se instala automáticamente; no necesitas incluirlo en requirements.txt.

Django

# myproject/settings.py
ALLOWED_HOSTS = ['*'] # o configura el dominio específico

Configuración en Kubiy:

Preset: gunicorn
Target: myproject.wsgi:application
Build Command: pip install -r requirements.txt && python manage.py collectstatic --noinput
aviso

ALLOWED_HOSTS debe incluir el dominio de Kubiy o * para que Django no rechace las peticiones.

Flask con app factory

# app/__init__.py
from flask import Flask

def create_app():
app = Flask(__name__)
# configuración...
return app
Preset: gunicorn
Target: app:create_app()

Aplicación en subdirectorio

Si tu app está en backend/:

Subdirectorio: backend
Preset: uvicorn
Target: main:app

Variables de entorno disponibles

VariableDescripción
PORTPuerto asignado (default 8000)
APP_PORTAlias de PORT
KUBIY_DEPLOY_IDID del deploy actual
KUBIY_APP_IDID de la aplicación

Para leer variables en tu app:

import os

database_url = os.environ['DATABASE_URL']
secret_key = os.environ.get('SECRET_KEY', 'dev-key-insegura')

Health Check recomendado

# FastAPI
@app.get("/health")
def health():
return {"status": "ok"}

# Flask
@app.route("/health")
def health():
return {"status": "ok"}, 200

# Django (en urls.py)
from django.http import JsonResponse

def health(request):
return JsonResponse({"status": "ok"})

Troubleshooting

ModuleNotFoundError al iniciar

El módulo no se instaló. Causas comunes:

  1. No tienes requirements.txt — Kubiy busca este archivo por defecto.
  2. Error en requirements.txt — Un paquete mal especificado puede hacer que pip install falle silenciosamente para ese paquete.
  3. Subdirectorio mal configurado — Kubiy busca requirements.txt en el subdirectorio configurado.

Gunicorn/uvicorn: "No module named X"

Aunque gunicorn y uvicorn se instalan automáticamente, sus dependencias opcionales no lo hacen. Si uvicorn necesita uvloop o httptools, agrégalos a requirements.txt:

uvicorn[standard]==0.24.0

Django: "DisallowedHost"

Agrega el dominio de Kubiy a ALLOWED_HOSTS en settings.py, o usa la variable de entorno para configurarlo:

import os
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',') + ['localhost']

Luego configura en Kubiy: ALLOWED_HOSTS=tu-app.kubiy.site

El virtualenv tiene versiones antiguas de paquetes

Si hiciste deploy antes y las versiones han cambiado en requirements.txt, puede que pip no actualice automáticamente. Usa el Build Command para forzar la actualización:

pip install --upgrade -r requirements.txt

Gunicorn timeout

Si tu app tarda en procesar requests, puedes configurar el timeout de gunicorn con el Build Command para variables de entorno, o usando un gunicorn.conf.py:

# gunicorn.conf.py
timeout = 120
workers = 2

Y en el Build Command agrega la configuración como env var o usa el archivo de configuración:

Preset: gunicorn
Target: app:app --config gunicorn.conf.py
aviso

Kubiy pasa el target directamente a gunicorn. Puedes agregar flags adicionales en el campo Target después del módulo WSGI, separados por espacios.

Puerto incorrecto en modo python

Si usas el preset python [archivo] y tu app no escucha en el puerto correcto, verifica que lees os.environ.get('PORT', 8000) y no un puerto hardcodeado.