Adios Traefik me paso a Caddy proxy

Después de tener algun problema con las ultimas actualizaciones de Traefik me decidí a pasar el proxy inverso a Caddy , para ello lo primero será agregarlo en nuestro dockercompose

  caddy:
    container_name: caddy
    image: caddy:2.6.4-alpine
    domainname: xxxxxx.duckdns.org
    restart: always
    networks:
      - traefik  
      - default
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "2019:2019"
    volumes:
      - ${DOCKERDIR}/caddy/Caddyfile:/etc/caddy/Caddyfile
      - ${DOCKERDIR}/caddy/data:/data
      - ${DOCKERDIR}/caddy/config:/config
      - ${DOCKERDIR}/caddy/log:/var/log/
      - ${DOCKERDIR}/wordpress/data/html:/var/www/html
    environment:
      - TZ=${TZ}      
      - DUCKDNS_TOKEN=${DUCKDNS_TOKEN}
      - CF_API_EMAIL=${CLOUDFARE_EMAIL}                 
      - CF_DNS_API_TOKEN=${CLOUDFARE_DNS_API_TOKEN}      
    logging:
        driver: "json-file"
        options:
            max-file: "10"
            max-size: "200k"

Usaremos la versión alpine mas ligera y con menor tamaño , esta linea es totalmente opcional , pero luego veremos que puede ser necesaria en caso de contener paginas con iframe

- ${DOCKERDIR}/wordpress/data/html:/var/www/html

Indicaremos la ubicación de nuestro fichero Caddyfile que será el fichero de configuración de todo el tinglado

 - ${DOCKERDIR}/caddy/Caddyfile:/etc/caddy/Caddyfile

Una vez levantado el docker empezaremos a darle funcionalidades a nuestro Caddy

La primera parte es la sección global , donde de momento indicaremos nuestro email y si por el puerto 2019 se podrá acceder a la API de Caddy

{
    # Configuración global para todos los sitios
    email xxxxxx.yyyyyy@gmail.com
    #Activar dashboard
    admin :2019
}

Pasaremos a las secciones de configuración de los subdominios , en este caso podemos poner uno o varios subdominios separados por un espacio , Caddy se encargara si todo es correcto de obtener y crear los certificados digitales de cada uno de ellos.

En este ejemplo al ser una pagina que quiero que este protegida con usuario y contraseña al acceder desde el exterior usaremos el middleware basicauth que nos permite evitar el acceso a un servicio si no te has autenticado correctamente

El siguiente bloque define como se van a procesar los logs de Caddy y sus parámetros de configuración

############################################################
subdominio1.xxxxxxxxxxxx.duckdns.org subdominio2.xxxxxxxxxxxx.duckdns.org {
    basicauth {
        usuario1 $2y$10$3BSnrRuD9c.O9erererereej6NqipuLYVxI7g6GpSubk9pNDIjXDVa
        usuario2 $2y$10$MAreregdojC.Lyy8ShgdgdjFL8egdgd9JylMLG9JbwxS/j6ULAy
    }    
	reverse_proxy http://192.168.1.20:480
	log {
		output file /var/log/caddy/subdominio1.xxxxxxxxxxxx.duckdns.org.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
}        
############################################################
subdominio1.rivas.cloud subdominio2.rivas.cloud {
    basicauth {
        usuario1 $2y$10$3BSnrRuD9c.O9erererereej6NqipuLYVxI7g6GpSubk9pNDIjXDVa
        usuario2 $2y$10$MAreregdojC.Lyy8ShgdgdjFL8egdgd9JylMLG9JbwxS/j6ULAy
    }    
	reverse_proxy http://192.168.1.20:480
	log {
		output file /var/log/caddy/subdominio1.rivas.cloud.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
}  

Tengo una serie de paginas con datos meteorológicos dentro del servidor web a las que se accede con un path , para que no aparezca el path en el navegador y solo aparezca el subdominio lo resolví modificando la ruta y luego llamando a servicio web , de esta forma el visitante no vera el path de la pagina

############################################################
meteo-xxxxx.antrivas.duckdns.org {
	handle * {
		rewrite * /xxxxx{uri}
		reverse_proxy http://192.168.1.20:9080
	}
	log {
		output file /var/log/caddy/meteo-xxxxx.antrivas.duckdns.org.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
}

Esta seria la forma de hacer una redirección de www a non www totalmente transparente

#Redireccion www a non www
www.rivas.cloud {
	redir https://rivas.cloud{uri}
}

Y después llamar a WordPress , así tanto www como no www llamaran a WordPress

############################################################
rivas.cloud {
	reverse_proxy http://rivas.cloud
	log {
		output file /var/log/caddy/global.rivas.cloud.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
}

En el dominio duckdns preferia enviar al visitante a una pagina en construcción , aplicamos la misma técnica anterior y modificamos la url para que sea transparente y apunte a la pagina de “en construcción”

############################################################
# Redireccion a pagina en construccion
xxxxxxxx.duckdns.org {
	handle * {
		rewrite * /contruccion/index.php{uri}
		reverse_proxy http://rivas.cloud
	}
	log {
		output file /var/log/caddy/xxxxxxxx.duckdns.org.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}    
}

Después de todo ello me encontre que Grafana me estaba dando problemas al visualizar los dashboards , con el error este tan místico que puede ser casi cualquier cosa , ¡¡¡ gracias Grafana por dar tantas pistas !!!

Para ver de donde viene el error ahora nos vendrá muy bien esta linea del dockercompose

- ${DOCKERDIR}/wordpress/data/html:/var/www/html

Crearemos una pagina en ese directorio llamada aire.html con este contenido , donde pondremos el iframe a pantalla completa

<!doctype html>
<html lang=''>
<head>
   <meta charset='utf-8'>
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="stylesheet" href="CSS/styles.css">

   <style>
   #contenedor {
  width: 700px;
}
#cabecera {
}
#menu {
  float: left;
  width: 225px;
}
#contenido {
  float: left;
  width: 470px;
}
#pie {
  clear: both;
}
**// prueba
.contenedor-responsive {
  position: relative;
  padding-bottom: 56.25%;
  padding-top: 30px;
  height: 0;
  overflow: hidden;
}
.contenedor-responsive iframe,
.contenedor-responsive object,
.contenedor-responsive embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

