1. Introducción
GLPI es una plataforma libre de gestión de activos informáticos y mesa de ayuda: mantiene el inventario de equipos, software y licencias, y gestiona los tickets de soporte sobre esos mismos activos. Esta guía la despliega con Docker Compose, usando MariaDB como base de datos y un proxy inverso Nginx con certificado autofirmado por delante, y añade el agente oficial GLPI-Agent en dos equipos reales para que el inventario se rellene solo.
glpi/glpi), publicada por el propio equipo de GLPI en Docker Hub y en el registro de GitHub. Durante años solo existieron imágenes mantenidas por la comunidad, y por eso la mayoría de tutoriales antiguos siguen apuntando a ellas. La imagen oficial se reconstruye periódicamente para incorporar parches de seguridad del sistema base y de PHP, sin tocar el código de la aplicación.2. Variables de esta guía
Todos los bloques usan los siguientes marcadores en MAYÚSCULAS. Sustitúyelos por los valores reales del entorno donde se aplique esta guía.
| Marcador | Qué es | Dónde se obtiene |
|---|---|---|
IP_HOST_DOCKER | IP del host Linux donde corre el stack con Docker | La interfaz de red de ese host (ip a) |
IP_HOST_DOCKER_2 | Segunda IP del host, solo si dispone de más de una interfaz de red y los agentes van a alcanzarlo por una distinta a la de administración | La segunda interfaz de ese host (ip a). Si el servidor solo tiene una IP, este marcador se ignora |
GLPI_DB_PASSWORD | Contraseña del usuario glpi en la base de datos | Se define en /docker/glpi/.env (sección 5) |
MARIADB_ROOT_PASSWORD | Contraseña root de MariaDB, necesaria para el paso de zonas horarias | Se define en /docker/glpi/.env (sección 5) |
FINGERPRINT_CERT | Huella SHA256 del certificado autofirmado, que los agentes usarán para confiar en el servidor | La revela el propio agente en su primer intento (secciones 11 y 12) |
ss -tlnp | grep 8446 y elige otro libre si hiciera falta, cambiándolo en las secciones 5, 6, 7, 8, 11 y 12.3. Arquitectura y flujo
Tres contenedores en el servidor, y un agente nativo instalado en cada equipo a inventariar. El agente no vive en un contenedor: se instala directamente sobre el sistema operativo de cada máquina, tal y como se haría en un despliegue real sobre equipos físicos o virtuales.
[UBUNTU SERVER] [WINDOWS 11]
glpi-agent GLPI-Agent
| |
| inventario por HTTPS |
| (el agente inicia la conexión)
+------------+-------------+
|
v
https://IP_HOST_DOCKER:8446 (certificado autofirmado)
|
v
[glpi-proxy] :8446 (Nginx)
|
v
[glpi] :80 (GLPI + cron interno)
|
v
[glpi-db] (MariaDB)
/front/inventory.php. Ningún equipo inventariado necesita abrir puertos de entrada para que esto funcione, lo que mantiene toda la superficie expuesta concentrada en un único punto.4. Requisitos
- Un host Linux con Docker Engine y el plugin Docker Compose (
docker compose, sin guion) ya instalados. - Un Ubuntu Server y un Windows 11 en la misma red, que serán los equipos inventariados.
- Salida a Internet desde los equipos donde se instale el agente, únicamente para descargar el instalador desde GitHub.
- Al menos 2 GB de RAM libres para el contenedor de GLPI.
5. Levantar MariaDB y GLPI con Docker
Misma organización de siempre: cada stack en su carpeta dentro de /docker, y las credenciales en un .env aparte, nunca escritas dentro del docker-compose.yml.
sudo mkdir -p /docker/glpi && cd /docker/glpi
sudo nano .env
MARIADB_ROOT_PASSWORD=glpi_root_pwd GLPI_DB_NAME=glpi GLPI_DB_USER=glpi GLPI_DB_PASSWORD=glpi_pwd
sudo chmod 600 .env para que solo root pueda leer el archivo.Ahora el archivo del stack, en la misma carpeta:
sudo nano docker-compose.yml
services:
glpi-db:
image: mariadb:11
container_name: glpi-db
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_DATABASE: ${GLPI_DB_NAME}
MARIADB_USER: ${GLPI_DB_USER}
MARIADB_PASSWORD: ${GLPI_DB_PASSWORD}
volumes:
- glpi-db-data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"]
interval: 5s
timeout: 5s
retries: 20
start_period: 30s
restart: unless-stopped
glpi:
image: glpi/glpi:11.0
container_name: glpi
environment:
GLPI_DB_HOST: glpi-db
GLPI_DB_PORT: 3306
GLPI_DB_NAME: ${GLPI_DB_NAME}
GLPI_DB_USER: ${GLPI_DB_USER}
GLPI_DB_PASSWORD: ${GLPI_DB_PASSWORD}
TZ: Europe/Madrid
volumes:
- glpi-data:/var/glpi
depends_on:
glpi-db:
condition: service_healthy
restart: unless-stopped
proxy:
image: nginx:alpine
container_name: glpi-proxy
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./proxy-selfsigned.crt:/etc/nginx/certs/proxy-selfsigned.crt:ro
- ./proxy-selfsigned.key:/etc/nginx/certs/proxy-selfsigned.key:ro
ports:
- "8446:8446"
depends_on:
- glpi
restart: unless-stopped
volumes:
glpi-db-data:
glpi-data:
GLPI_DB_* del servicio glpi son las que activan la instalación automática. La documentación oficial es explícita: si falta cualquiera de ellas, GLPI desactiva tanto la instalación como la actualización automáticas y presenta en su lugar el asistente web. No es un fallo, pero conviene saberlo para no confundirse si aparece esa pantalla.glpi-data monta /var/glpi completo, que es donde la imagen coloca la configuración, los archivos subidos, los registros y el marketplace de plugins. Persistir esa ruta es lo que marca la diferencia entre poder recrear el contenedor sin consecuencias y perder la configuración al hacerlo.6. Configurar el proxy inverso con HTTPS propio
Genera un certificado autofirmado con clave EC, válido para la IP del host:
cd /docker/glpi sudo openssl ecparam -name prime256v1 -genkey -noout -out proxy-selfsigned.key sudo openssl req -new -x509 -key proxy-selfsigned.key -out proxy-selfsigned.crt -days 825 \ -subj "/CN=IP_HOST_DOCKER" \ -addext "subjectAltName=IP:IP_HOST_DOCKER"
Servidor con varias interfaces de red
Es habitual que el servidor tenga más de una interfaz: una en la red de administración, desde la que se accede a la interfaz web, y otra en una red interna donde viven los equipos a inventariar. En ese escenario, los agentes alcanzarán el servidor por una IP distinta a la que se usa desde el navegador.
La solución es emitir un único certificado válido para ambas direcciones, añadiendo las dos al campo subjectAltName separadas por comas:
cd /docker/glpi sudo openssl ecparam -name prime256v1 -genkey -noout -out proxy-selfsigned.key sudo openssl req -new -x509 -key proxy-selfsigned.key -out proxy-selfsigned.crt -days 825 \ -subj "/CN=IP_HOST_DOCKER" \ -addext "subjectAltName=IP:IP_HOST_DOCKER,IP:IP_HOST_DOCKER_2"
IP: para direcciones y DNS: para nombres. El valor de CN es indiferente mientras las direcciones reales estén todas en subjectAltName, que es lo que los clientes modernos comprueban en realidad.Ahora la configuración de Nginx:
sudo nano nginx.conf
resolver 127.0.0.11 valid=10s;
server {
listen 8446 ssl;
server_name IP_HOST_DOCKER;
ssl_certificate /etc/nginx/certs/proxy-selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/proxy-selfsigned.key;
# Los inventarios y los documentos adjuntos pueden superar el limite por defecto
client_max_body_size 64M;
location / {
set $upstream_glpi http://glpi:80;
proxy_pass $upstream_glpi;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
resolver 127.0.0.11 (el DNS interno de Docker) junto con set $upstream_glpi; proxy_pass $upstream_glpi; no es cosmético: sin la variable, Nginx intenta resolver el nombre glpi una sola vez al arrancar, y si en ese instante el contenedor todavía no está listo, se niega a arrancar con un error de host not found in upstream. Con la variable, la resolución se hace en cada petición.client_max_body_size 64M evita un problema que aparece más tarde y cuesta relacionar con el proxy: los inventarios de equipos con mucho software instalado, y los documentos que se adjuntan a los tickets, pueden superar el límite por defecto de Nginx (1 MB) y ser rechazados antes de llegar a GLPI.7. Arrancar el stack y verificar
cd /docker/glpi docker compose up -d docker compose ps
El primer arranque tarda más de lo normal porque GLPI crea el esquema completo de la base de datos. Sigue el registro para verlo:
docker logs -f glpi
Cuando termine la instalación automática y no aparezcan errores de conexión a la base de datos, sal con Ctrl+C y comprueba que el proxy responde:
curl -kI https://IP_HOST_DOCKER:8446
HTTP/1.1 200 OK o una redirección confirma que el TLS funciona y que Nginx está alcanzando el contenedor de GLPI.8. Primer acceso y cuentas por defecto
Abre en el navegador:
https://IP_HOST_DOCKER:8446
GLPI se instala con cuatro cuentas de demostración, una por cada perfil, y todas con la contraseña igual al nombre de usuario:
| Usuario | Contraseña | Perfil |
|---|---|---|
glpi | glpi | Super-administrador |
tech | tech | Técnico |
normal | normal | Usuario normal |
post-only | postonly | Autoservicio, solo abrir tickets |
glpi/glpi entra como super-administrador. El propio GLPI muestra un aviso de seguridad en el panel mientras alguna siga con su contraseña original. Nada más entrar por primera vez: cambia la contraseña de glpi, y elimina o desactiva tech, normal y post-only si no las vas a usar, desde Administración → Usuarios.9. Activar el soporte de zonas horarias
GLPI necesita que MariaDB tenga cargada su tabla de zonas horarias y que el usuario de la aplicación pueda consultarla. Sin esto, la instalación no puede fijar su zona horaria y las fechas quedan atadas a la configuración por defecto del servidor.
Primero, dale permiso de lectura al usuario de GLPI sobre esa tabla (te pedirá la contraseña root que definiste en el .env):
docker exec -it glpi-db mariadb -u root -p \ -e "GRANT SELECT ON mysql.time_zone_name TO 'glpi'@'%'; FLUSH PRIVILEGES;"
Después, dile a GLPI que active el soporte:
docker exec -it glpi /var/www/glpi/bin/console database:enable_timezones
Setup → General → General setup.TZ del docker-compose.yml, que afecta a los registros y al reloj del sistema) no es lo mismo que el soporte de zonas horarias de la base de datos, que es lo que permite a GLPI almacenar y convertir fechas correctamente entre distintas ubicaciones. Configurar solo la primera no elimina el aviso.10. Activar el inventario nativo
Desde GLPI 10, el inventario viene integrado en el producto y ya no hace falta el antiguo complemento FusionInventory. Pero llega desactivado de fábrica: si instalas los agentes sin dar este paso, enviarán su inventario y el servidor lo descartará sin decir gran cosa.
- Entra como administrador y ve a
Administración → Inventario. - Abre la pestaña de configuración general del inventario.
- Activa la opción para habilitar el inventario.
- Revisa las opciones de importación (equipos, monitores, impresoras, componentes) y déjalas según lo que quieras que entre en el inventario.
- Guarda.
/front/inventory.php. No hace falta escribirlo en la configuración del agente: basta con darle la URL base del servidor y él resuelve la ruta por su cuenta.11. Instalar el agente en Ubuntu Server
El proyecto GLPI publica un instalador en Perl que detecta la distribución y coloca el paquete adecuado. Descárgalo desde las publicaciones oficiales del agente, sustituyendo el número de versión por el actual que veas en la página de releases:
cd /tmp wget https://github.com/glpi-project/glpi-agent/releases/download/1.19/glpi-agent-1.19-linux-installer.pl sudo perl glpi-agent-1.19-linux-installer.pl
Ahora configura a qué servidor debe reportar. En lugar de editar el archivo principal, se añade un fichero propio en la carpeta de configuración adicional, que es la forma recomendada porque sobrevive a las actualizaciones del paquete:
sudo nano /etc/glpi-agent/conf.d/00-clockwork.cfg
server = https://IP_HOST_DOCKER:8446 no-ssl-check = 1 tag = laboratorio
Fuerza una ejecución inmediata para comprobar que llega:
sudo systemctl restart glpi-agent sudo glpi-agent --force --debug
Del atajo a la configuración correcta
no-ssl-check desactiva por completo la validación del certificado del servidor. La documentación oficial de GLPI es tajante en que no debe quedarse así en producción: sin validación, el agente enviaría su inventario a cualquiera que suplantara la dirección del servidor. Su uso correcto es puntual, exactamente como aquí: activarla una sola vez para que el agente muestre en su registro la huella del certificado.En la salida del comando anterior, con no-ssl-check activo, el agente indica la huella SHA256 del certificado del servidor. Cópiala, y sustituye el contenido del archivo de configuración por esta versión definitiva:
server = https://IP_HOST_DOCKER:8446 ssl-fingerprint = FINGERPRINT_CERT tag = laboratorio
sudo systemctl restart glpi-agent sudo glpi-agent --force --debug
ssl-fingerprint, el agente sigue validando el certificado, pero contra la huella concreta que le has indicado en lugar de contra una autoridad pública. Se conserva la autenticación del servidor sin necesidad de un certificado firmado por una entidad reconocida: es la solución recomendada por el propio proyecto para certificados privados.tag es opcional pero muy útil en cuanto crece el parque: es una etiqueta libre que viaja con el inventario y permite después clasificar automáticamente los equipos por sede, departamento o entidad mediante las reglas de importación de GLPI.12. Instalar el agente en Windows 11
Descarga el instalador MSI de 64 bits desde la misma página de releases y ejecútalo en modo silencioso desde PowerShell como administrador. Igual que en Linux, el primer intento sirve para obtener la huella del certificado:
msiexec /i "C:\Users\$env:USERNAME\Downloads\GLPI-Agent-1.19-x64.msi" /quiet SERVER="https://IP_HOST_DOCKER:8446" NO_SSL_CHECK=1 TAG="laboratorio" RUNNOW=1 EXECMODE=1 /l*v "C:\Users\$env:USERNAME\Downloads\glpi-agent-install.log"
Comprueba que el servicio quedó instalado y en marcha:
Get-Service -Name "glpi-agent"
Y revisa el registro del agente, donde aparecerá la huella del certificado:
Get-Content "C:\Program Files\GLPI-Agent\logs\glpi-agent.log" -Tail 40
Con la huella ya conocida, reinstala pasando la configuración correcta en lugar de desactivar la validación:
msiexec /i "C:\Users\$env:USERNAME\Downloads\GLPI-Agent-1.19-x64.msi" /quiet SERVER="https://IP_HOST_DOCKER:8446" SSL_FINGERPRINT="FINGERPRINT_CERT" TAG="laboratorio" RUNNOW=1 EXECMODE=1
HKEY_LOCAL_MACHINE\SOFTWARE\GLPI-Agent. Se puede editar ahí directamente y reiniciar el servicio para aplicar el cambio; el resultado es el mismo.EXECMODE=1 lo instala como servicio (la alternativa es tarea programada, útil en servidores donde no interesa un servicio permanente), RUNNOW=1 lanza un inventario nada más terminar la instalación, y ADD_FIREWALL_EXCEPTION=1 abriría el puerto 62354 si se quisiera permitir ejecuciones bajo demanda desde el servidor.13. Verificar el inventario en GLPI
En la interfaz web, ve a Activos → Equipos. Deberían aparecer los dos equipos con su nombre, y al abrir cualquiera de ellos verás la información recogida automáticamente: procesador, memoria, discos, tarjetas de red, sistema operativo y el listado completo de software instalado.
Para revisar los agentes en sí y cuándo contactaron por última vez:
Administración → Inventario → Agentesmuestra cada agente registrado, su versión y la fecha del último contacto.- En la ficha de cada equipo, el historial permite ver qué cambió entre un inventario y el siguiente.
Una última comprobación confirma que el inventario se mantiene vivo y no es una foto fija: instalar o desinstalar cualquier programa en uno de los equipos, forzar un inventario nuevo y verificar que GLPI refleja el cambio en el listado de software y lo registra en el historial del activo.
14. Tabla de puertos y componentes
| Puerto | Componente | Sentido de la conexión | Para qué sirve |
|---|---|---|---|
| 8446/tcp | glpi-proxy (Nginx) | Navegador y agentes → contenedor | Único punto de entrada: interfaz web y recepción de inventarios, por HTTPS |
| — | glpi (Docker, interno) | proxy → glpi | Aplicación GLPI y su cron interno; no publica ningún puerto al host |
| — | glpi-db (Docker, interno) | glpi → glpi-db | MariaDB; no necesita exponerse al host |
| 62354/tcp | GLPI-Agent en cada endpoint | Servidor → agente | No se usa en esta guía. Solo hace falta para pedir al agente una ejecución bajo demanda |
15. Errores comunes y cómo resolverlos
| Problema | Causa probable | Solución |
|---|---|---|
| Al entrar aparece el asistente de instalación web en vez de la pantalla de login | Falta alguna de las cinco variables GLPI_DB_*, así que la instalación automática se desactivó |
Revisar el servicio glpi del compose y confirmar con docker compose config que las cinco se resolvieron (sección 5) |
El contenedor glpi-proxy se reinicia en bucle con host not found in upstream "glpi" |
Nginx intentó resolver el nombre una sola vez al arrancar y GLPI aún no estaba listo | Confirmar que nginx.conf usa resolver 127.0.0.11 con la variable $upstream_glpi (sección 6) |
No aparece el selector de zona horaria en Setup → General → General setup |
La tabla de zonas horarias de MariaDB no está cargada o no es accesible para el usuario de GLPI. No se muestra ningún aviso: la opción simplemente no está | Ejecutar los dos comandos de la sección 9, en ese orden, y volver a comprobar la pestaña |
| Los agentes parecen funcionar pero no aparece ningún equipo | El inventario nativo sigue desactivado en el servidor | Activarlo en Administración → Inventario (sección 10) y forzar un nuevo inventario en los agentes |
El agente registra certificate verify failed |
Comportamiento esperado con un certificado autofirmado: el agente no reconoce la autoridad que lo emitió | Obtener la huella con no-ssl-check una sola vez y configurar ssl-fingerprint de forma permanente (secciones 11 y 12) |
| El navegador o los agentes funcionan por una interfaz del servidor pero no por otra | El certificado se emitió solo para una de las direcciones del host, y no incluye aquella por la que se está accediendo | Regenerar el certificado incluyendo todas las direcciones en subjectAltName (sección 6). Al cambiar la huella, hay que actualizarla también en los agentes ya configurados |
| El inventario de un equipo concreto falla mientras otros funcionan | El envío supera el tamaño máximo admitido por el proxy | Confirmar client_max_body_size en nginx.conf y subirlo si hace falta (sección 6) |
| Tras recrear el contenedor se pierde la configuración de GLPI | No se persistió /var/glpi, que es donde vive la configuración |
Comprobar que el volumen glpi-data está declarado y montado (sección 5) |
16. Notas de ampliación
El montaje de esta guía cubre lo necesario para tener el inventario automático funcionando y la mesa de ayuda operativa. Para un uso continuado conviene ampliar con:
- Reglas de importación de activos, para que los equipos entren clasificados solos en la entidad, ubicación o grupo que corresponda, apoyándose en la etiqueta
tagque ya envían los agentes. - Notificaciones por correo, para que la apertura y actualización de tickets avise automáticamente a quien corresponda.
- Descubrimiento de red por SNMP, que permite inventariar switches, impresoras y otros equipos donde no se puede instalar un agente.
- Dominio propio y certificado válido en lugar del autofirmado, lo que además simplifica los agentes: con un certificado reconocido dejan de necesitar la huella y basta con indicarles la URL.
- Copias de seguridad del volumen de MariaDB y del volumen
glpi-data, que contiene la configuración y todos los documentos adjuntos a los tickets. - Integración con la monitorización, para que una alerta de un sistema como Zabbix abra automáticamente un ticket sobre el activo correspondiente ya inventariado en GLPI.