Mi instalación de lighttpd

Hace bastante tiempo conocí un servidor web muy ligero, con gran aceptación y muy bien documentado, llamado lighttpd. En su página web indican que servicios como imageshack, youtube, myspace o tuenti, por citar algunos, utilizan lighttpd de una u otra manera. Así que algo debe tener, ¿no?

La instalación que tengo hecha cumple los siguientes requisitos:

  1. Permite alojar varias webs (hosts virtuales).
  2. Tiene un host virtual para https.
  3. Soporta PHP mediante fastcgi
  4. Genera logs de cada host virtual por día (mediante cronolog).
  5. El proceso se mantiene vivo mediante las utilidades daemontools.

Para poder llevar a cabo esta instalación supondremos que cronolog y las daemontools ya están instalados. Estas últimas se encargarán de mantener ejecutándose el proceso, informando de posibles errores y dándonos una serie de opciones (detención, rearranque, etc) sobre el mismo. Para más información, consulta su documentación.

Preparación de lighttpd para daemontools

La estructura de un servicio en daemontools es muy simple: basta un directorio que contenga otro directorio log/, y dentro de cada uno de estos directorios es necesario colocar un script run.

Para lighttpd crearemos además un directorio root/, en el que colocaremos el fichero lighttpd.conf. Creamos todo esto en cualquier ruta, por ejemplo en /root/ :

# mkdir -p /root/lighttpd/{log,root}
# cd /root/lighttpd

El fichero lighttpd/run debe contener lo siguiente:

#!/bin/sh

exec 2>&1
exec lighttpd -D -f ./root/lighttpd.conf

Y el fichero lighttpd/log/run:

#!/bin/sh

umask 0027
exec setuidgid nobody multilog ./main

Y por supuesto, deben tener permisos de ejecución:

# chmod 755 run log/run

Escritura de lighttpd.conf

Quizás ésta sea la parte más compleja. Hasta que conseguí que lighttpd se comportara como yo quería, estuve bastante tiempo probando configuraciones. La configuración de PHP ejecutándose como fastcgi está muy bien documentada, en mi opinión la parte más complicada es definir los hosts virtuales, entre ellos el que soportará https.

La sintaxis de lighttpd permite usar condicionales en la configuración. Yo no he usado ninguno de los módulos destinados a hosts virtuales, como pueden ser mod_simple_vhost o mod_evhost. El motivo es que de esa forma estaba bastante limitado a la hora de almacenar los logs y que la configuración para usar SSL se me antojaba bastante más complicada.

La estructura de condicionales para que todo funcione bien es la siguiente:

$SERVER["socket"] == ":80" {
$HTTP["host"] == "dominio1.tld" {
  server.document-root = "/var/www/dominio1/htdocs"
  accesslog.filename = "|/usr/bin/cronolog /var/www/dominio1/logs/access_%Y%m%d.log"
}
$HTTP["host"] == "sub.dominio2.tld" {
  server.document-root = "/var/www/sub-dominio2/htdocs"
  accesslog.filename = "|/usr/bin/cronolog /var/www/sub-dominio2/logs/access_%Y%m%d.log"
}
# Más dominios virtuales
}
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "./root/ssl/lighttpd.pem"
server.document-root        = "/var/www/https"
accesslog.filename = "|/usr/bin/cronolog /var/www/https/logs/access_%Y%m%d.log"
}

Me gustaría hacer varias observaciones:

  • Por cada host virtual crearemos un bloque de los que aparecen dentro del primer condicional. Tengo la costumbre de crear un directorio por cada dominio, y dentro de él colocar dos subdirectorios: htdocs/ y logs/, de esa manera lo tengo todo bien organizado.
  • Mediante la opción accesslog.filename se usa cronolog, que acepta una expresión con formateadores como %Y%m%d, que serán traducidos por el año, mes y día respectivamente. Los directorios de logs tendrán esta pinta:
    # ls logs/
    [...]
    access_20071229.log  access_20080212.log  access_20080328.log
    access_20071230.log  access_20080213.log  access_20080329.log
    access_20071231.log  access_20080214.log  access_20080330.log
    access_20080101.log  access_20080215.log  access_20080331.log
    access_20080102.log  access_20080216.log  access_20080401.log
  • Hay que tener un certificado válido en el subdirectorio root/ssl/

Dejando a un lado los hosts virtuales, es aconsejable que el PID de lighttpd se almacene dentro de root/ con la opción:

server.pid-file            = "./root/lighttpd.pid"

Arrancando lighttpd

Para arrancar lighttpd sólo hace falta enlazar en el directorio /service (o donde estén ejecutándose las daemontools, suele ser éste) el directorio /root/lighttpd que creamos al principio:

# ln -sf /root/lighttpd /service

Para saber si todo va bien, basta con esperar unos segundos y ejecutar:

# svstat /service/lighttpd
/service/lighttpd: up (pid 11290) 8 seconds

Si por algún motivo no aparece como arrancado, o el PID va variando entre llamadas a svstat y los tiempos son bajos, algo está fallando y debemos consultar el fichero /service/lighttpd/log/main/current.

Consiguiendo que los hosts virtuales permitan www.dominio.tld y dominio.tld

¿Qué pasa si queremos que el host virtual sea el mismo para www.dominio.tld y para dominio.tld? Es muy fácil de conseguir, sólo hay que cambiar el condicional para ese host virtual. Inicialmente es:

$HTTP["host"] == "dominio1.tld" {
# ...

Y sólo hace falta cambiarlo por:

  $HTTP["host"] =~ "(www\.)?dominio1.tld" {
# ...

Actualización [8/abr/08]: La expresión regular de arriba puede dar problemas si tenemos algún subdominio más bajo dominio1.tld. Es más certera la siguiente: "^(www\.)?dominio1.tld$".

Posteriormente, reiniciamos el servicio mediante svc -dx /service/lighttpd, y tras unos segundos podremos comprobar que ha vuelto a arrancar.

Clasificado como

Comentarios

Enviar un comentario nuevo

  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Saltos automáticos de líneas y de párrafos.
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <p>

Más información sobre opciones de formato

CAPTCHA
Esta pregunta sirve para evitar envíos automatizados y SPAM
3 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.