Día 68 - Set Up de Jenkins Server (instalación con apt + setup inicial vía UI)
Problema / Desafío
El equipo DevOps de xFusionCorp arranca con sus pipelines CI/CD y eligió Jenkins como servidor. Hay que instalarlo en la máquina jenkins y dejarlo accesible con un usuario admin configurado.
Requirements:
- Instalar Jenkins con
apt(no manual, no Docker) - Arrancar el servicio con
service(nosystemctldirecto) - Crear usuario admin vía la UI del setup wizard:
- Username:
theadmin - Password:
Adm!n321 - Full name:
Ravi - Email:
ravi@jenkins.stratos.xfusioncorp.com - Si hay timeout al arrancar, revisar
/var/log/jenkins/jenkins.log
Acceso al server: SSH como root con password S3curePass desde el jump host.
Conceptos clave
Qué es Jenkins y por qué se usa
Jenkins es un servidor de automatización open source escrito en Java. Su rol típico:
| Capa | Qué hace Jenkins |
|---|---|
| CI (Continuous Integration) | Detecta commits a un repo, corre tests, reporta resultados |
| CD (Continuous Delivery / Deployment) | Construye artifacts (Docker images, JARs, etc.), los pushea a registries, despliega a servidores |
| Orquestación de tareas | Cualquier script repetitivo: backups, reportes, batch jobs |
| Plugin marketplace | ~1900+ plugins para integrar con casi cualquier herramienta (Git, K8s, AWS, Slack, etc.) |
Conceptos de Jenkins que aparecerán en days posteriores:
| Concepto | Definición |
|---|---|
| Job / Item | Una tarea configurada (build, deploy, test). Tipos: Freestyle, Pipeline, Multibranch |
| Pipeline | Un job definido como código (Jenkinsfile) — Declarativo o Scripted (Groovy) |
| Build | Una ejecución específica de un job |
| Executor | Slot de cómputo donde corre un build (puede haber varios en el master y/o en agents) |
| Agent / Node | Máquina (física, VM o container) que ejecuta builds. El master coordina, los agents corren |
| Workspace | Directorio en el agent donde se hace el checkout del repo y se ejecutan los pasos |
| Trigger | Qué dispara un build: webhook de SCM, scheduler tipo cron, manual, upstream job |
Por qué Java 21 (no Java 8 / 11)
Jenkins 2.x usa Java como runtime, pero cada versión LTS sube los requisitos. La tabla actual:
| Versión de Jenkins | Java soportado |
|---|---|
| 2.346.x – 2.426.x | Java 11 o 17 |
| 2.427.x+ | Java 17 o 21 |
| 2.500+ (este lab) | Java 17 o 21 |
Por eso este lab arranca con
apt install openjdk-21-jreantes de Jenkins. Con Java 11 el servicio fallaría al arrancar con error de "unsupported class file version".
Por qué fontconfig antes de Java
La librería AWT de Java (usada por Jenkins para generar imágenes — gráficos de build trends, badges) requiere fonts del sistema. Sin fontconfig, Jenkins arranca pero ciertas operaciones de UI/reportes pueden fallar con NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager. Es un requisito histórico de la JVM en Linux, no específico de Jenkins.
service jenkins start vs systemctl start jenkins
En Ubuntu 20.04+ (sistemas systemd), los dos comandos son equivalentes:
service jenkins startes un wrapper de compatibilidad heredado de sysvinit- Internamente delega a
systemctl start jenkins.service - El output
Synchronizing state of jenkins.service with SysV service scriptconfirma que systemd reconoce ambos comandos
El lab pide service específicamente porque:
- Es portable entre distros (funciona en sistemas viejos sysvinit y nuevos systemd)
- El wrapper sysv-install garantiza que el unit file de systemd quede registrado correctamente
- Es la convención más usada en docs históricas — el lab valida que el servicio quede arrancable de esta forma
Estructura de archivos de Jenkins en Ubuntu
| Path | Qué contiene |
|---|---|
/var/lib/jenkins/ |
JENKINS_HOME — config, jobs, plugins, builds, secrets. Backup point principal |
/var/lib/jenkins/secrets/initialAdminPassword |
Password de un solo uso para desbloquear el setup wizard |
/var/lib/jenkins/jobs/<job-name>/ |
Configuración y builds de cada job |
/var/lib/jenkins/plugins/ |
Plugins instalados (.jpi o .hpi) |
/var/lib/jenkins/users/ |
Usuarios y sus credenciales (incluido el admin que se crea en el wizard) |
/var/log/jenkins/jenkins.log |
Log principal del servicio — lo primero a revisar en cualquier problema |
/etc/default/jenkins |
Variables de entorno del servicio (memoria de JVM, puerto, etc.) |
/usr/lib/systemd/system/jenkins.service |
Unit file de systemd |
/usr/share/java/jenkins.war |
El .war ejecutable de Jenkins (no se toca a mano) |
El setup wizard — qué pasa al arrancar Jenkins por primera vez
Al levantar Jenkins, escucha en :8080 y bloquea el acceso hasta completar 4 pasos:
- Unlock: ingresar el
initialAdminPassword(sale en el log y en/var/lib/jenkins/secrets/initialAdminPassword) - Plugins: instalar el set sugerido (Git, Pipeline, GitHub, etc.) o seleccionar específicos
- Crear admin user: username, password, full name, email
- Instance config: URL pública del Jenkins (para webhooks y notificaciones)
El initialAdminPassword se invalida después del wizard — el acceso pasa al admin user creado en el paso 3.
Pasos
- Conectarse al jenkins server desde el jump host
- Instalar
fontconfigyopenjdk-21-jre - Agregar el APT repo oficial de Jenkins (key + sources list)
apt install jenkins- Habilitar el servicio con
systemctl enable jenkins - Arrancar con
service jenkins start - Verificar estado y proceso
- Leer el initial admin password
- Acceder a la UI por
http://<jenkins-host>:8080/ - Completar el wizard creando el usuario admin con los datos del lab
Comandos / Código
1. Conexión al jenkins server
2. Pre-requisitos: Java 21 y fontconfig
Validación:
openjdk version "21.0.11" 2026-04-21
OpenJDK Runtime Environment (build 21.0.11+10-1-24.04.2-Ubuntu)
OpenJDK 64-Bit Server VM (build 21.0.11+10-1-24.04.2-Ubuntu, mixed mode, sharing)
3. Agregar el APT repo oficial de Jenkins
Pasos según la doc oficial:
# Importar la clave GPG del repo
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
# Agregar el repo a las sources de apt
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \
"https://pkg.jenkins.io/debian-stable binary/" | \
sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
# Refresh del cache de apt
sudo apt update
Por qué
signed-by=en lugar deapt-key add:apt-keyestá deprecated desde Debian 11 / Ubuntu 22.04. El método moderno es referenciar la clave en el archivo de sources directamente — más seguro porque la clave solo aplica a ese repo, no a todo apt.
4. Instalar Jenkins
Validación de versión:
5. Habilitar y arrancar el servicio
Synchronizing state of jenkins.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable jenkins
6. Verificar el proceso
Detalles a notar:
| Campo | Valor | Significado |
|---|---|---|
| Usuario | jenkins |
UID dedicado, no root. El paquete lo crea automáticamente |
VSZ (memoria virtual) |
9314068 KB (~9.3 GB) |
Address space reservado por la JVM — no es uso real |
RSS (memoria real) |
771568 KB (~771 MB) |
Memoria residente actual. Sube según número de builds activos |
| Comando | /usr/bin/java ... |
El runtime — Jenkins es un proceso Java |
Que
VSZsea 9.3 GB es normal en procesos Java — la JVM reserva mucho address space pero solo usa lo que necesita. La métrica relevante esRSS.
7. Leer el initial admin password
El log también lo expone:
8. Verificar que la UI responde
HTTP/2 200
content-type: text/html;charset=utf-8
x-hudson: 1.395
x-jenkins: 2.555.2
x-jenkins-session: 3039cc01
Headers a notar:
x-jenkins: 2.555.2— versión confirmada por el headerx-hudson: 1.395— header legacy del proyecto Hudson (Jenkins forkeó Hudson en 2011, mantiene el header por compat)x-frame-options: sameorigin— protección contra clickjackingcross-origin-opener-policy: same-origin— aislamiento de procesos del browser
9. Setup wizard vía UI
Pasos en el browser apuntando a http://<jenkins-host>:8080/:
- Unlock Jenkins: pegar el
initialAdminPassword(ea7f2b7938904bc19bc9820ec000d741) - Customize Jenkins: elegir "Install suggested plugins" — instala ~30 plugins core (Git, Pipeline, GitHub, Folders, Build Timeout, Credentials Binding, Timestamper, etc.)
- Create First Admin User:
| Campo | Valor del lab |
|---|---|
| Username | theadmin |
| Password | Adm!n321 |
| Full name | Ravi |
ravi@jenkins.stratos.xfusioncorp.com |
- Instance Configuration: aceptar la URL pública que detecta Jenkins (en KodeKloud es la URL del proxy del lab)
- Start using Jenkins: dashboard final con "Welcome to Jenkins!"
Validación final
Después del wizard:
- Dashboard muestra "Welcome to Jenkins!" con el nombre del admin user
http://<jenkins-host>:8080/memuestra el perfil del user conFull name: Raviy email correcto/var/lib/jenkins/users/theadmin_<id>/config.xmlcontiene el user creado
Anatomía del proceso instalado — qué crea el paquete .deb
| Recurso | Creado por el .deb |
|---|---|
Usuario jenkins (UID/GID) |
useradd automático en post-install |
Directorio /var/lib/jenkins/ |
Como JENKINS_HOME, propiedad de jenkins:jenkins |
Unit file jenkins.service |
Registrado en systemd, enabled opcional manualmente |
Log dir /var/log/jenkins/ |
Propiedad de jenkins:adm |
/etc/default/jenkins |
Defaults editables: HTTP_PORT=8080, JAVA_ARGS, etc. |
| Firewall del nodo | No se toca — el paquete no abre puertos. Hay que abrir 8080 si hay firewall |
Troubleshooting
| Problema | Causa | Solución |
|---|---|---|
service jenkins start da timeout |
Falta Java o la versión no es compatible (Jenkins 2.500+ requiere Java 17 o 21) | java -version para verificar. Si falta, apt install openjdk-21-jre |
service jenkins status reporta inactive después del start |
Falla al levantar la JVM por OOM o config inválida | Revisar /var/log/jenkins/jenkins.log para el stack trace del error |
Log muestra NoClassDefFoundError: ... X11FontManager |
Falta fontconfig — la JVM no puede inicializar AWT |
sudo apt install fontconfig y reiniciar el servicio |
apt install jenkins falla con Unable to locate package jenkins |
El APT repo de Jenkins no está agregado o no se hizo apt update después de agregarlo |
Repetir los pasos de agregar el GPG key + sources list, luego apt update |
El log muestra Permission denied al escribir en /var/lib/jenkins/ |
Permisos rotos del JENKINS_HOME | chown -R jenkins:jenkins /var/lib/jenkins/ y reiniciar |
| La UI responde pero el setup wizard no aparece (va directo al dashboard) | Jenkins ya pasó el setup (instalación previa con state). El initialAdminPassword quedó invalidado |
Borrar /var/lib/jenkins/ (cuidado: borra todo) y reiniciar, o seguir con el admin existente |
curl al puerto 8080 da Connection refused |
El servicio no terminó de arrancar (Jenkins tarda ~30s en levantar) o no escucha en 0.0.0.0 |
Esperar 30-60s; verificar con ss -tlnp | grep 8080 |
| Olvidé el admin password después del wizard | El admin se crea con hash en /var/lib/jenkins/users/ |
Editar /var/lib/jenkins/config.xml y deshabilitar security temporalmente, o resetear el hash |
x-jenkins-session cambia cada request |
Comportamiento normal — cada response trae el ID de sesión del nodo | No es un bug |
Conexión con días anteriores
Día 68 marca la transición del journal de Kubernetes (Días 48–67) a CI/CD. Los puentes entre los dos mundos:
- Git (Días 21–34): Jenkins típicamente se conecta a un repo Git, hace checkout, corre tests, construye. Los hooks de
post-updatedel Día 34 son la versión "casera" de un trigger de Jenkins. - Docker (Días 35–47): pipelines de Jenkins típicamente construyen imágenes Docker (
docker build), las pushean a registries, y luego despliegan. - Kubernetes (Días 48–67): el deploy step de un pipeline moderno es
kubectl applyohelm upgradecontra el cluster. Jenkins suele tener un Service Account con RBAC limitado al namespace de la app.
La cadena completa en producción típica:
Developer → git push
↓
GitHub webhook
↓
Jenkins pipeline (Día 68+)
├── git checkout
├── unit tests
├── docker build + push
├── kubectl apply (Día 49+)
└── notificación a Slack
En el journal vienen días de pipelines, freestyle jobs, integraciones — todos construyen sobre la instalación de hoy.