Mantenimiento y despliegue seguro de sitios en Apache

Capítulo 10

Tiempo estimado de lectura: 9 minutos

+ Ejercicio

Proceso repetible de despliegue: contenido y configuración

Un despliegue seguro en Apache busca dos objetivos: cero sorpresas (validar antes de aplicar) y recuperación rápida (rollback simple). Para lograrlo, conviene separar claramente: (1) el código/contenido del sitio, (2) la configuración de Apache, y (3) los datos (si aplica). La idea es que cada publicación sea un “release” identificable, con copias de seguridad y un procedimiento de verificación previo a recargar.

Estructura recomendada de releases

Una estructura típica (inspirada en despliegues tipo “releases + symlink”) facilita volver atrás sin tocar Apache más de lo necesario:

/var/www/misitio/  (propietario: root o deploy; grupo: www-data) /var/www/misitio/releases/ 2026-02-03_1200/ 2026-02-01_0900/ /var/www/misitio/shared/ logs/ uploads/ cache/ /var/www/misitio/current -> /var/www/misitio/releases/2026-02-03_1200
  • releases/: cada versión publicada en una carpeta nueva e inmutable.
  • shared/: contenido persistente (subidas, caché, etc.) que no debe perderse al cambiar de release.
  • current: enlace simbólico al release activo; el cambio de versión se reduce a actualizar este enlace.

En Apache, el DocumentRoot del Virtual Host puede apuntar a /var/www/misitio/current/public (o la carpeta pública equivalente), de forma que el cambio de release sea atómico (cambio de symlink) y rápido.

Copias de seguridad: qué respaldar y cuándo

Antes de tocar producción, define un mínimo de respaldos:

  • Configuración: /etc/apache2/ (Debian/Ubuntu) o /etc/httpd/ (RHEL/CentOS/Alma/Rocky).
  • Contenido: el release anterior ya actúa como “backup” del código; aun así, respalda shared/ (uploads, assets generados).
  • Certificados/keys (si están en el servidor): rutas de TLS y permisos correctos.
  • Logs: opcional para despliegue, pero útil para auditoría.

Ejemplos de backup rápido (ajusta rutas según tu distro):

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

# Configuración Apache (Debian/Ubuntu) sudo tar -czf /root/backup-apache-$(date +%F).tgz /etc/apache2 # Sitio (solo shared) sudo tar -czf /root/backup-misitio-shared-$(date +%F).tgz /var/www/misitio/shared

Permisos y propiedad: regla práctica para evitar incidentes

En despliegues, muchos problemas vienen de permisos inconsistentes. Reglas prácticas:

  • El proceso de Apache (p. ej. www-data o apache) debe tener lectura del contenido publicado.
  • Evita que el usuario del servidor web tenga permisos de escritura en el código del release; limita escritura a shared/ cuando sea necesario (uploads).
  • El usuario de despliegue (p. ej. deploy) puede ser propietario de releases/ y current, pero mantén un grupo común (p. ej. www-data) para lectura.

Ejemplo orientativo:

# Propietario/grupo sudo chown -R deploy:www-data /var/www/misitio # Directorios: 750, Archivos: 640 (ajusta según necesidad) sudo find /var/www/misitio -type d -exec chmod 750 {} \; sudo find /var/www/misitio -type f -exec chmod 640 {} \; # Si shared/uploads requiere escritura por el servidor web: sudo chown -R deploy:www-data /var/www/misitio/shared/uploads sudo chmod -R 770 /var/www/misitio/shared/uploads

Validación previa: configtest antes de recargar

Antes de aplicar cambios de configuración, valida sintaxis y coherencia. Esto evita caídas por un error tipográfico o una directiva inválida.

  • En Debian/Ubuntu: apache2ctl configtest
  • En RHEL-like: apachectl configtest o httpd -t
sudo apache2ctl configtest

Si el resultado es Syntax OK, recién entonces procede a recargar. Si falla, corrige antes de tocar el servicio.

Cómo evitar caídas: recarga vs reinicio, ventanas y rollback

Recarga (reload) vs reinicio (restart)

Para cambios de configuración y rotación de logs, normalmente conviene recargar en lugar de reiniciar:

  • Reload: Apache re-lee configuración y reabre logs, intentando mantener conexiones activas (graceful). Minimiza impacto.
  • Restart: detiene y arranca el servicio; puede cortar conexiones y aumentar el riesgo de indisponibilidad.