</style>

</head>
<body>

<div id="contenedor">
  <div id="cabecera">
  </div>
 
  <div id="menu">
  <div id='cssmenu'>
</div>
  

  </div>
 
  <div id="contenido" class="contenedor-responsive">
<iframe frameborder="0" allowfullscreen="" src="http://xxxxxxxxx.rivas.cloud/d/7zvlpJD4z/contaminacion?orgId=1&theme=dark&kiosk" width="100px" height="600px" id="theIframe" name="pagina" >El navegador no soporta iframes</iframe>
  </div>
 
  <div id="pie">
  </div>
</div>


</body>
</html>

La probamos para ver que funciona correctamente y vemos el dashboard de Grafana alojado en nuestro servidor

Una vez comprobado vamos a hacer que sea Caddy quien nos sirva el HTML de forma directa sin acceder a ninguna pagina , para ello lo primero será bajarle el tamaño , podemos usar una herramienta del estilo https://www.willpeavy.com/tools/minifier/ para ello , una vez obtenido el código reducido cambiaremos la comillas dobles por comillas sencillas.

Y el código para este subdominio quedaria mas o menos así , en el indicamos el tipo de respuesta y el contenido de la respuesta que es nuestro HTML pero de forma embebida.

############################################################
# Redireccion a pagina 
yyyyyyyyyy.rivas.cloud {
	handle * {
        header Content-Type text/html
        respond "<!doctype html><html lang=''><head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <meta name='viewport' content='width=device-width, initial-scale=1'> <link rel='stylesheet' href='CSS/styles.css'> <style>#contenedor{width: 700px;}#cabecera{}#menu{float: left; width: 225px;}#contenido{float: left; width: 470px;}#pie{clear: both;}**// prueba.contenedor-responsive{position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden;}.contenedor-responsive iframe,.contenedor-responsive object,.contenedor-responsive embed{position: absolute; top: 0; left: 0; width: 100%; height: 100%;}</style></head><body><div id='contenedor'> <div id='cabecera'> </div><div id='menu'> <div id='cssmenu'></div></div><div id='contenido' class='contenedor-responsive'><iframe frameborder='0' allowfullscreen='' src='https://xxxxxxxxxx.rivas.cloud/d/7zvlpJD4z/contaminacion?orgId=1&theme=dark&kiosk' width='100px' height='600px' id='theIframe' name='pagina' >El navegador no soporta iframes</iframe> </div><div id='pie'> </div></div></body></html>"
        
    }    
	log {
		output file /var/log/caddy/aire.rivas.cloud.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
} 

Y probarlo se hizo la magia ……

La otra forma de hacer lo mismo pero con ficheros locales seria la siguiente

Añadiremos en nuestro directorio HTML un directorio con su pagina index.html con el código anterior

Añadiremos el path y llamaremos a WordPress , quedando de esta manera

############################################################
# Redireccion a pagina 
xxxxxxxx.rivas.cloud {
    # Añadir '/aire'
	handle * {
		rewrite * /aire{uri}
        reverse_proxy http://rivas.cloud {
        }
	}
	log {
		output file /var/log/caddy/xxxxxxxxxxxx.rivas.cloud.access.log {
			roll_size 10mb
			roll_keep 20
			roll_keep_for 720h
			}
		}
} 

Y veremos que al igual que en el caso anterior nuestra pagina con iframe es mostrada correctamente

Y con esto y un bizcocho