Cómo llevé un sistema de escritorio a la nube: Mi experiencia y arquitectura real

Cómo llevé un sistema de escritorio a la nube: Mi experiencia y arquitectura real

Ruperto Coronado
Ruperto Coronado

Soy programador. Tuve dos tiendas de abarrotes y, para resolver la operativa diaria, desarrollé mi propio sistema de punto de venta de escritorio.

Funcionó muy bien. Tanto que se lo vendí a un par de clientes comerciales (tiendas y negocios locales). Pero con el tiempo surgió la necesidad natural: tocaba migrarlo a la nube para consultar ventas desde cualquier lugar, centralizar información y aprovechar la flexibilidad del ecosistema web.

📖 Este post es parte de la serie:

  1. ¿Se puede llevar un sistema de escritorio a la nube?
  2. Cómo llevé un sistema de escritorio a la nube: Mi experiencia y arquitectura real
  3. De Access a la nube: Caso de estudio y entrevista técnica

El punto de partida: Las tecnologías

Para entender el salto técnico, hay que ver de dónde veníamos y a dónde fuimos:

El sistema de escritorio original

  • Interfaz y lógica cliente: Formularios de Microsoft Access + VBA (Visual Basic for Applications).
  • Motor de persistencia: Microsoft SQL Server corriendo en red local en el servidor de cada cliente (Windows).

El nuevo stack en la nube

  • Backend: Python + Django + Django REST Framework (DRF) para exponer la API.
  • Conectores de base de datos: mssql-django + pyodbc.
  • Bases de datos:
    • PostgreSQL: Base de datos principal (default) para Django, autenticación y todas las tablas/módulos nuevos.
    • MS SQL Server: Base de datos secundaria conectada para mantener compatibilidad con el sistema de escritorio original mientras duraba la transición.
  • Frontend: Vue 3 (Single Page Application rápida y reactiva).
  • Infraestructura: Docker + NGINX como reverse proxy sobre Ubuntu Server 24.04.

La arquitectura general y funcionamiento

El reto era no interrumpir el negocio. La caja registradora no puede parar jamás por un deploy en la nube.

+------------------------------------+
|  Servidor Local (Windows + MSSQL)   |
|   (Punto de Venta de Escritorio)   |
+------------------+-----------------+
                   | (Conexión de red)
                   v
+------------------+-----------------------------------------------+
|  VPS / Servidor Linux (Ubuntu 24.04 + Docker)                    |
|                                                                  |
|   [NGINX (Reverse Proxy / SSL)]                                  |
|          |                                                       |
|          +--> [Frontend SPA: Vue 3]                              |
|          |                                                       |
|          +--> [Backend: Django REST Framework]                   |
|                     |                   |                        |
|                     v (Default)         v (Secundaria / Legacy)  |
|               [PostgreSQL]        [MSSQL Server]                 |
+------------------------------------------------------------------+
  1. Base de datos origen intacta: La base original se mantuvo en la máquina del cliente (Windows + MSSQL).
  2. Despliegue contenerizado: El nuevo sistema se instaló en un VPS con Ubuntu Server 24.04 utilizando Docker en todo el entorno.
  3. Persistencia híbrida (Multi-Database en Django): Postgres almacena las sesiones, usuarios, permisos y tablas nuevas. Django permite configurar múltiples bases de datos con enrutadores (routers), especificando a qué base de datos va cada modelo.
  4. Consumo por API: La app web en Vue 3 consume los endpoints provistos por Django REST Framework.
  5. Enrutamiento perimetral: Un contenedor NGINX recibe la solicitud y dirige el tráfico hacia donde corresponde: al frontend de Vue 3 o a la API/Admin de Django.

La anécdota: Nuestro propio DDNS casero con una Mini PC

Antes de pasar a un VPS, el primer despliegue real no estuvo en un datacenter, sino en una Mini PC con Ubuntu Server conectada a un módem de Telmex.

¿El problema? Conexión residencial con IP pública dinámica y sin IP fija. La solución fue puramente artesanal:

  1. Abrí y expuse el puerto 80 en el módem de Telmex apuntando a la Mini PC.
  2. Contraté dominio y hosting en algo como HostGator.
  3. Creé un subdominio apuntando al módem (por ejemplo: app.factukora.net).
  4. Creé un script en Bash corriendo en el servidor cada 5 minutos:
    • Detectaba si la IP pública había cambiado.
    • Si cambiaba, le “avisaba” al cPanel del host para actualizar el registro DNS tipo A del subdominio.

Un Dynamic DNS hecho en casa que mantuvo viva la app durante los primeros meses sin incurrir en costos fijos.


El proceso de construcción paso a paso

1. Primera meta: Solo lectura

La primera meta fue “solo ver” los datos en la nube, jamás modificarlos de entrada. Si la nube fallaba, la operación física y el punto de venta local en Access continuaban funcionando al 100%.

2. Configurar Postgres como principal y MSSQL como secundaria

Django se configuró con PostgreSQL como base de datos por defecto (default):

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'nube_db',
        'USER': 'postgres_user',
        'PASSWORD': 'secret_password',
        'HOST': 'postgres_container',
        'PORT': '5432',
    },
    'mssql_legacy': {
        'ENGINE': 'mssql',
        'NAME': 'PuntoVentaLocal',
        'USER': 'sa',
        'PASSWORD': 'sql_password',
        'HOST': 'ip_servidor_cliente',
        'PORT': '1433',
        'OPTIONS': {
            'driver': 'ODBC Driver 18 for SQL Server',
        },
    }
}

Para conectar Django con MSSQL usamos el paquete oficial de Microsoft: mssql-django junto con pyodbc.

3. Ingeniería inversa con inspectdb

No hubo que teclear modelos a mano desde cero. Corrí el comando:

python manage.py inspectdb --database=mssql_legacy > modelos.py

Esto generó el archivo modelos.py construyendo automáticamente las clases y campos basados en las tablas existentes en la base de datos de MSSQL.

4. Modularizar y adaptar al Admin de Django

Con los modelos listos:

  • Los separé en aplicaciones modulares de Django.
  • Ajusté las opciones de los modelos para hacerlos funcionales y auditables desde el panel de administración de Django.
  • Configuré los modelos legacy con managed = False para evitar que las migraciones de Django alteraran la base de datos de producción local.

5. Crear la API y el frontend

Esta parte fue bastante compleja porque requirió poner mucho cuidado en la seguridad, tanto a nivel de sitio como de autenticación de usuarios y permisos.

En aquel momento todavía no usábamos agentes de IA autónomos, pero ya existía ChatGPT: le hacía preguntas sobre qué camino tomar, analizaba los snippets y luego los adaptaba e implementaba. Esto fue allá por el lejano 2024.


Conclusión

Llevar un sistema de escritorio a la nube no significa tirar a la basura años de desarrollo ni paralizar a tus clientes. Con una arquitectura híbrida, empezando por lectura y aislando los servicios con Docker, podés modernizarte de forma segura paso a paso.