Comandos típicos:

# systemd sudo systemctl reload apache2   # Debian/Ubuntu sudo systemctl reload httpd     # RHEL-like # Alternativa graceful (según empaquetado) sudo apache2ctl graceful

Usa restart solo cuando sea necesario (cambios que requieran reinicio completo o si el reload no aplica correctamente), y preferiblemente dentro de una ventana de mantenimiento.

Ventanas de mantenimiento: cuándo y cómo

Una ventana de mantenimiento no es solo “hacerlo de noche”; es un acuerdo operativo:

  • Define un horario con menor tráfico y comunica el cambio.
  • Prepara el plan de despliegue y el plan de rollback por escrito.
  • Ten a mano comandos de verificación y un punto de control (por ejemplo, “si a los 5 minutos hay errores 5xx, rollback”).

Rollback simple con releases

Si el sitio está publicado con current apuntando a un release, el rollback puede ser tan simple como volver el symlink al release anterior y recargar (si no cambiaste configuración). Ejemplo:

# Ver releases disponibles ls -1 /var/www/misitio/releases # Apuntar a release anterior (ajusta nombre) sudo ln -sfn /var/www/misitio/releases/2026-02-01_0900 /var/www/misitio/current # Verificar permisos rápidos (opcional) sudo -u www-data test -r /var/www/misitio/current/public/index.html # Recargar para asegurar que todo está consistente (si aplica) sudo systemctl reload apache2

Si el despliegue incluyó cambios en configuración de Apache, el rollback debe contemplar revertir también esos archivos (idealmente desde control de versiones o desde el backup de /etc/apache2).

Guía práctica paso a paso: despliegue seguro

Este flujo asume que ya tienes un Virtual Host apuntando a /var/www/misitio/current/public y que publicarás un nuevo release.

1) Preparar el release (sin tocar producción)

  • Copia el nuevo contenido a una carpeta nueva en releases/.
  • Conecta recursos persistentes desde shared/ (symlinks a uploads, etc.).
RELEASE=2026-02-03_1200 sudo mkdir -p /var/www/misitio/releases/$RELEASE sudo rsync -a --delete ./build/ /var/www/misitio/releases/$RELEASE/ # Ejemplo: enlazar uploads persistentes sudo ln -sfn /var/www/misitio/shared/uploads /var/www/misitio/releases/$RELEASE/public/uploads

2) Verificar permisos y lectura por el usuario del servidor web

# Ajusta usuario/grupo según tu sistema (www-data o apache) sudo chown -R deploy:www-data /var/www/misitio/releases/$RELEASE sudo find /var/www/misitio/releases/$RELEASE -type d -exec chmod 750 {} \; sudo find /var/www/misitio/releases/$RELEASE -type f -exec chmod 640 {} \; sudo -u www-data test -r /var/www/misitio/releases/$RELEASE/public/index.html

3) (Si hay cambios de Apache) validar configuración antes de aplicar

Si modificaste archivos de Virtual Hosts, includes o módulos, valida:

sudo apache2ctl configtest

Si falla, no continúes. Corrige y repite el test.

4) Cambiar el symlink current (cambio atómico)

sudo ln -sfn /var/www/misitio/releases/$RELEASE /var/www/misitio/current

5) Recargar Apache (preferible) y verificar

sudo systemctl reload apache2

Verificaciones rápidas:

  • Estado del servicio: systemctl status
  • Respuesta HTTP local: curl -I http://127.0.0.1/ (o al ServerName)
  • Errores recientes: revisar el error log del vhost
systemctl status apache2 --no-pager curl -I http://127.0.0.1/ tail -n 50 /var/log/apache2/error.log

Tareas de higiene operativa

Rotación de logs (logrotate) y recarga

Los logs crecen; si no rotan, llenan disco y provocan fallos. En la mayoría de distros, logrotate ya está configurado para Apache, pero conviene verificar:

  • Que exista una política para access.log y error.log (tamaño/tiempo, compresión, retención).
  • Que tras rotar se haga reload para que Apache reabra archivos.

Comprobación típica:

