Despliegue en servidor Windows
Para quién es esta guía
Una guía paso a paso y muy detallada para instalar Gestión Civis en un servidor Windows (Windows Server 2019/2022), pensada para alguien con poca experiencia. Si tu servidor es Linux, usa la guía de servidor; si es Google Cloud, la guía de Google Cloud.
¿Qué vamos a montar?
En Windows usaremos herramientas equivalentes a las de Linux, pero nativas del sistema:
flowchart LR
U["👤 Usuario"] -->|HTTPS| IIS["IIS<br/>(web + proxy + HTTPS)"]
IIS -->|páginas| D["Frontend (dist)"]
IIS -->|/api| W["waitress + Flask<br/>(backend, 127.0.0.1:5000)"]
W --> P[("PostgreSQL")]
W --> S["Almacenamiento"]
TS["Programador de tareas<br/>(cada 5 min)"] --> W
| Pieza Windows | Equivale en Linux a… | Qué hace |
|---|---|---|
| IIS (Internet Information Services) | Nginx | Sirve la web, reenvía /api al backend y pone el HTTPS. |
| waitress | gunicorn | El motor que ejecuta el backend Flask (gunicorn no funciona en Windows). |
| NSSM | systemd | Convierte el backend en un servicio de Windows que arranca solo. |
| Programador de tareas | cron | Lanza las tareas automáticas cada pocos minutos. |
| PostgreSQL para Windows | PostgreSQL | La base de datos. |
Aviso importante: generación de PDF
En Windows, la librería que genera los PDF (WeasyPrint) necesita un componente extra llamado GTK runtime. Es el punto que más falla en Windows; lo instalaremos en el Paso 3 y no debe omitirse o los recibos e informes en PDF no funcionarán.
Paso 0. Conectarse al servidor (Escritorio Remoto)
A un servidor Windows se accede con Conexión a Escritorio Remoto (RDP):
- En tu PC, pulsa Inicio y escribe "Conexión a Escritorio Remoto".
- Introduce la IP del servidor y conéctate con el usuario administrador.
Una vez dentro, verás el escritorio del servidor. Abriremos PowerShell como administrador para casi todo:
- Botón Inicio → escribe PowerShell → clic derecho → Ejecutar como administrador.
Sobre los comandos
Los comandos de esta guía se escriben en esa ventana de PowerShell. Cópialos en orden y comprueba que cada uno termina sin errores en rojo.
Paso 1. Instalar Python
- Descarga Python 3.11 (o superior) desde python.org/downloads.
- Ejecuta el instalador y, muy importante, marca la casilla "Add python.exe to PATH" antes de pulsar Install Now.
- Comprueba la instalación (cierra y reabre PowerShell):
Debe mostrar la versión instalada.
Paso 2. Instalar PostgreSQL
- Descarga el instalador de PostgreSQL para Windows desde enterprisedb.com/downloads.
- Instálalo. Durante la instalación:
- Define y anota la contraseña del usuario
postgres. - Deja el puerto por defecto 5432.
- Se instalará también pgAdmin (una herramienta gráfica para la base de datos).
- Crea la base de datos y el usuario. Abre pgAdmin (o usa el "SQL Shell (psql)" del menú Inicio) y ejecuta:
CREATE USER civis WITH PASSWORD 'CAMBIA-ESTA-CONTRASEÑA';
CREATE DATABASE gestion_civis OWNER civis;
Cambia la contraseña
Sustituye CAMBIA-ESTA-CONTRASEÑA por una contraseña fuerte y anótala. La
cadena de conexión será:
postgresql://civis:CAMBIA-ESTA-CONTRASEÑA@localhost:5432/gestion_civis
Paso 3. Instalar GTK runtime (para los PDF)
WeasyPrint necesita las librerías GTK3 para funcionar en Windows:
- Descarga el instalador "GTK3 runtime for Windows" desde el repositorio
público
github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases
(el fichero
gtk3-runtime-...-win64.exe). - Ejecútalo y, cuando lo pregunte, marca la opción de añadir GTK al PATH del sistema.
- Reinicia el servidor (o al menos cierra la sesión y vuelve a entrar) para que el PATH se actualice.
Cómo saber si funcionó
Tras instalar el backend (Paso 5), si al generar un PDF aparece un error que
menciona libgobject, cairo o pango, es que GTK no está bien instalado o no
está en el PATH. Repite este paso y reinicia.
Paso 4. Descargar el código
Elige una carpeta para la aplicación, por ejemplo C:\gestion-civis.
Instala Git para Windows y luego:
Descarga el código en .zip, descomprímelo y copia el contenido en
C:\gestion-civis (de modo que run.py y requirements.txt queden
directamente en esa carpeta).
Paso 5. Instalar el backend
Crea el entorno virtual e instala las dependencias (incluido waitress, el motor que servirá la app en Windows):
cd C:\gestion-civis
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install waitress
Si PowerShell bloquea la activación
Si al activar el entorno aparece un error de "scripts deshabilitados", ejecuta una vez (como administrador):
y vuelve a intentar.\.venv\Scripts\Activate.ps1.
Crear el fichero de configuración .env
Crea el fichero C:\gestion-civis\.env (puedes usar el Bloc de notas). Su
contenido, ajustando los valores:
SECRET_KEY=pega-aqui-una-cadena-larga-y-aleatoria
DATABASE_URL=postgresql://civis:CAMBIA-ESTA-CONTRASEÑA@localhost:5432/gestion_civis
STORAGE_PROVIDER=local
STORAGE_LOCAL_PATH=C:\gestion-civis\storage
FRONTEND_URL=https://civis.tu-ayuntamiento.es
FRONTEND_ALLOWED_ORIGINS=https://civis.tu-ayuntamiento.es
IA_AUDITORIA_ENABLED=false
GOOGLE_API_KEY=
Generar la SECRET_KEY
Copia el resultado como valor deSECRET_KEY.
Preparar la base de datos y comprobar
Comprueba que el backend arranca con waitress:
Abre otra ventana y prueba http://127.0.0.1:5000/api/_routes en el navegador del
servidor: debe devolver texto JSON. Vuelve a la primera ventana y pulsa Ctrl+C
para pararlo (lo dejaremos como servicio en el Paso 7).
Paso 6. Compilar el frontend
El frontend necesita Node.js:
- Instala Node.js LTS desde nodejs.org (instalador
.msi). - Compila el frontend:
Esto crea la carpeta dist. Cópiala a la ruta desde la que IIS servirá la web,
por ejemplo C:\inetpub\civis:
New-Item -ItemType Directory -Force C:\inetpub\civis
Copy-Item -Recurse -Force .\dist\* C:\inetpub\civis\
Paso 7. El backend como servicio de Windows (NSSM)
Para que el backend arranque solo y se reinicie si falla, lo registramos como servicio con NSSM:
- Descarga NSSM desde nssm.cc/download y copia
nssm.exe(versión win64) aC:\gestion-civis\nssm.exe. - Instala el servicio:
Se abre una ventana. Rellena:
- Path:
C:\gestion-civis\.venv\Scripts\python.exe - Startup directory:
C:\gestion-civis - Arguments:
-m waitress --listen=127.0.0.1:5000 --call app:create_app
En la pestaña Details ponle un nombre descriptivo, y en Exit actions deja que reinicie automáticamente. Pulsa Install service.
- Arranca el servicio y comprueba su estado:
Debe aparecer Running.
Logs del servicio
En NSSM, pestaña I/O, puedes indicar ficheros donde volcar la salida y los
errores del backend (p. ej. C:\gestion-civis\logs\backend.log). Muy útil para
diagnosticar.
Paso 8. Las tareas automáticas (Programador de tareas)
El scheduler de MOS (SIR, avisos, prescripciones, proyección…) se lanza con
flask civis-system-run. En Windows lo programamos con el Programador de
tareas:
# Crea una tarea que se ejecuta cada 5 minutos
$accion = New-ScheduledTaskAction -Execute "C:\gestion-civis\.venv\Scripts\flask.exe" `
-Argument "civis-system-run" -WorkingDirectory "C:\gestion-civis"
$disparo = New-ScheduledTaskTrigger -Once -At (Get-Date) `
-RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName "GestionCivis-Scheduler" `
-Action $accion -Trigger $disparo -RunLevel Highest -User "SYSTEM"
Una sola tarea
Programa esto una única vez. No lo dupliques ni lo ejecutes también en otra máquina, o las acciones automáticas se duplicarían.
Para comprobar que se ejecuta, ábrela en el Programador de tareas (Inicio → "Programador de tareas" → Biblioteca) y revisa la columna Resultado de la última ejecución.
Paso 9. IIS: la web, el proxy y el HTTPS
IIS servirá el frontend y reenviará /api al backend.
9.1 Instalar IIS y sus extensiones
Después, descarga e instala estas dos extensiones (necesarias para el proxy):
- URL Rewrite — iis.net/downloads/microsoft/url-rewrite
- Application Request Routing (ARR) — iis.net/downloads/microsoft/application-request-routing
Tras instalar ARR, actívalo como proxy: abre el Administrador de IIS → nodo raíz del servidor → Application Request Routing Cache → (panel derecho) Server Proxy Settings → marca Enable proxy → Apply.
9.2 Crear el sitio web
- En el Administrador de IIS, clic derecho en Sitios → Agregar sitio web.
- Nombre:
GestionCivis. - Ruta de acceso física:
C:\inetpub\civis(donde copiaste el frontend). -
Enlace: tipo
https(si ya tienes certificado) ohttpde momento; Nombre de host:civis.tu-ayuntamiento.es. -
Coloca en
C:\inetpub\civisun ficheroweb.configcon esta configuración (reenvía/apial backend y hace que las rutas del frontend funcionen):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- Reenviar /api al backend (waitress en el puerto 5000) -->
<rule name="API" stopProcessing="true">
<match url="^api/(.*)" />
<action type="Rewrite" url="http://127.0.0.1:5000/api/{R:1}" />
</rule>
<!-- El frontend es una SPA: lo demás va a index.html -->
<rule name="SPA" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
<!-- Tamaño máximo de subida (adjuntos): ~15 MB -->
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="15728640" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
9.3 Activar HTTPS
- Opción A (recomendada, gratis): win-acme. Descarga
win-acme en el servidor, ejecútalo (
wacs.exe) y sigue el asistente: detecta el sitio de IIS y obtiene e instala un certificado Let's Encrypt, renovándolo automáticamente. - Opción B: certificado propio del ayuntamiento. Impórtalo en IIS
(Certificados de servidor) y asígnalo en el enlace
httpsdel sitio.
DNS
Para usar civis.tu-ayuntamiento.es necesitas un registro DNS de tipo A que
apunte ese nombre a la IP pública del servidor, y que el puerto 443 esté
abierto en el firewall de Windows y en el del ayuntamiento.
Paso 10. Comprobar que todo funciona
- Abre en un navegador
https://civis.tu-ayuntamiento.es→ debe aparecer la pantalla de inicio de sesión. - Entra con el usuario administrador inicial (el que crea
seed.py). - Genera algo en PDF (un recibo o un informe) para confirmar que GTK está bien instalado.
Si algo va mal
| Síntoma | Posible causa y solución |
|---|---|
| Error 502 / la web no muestra datos | El servicio del backend no corre: Get-Service GestionCivis; arráncalo y revisa su log. |
Error al generar PDF (pango, cairo, libgobject) |
Falta el GTK runtime (Paso 3) o no está en el PATH. Reinstálalo y reinicia. |
/api da 404 o no reenvía |
Revisa que ARR esté instalado y con el proxy habilitado (Paso 9.1) y el web.config. |
| El servicio no arranca | Revisa en NSSM la ruta a python.exe, el startup directory y el log de errores. |
| Las tareas automáticas no se ejecutan | Revisa la tarea en el Programador de tareas y que el usuario SYSTEM tenga permisos. |
Mantenimiento
Para actualizar a una versión nueva:
cd C:\gestion-civis
git pull # o sustituye los archivos del ZIP
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
flask db upgrade
# si cambió el frontend, recompílalo (Paso 6) y vuelve a copiar a C:\inetpub\civis
Restart-Service GestionCivis
- Copias de seguridad: usa pgAdmin (Backup de la base de datos) o el
comando
pg_dumpque viene con PostgreSQL, y copia también la carpetaC:\gestion-civis\storage. Guárdalas fuera del servidor. - El resto de tareas de operación (logs, monitorización, seguridad) están en
Operación y mantenimiento (los conceptos son los
mismos; en Windows los logs del backend están donde los configuraste en NSSM, y
los servicios se gestionan con
Get-Service/Restart-Service).
Recomendación
Windows Server es perfectamente válido, pero el despliegue tiene más piezas manuales que en Linux (GTK, NSSM, ARR). Si el ayuntamiento no tiene preferencia por Windows, la guía de servidor Linux suele ser más directa.