# Ver configuración de logrotate para Apache (ruta puede variar) ls /etc/logrotate.d/ | grep -i apache cat /etc/logrotate.d/apache2

Prueba controlada (forzar rotación) en ventana de mantenimiento:

sudo logrotate -f /etc/logrotate.d/apache2 sudo systemctl reload apache2

Actualización de paquetes: planificar y validar

Mantener Apache y dependencias al día reduce exposición a vulnerabilidades. Buenas prácticas:

  • Actualiza en un entorno de prueba primero si es posible.
  • Revisa cambios de configuración por actualizaciones (archivos .dpkg-dist, .rpmnew, etc.).
  • Tras actualizar, ejecuta configtest y recarga/reinicia según corresponda.
# Debian/Ubuntu (ejemplo) sudo apt update sudo apt upgrade # Validar y recargar sudo apache2ctl configtest sudo systemctl reload apache2

Revisión de módulos habilitados: menos es más

Con el tiempo se habilitan módulos “por si acaso”. Cada módulo extra aumenta superficie de ataque y complejidad. Programa una revisión periódica:

  • Lista módulos cargados y cuestiona su necesidad real.
  • Deshabilita lo que no uses (siguiendo el método de tu distro).
  • Tras cambios, configtest y reload.
# Ver módulos cargados (general) apache2ctl -M

Auditoría periódica de Virtual Hosts

Con múltiples sitios, es común acumular Virtual Hosts obsoletos, duplicados o con ServerName/ServerAlias inconsistentes. Una auditoría reduce incidentes de enrutamiento y certificados mal aplicados:

  • Lista vhosts efectivos y revisa cuál responde a cada nombre.
  • Confirma que cada vhost tenga el DocumentRoot correcto (apuntando a current si usas releases).
  • Verifica que no existan vhosts “catch-all” no deseados.
apache2ctl -S

Si detectas un vhost antiguo, retíralo de forma controlada: primero deshabilitar, luego recargar, y finalmente eliminar el archivo cuando confirmes que no se usa.

Checklist de publicación profesional

Usa esta lista como verificación rápida antes y después del despliegue.

DNS / hosts

  • El dominio apunta a la IP correcta (A/AAAA) y, si aplica, www y subdominios.
  • TTL razonable para cambios planificados.
  • En pruebas internas, /etc/hosts solo temporalmente y documentado.

Virtual Host

  • ServerName y ServerAlias correctos.
  • DocumentRoot apunta a /var/www/.../current/... (si usas releases).
  • No hay vhosts duplicados compitiendo por el mismo nombre.
  • apache2ctl -S muestra el mapeo esperado.

HTTPS

  • Certificado válido para el/los nombres (incluye SAN necesarios).
  • Redirecciones HTTP→HTTPS correctas donde corresponda.
  • Cadena de certificados completa (si aplica) y archivos con permisos adecuados.

Permisos

  • Apache puede leer el contenido del release activo.
  • Solo shared/ tiene escritura si es imprescindible (uploads).
  • No hay secretos expuestos en el DocumentRoot (archivos de despliegue, backups, etc.).

Logs

  • Access/error logs del vhost escriben correctamente tras el despliegue.
  • Logrotate configurado y probado; no hay crecimiento descontrolado.
  • Revisar error log tras publicar para detectar warnings/errores nuevos.

Pruebas finales

  • apache2ctl configtest antes de recargar si hubo cambios de configuración.
  • curl -I a HTTP/HTTPS y a rutas críticas (home, login, assets).
  • Comprobar códigos 200/301 esperados y ausencia de 500/503.
  • Validar que el rollback es posible (release anterior disponible y accesible).

Ahora responde el ejercicio sobre el contenido:

En un despliegue con estructura de releases y un enlace simbólico "current", ¿qué acción permite cambiar de versión de forma atómica y facilita un rollback rápido sin modificar la configuración del Virtual Host?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

Al apuntar el DocumentRoot a current, cambiar de versión se reduce a actualizar ese enlace simbólico. Esto hace el cambio rápido y atómico, y el rollback consiste en volver el symlink al release anterior (y recargar si aplica).

Portada de libro electrónico gratuitaApache desde Cero: Guía Práctica para Principiantes
100%

Apache desde Cero: Guía Práctica para Principiantes

Nuevo curso

10 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.