--- title: "Cómo instalar Caddy en Ubuntu 24.04 con HTTPS automático" description: "Instala Caddy desde su repositorio oficial en Ubuntu 24.04, sirve un sitio estático con HTTPS automático y configúralo como proxy inverso con un Caddyfile." category: "Proxy y Equilibrio de Carga" language: es source: https://cubepath.com/es/docs/proxy-y-equilibrio-de-carga/instalacion-y-configuracion-del-servidor-web-caddy updated: 2026-09-25 --- # Cómo instalar Caddy en Ubuntu 24.04 con HTTPS automático Caddy es un servidor web y proxy inverso escrito en Go que obtiene y renueva certificados TLS de Let's Encrypt o ZeroSSL de forma automática, sin Certbot ni tareas programadas. Su archivo de configuración, el Caddyfile, es mucho más corto que el equivalente en Nginx o Apache. En este tutorial instalarás Caddy desde su repositorio oficial en Ubuntu 24.04, publicarás un sitio estático con HTTPS y lo configurarás como proxy inverso para una aplicación que corre en el mismo servidor. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Un dominio con registros DNS de tipo A (y AAAA si usas IPv6) para `your_domain` y `www.your_domain` apuntando a la IP del servidor. Para el paso 6 necesitarás además `app.your_domain`. - Los puertos 80 y 443 libres: si tienes Nginx o Apache instalados, detenlos antes de empezar. A lo largo de la guía sustituye **`your_domain`** por tu dominio. ## Paso 1: Instalar Caddy desde el repositorio oficial El paquete `caddy` de los repositorios de Ubuntu va varias versiones por detrás. Usa el repositorio oficial del proyecto, alojado en Cloudsmith. Instala las dependencias y descarga la clave de firma: ```bash sudo apt update sudo apt install debian-keyring debian-archive-keyring apt-transport-https curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg ``` Añade el repositorio. El archivo que proporciona Caddy ya apunta a la clave que acabas de guardar mediante `signed-by`: ```bash curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg /etc/apt/sources.list.d/caddy-stable.list ``` Instala Caddy: ```bash sudo apt update sudo apt install caddy ``` El paquete crea el usuario `caddy`, la configuración en `/etc/caddy/Caddyfile` y un servicio de systemd que arranca automáticamente. Compruébalo: ```bash caddy version systemctl status caddy --no-pager ``` ```output v2.11.4 h1:... ● caddy.service - Caddy Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-25 10:15:02 UTC; 20s ago ``` ## Paso 2: Abrir los puertos en el firewall Caddy necesita el puerto 80 para el reto HTTP de Let's Encrypt y para redirigir a HTTPS, y el 443 para servir el tráfico cifrado. Abre también `443/udp` para HTTP/3, que Caddy activa por defecto: ```bash sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw allow 443/udp sudo ufw status ``` ```output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere 443/udp ALLOW Anywhere ``` Si visitas `http://your_server_ip` en el navegador verás la página de bienvenida de Caddy, que sirve la configuración por defecto. ## Paso 3: Crear el contenido del sitio Crea el directorio del sitio y una página de prueba: ```bash sudo mkdir -p /var/www/your_domain echo '

Hola desde Caddy

' | sudo tee /var/www/your_domain/index.html ``` Caddy se ejecuta como el usuario `caddy`, que solo necesita permiso de lectura. Los permisos por defecto (`755` para directorios y `644` para archivos) son suficientes; no hace falta cambiar el propietario. ## Paso 4: Configurar el sitio con HTTPS automático Sustituye la configuración por defecto. Haz antes una copia por si quieres consultarla: ```bash sudo cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.orig sudo nano /etc/caddy/Caddyfile ``` ```caddy { email admin@your_domain } your_domain { root * /var/www/your_domain encode zstd gzip file_server header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" Referrer-Policy "strict-origin-when-cross-origin" -Server } log { output file /var/log/caddy/your_domain.log } } www.your_domain { redir https://your_domain{uri} permanent } ``` Qué hace cada parte: - El bloque global inicial (`{ email ... }`) indica el correo de contacto para la autoridad de certificación, que lo usa para avisos importantes. - `your_domain { ... }`: al usar un nombre de dominio como dirección del sitio, Caddy obtiene el certificado, lo renueva y redirige HTTP a HTTPS sin más configuración. - `root` y `file_server` sirven los archivos del directorio; `encode` comprime las respuestas con zstd o gzip. - `header` añade cabeceras de seguridad y `-Server` elimina la que identifica al servidor. - `log` escribe el log de acceso en JSON en `/var/log/caddy/`, directorio que crea el paquete. Caddy rota el archivo automáticamente. - El bloque `www.your_domain` también recibe su certificado y redirige a la versión sin `www`. Formatea el archivo con el estilo estándar y valida la configuración antes de aplicarla: ```bash sudo caddy fmt --overwrite /etc/caddy/Caddyfile caddy validate --config /etc/caddy/Caddyfile ``` ```output Valid configuration ``` Recarga Caddy. `reload` aplica la configuración nueva sin cortar las conexiones abiertas y, si tuviera errores, mantiene la anterior: ```bash sudo systemctl reload caddy ``` ## Paso 5: Verificar HTTPS Caddy solicita los certificados en cuanto carga la configuración. Sigue el proceso en el journal: ```bash sudo journalctl -u caddy -f ``` Cuando aparezca un mensaje `certificate obtained successfully` para cada dominio, pulsa `Ctrl+C` y comprueba el sitio: ```bash curl -I http://your_domain curl -sI https://your_domain curl -sI https://www.your_domain | grep -i location ``` ```output HTTP/1.1 308 Permanent Redirect Location: https://your_domain/ HTTP/2 200 alt-svc: h3=":443"; ma=2592000 content-type: text/html; charset=utf-8 strict-transport-security: max-age=31536000; includeSubDomains x-content-type-options: nosniff location: https://your_domain/ ``` La cabecera `alt-svc` anuncia HTTP/3 a los navegadores. Los certificados se guardan en `/var/lib/caddy/.local/share/caddy/` y Caddy los renueva solo, aproximadamente un tercio antes de que caduquen. ## Paso 6: Configurar Caddy como proxy inverso El uso más habitual de Caddy es publicar con HTTPS una aplicación que escucha en local, por ejemplo una aplicación Node.js en el puerto 3000. Para probarlo sin tener una, arranca un servidor de prueba en una segunda terminal: ```bash mkdir -p ~/app && echo "Respuesta del backend" > ~/app/index.html python3 -m http.server 3000 --bind 127.0.0.1 --directory ~/app ``` Añade un sitio nuevo al final del Caddyfile: ```bash sudo nano /etc/caddy/Caddyfile ``` ```caddy app.your_domain { reverse_proxy 127.0.0.1:3000 } ``` `reverse_proxy` reenvía las peticiones al backend y añade por defecto las cabeceras `X-Forwarded-For`, `X-Forwarded-Proto` y `X-Forwarded-Host`, para que la aplicación conozca la IP del cliente y el esquema original. También gestiona WebSockets sin configuración adicional. Valida y recarga: ```bash caddy validate --config /etc/caddy/Caddyfile sudo systemctl reload caddy curl https://app.your_domain ``` ```output Respuesta del backend ``` ### Enrutar por ruta dentro del mismo dominio Si la aplicación y el sitio estático comparten dominio (por ejemplo, la API en `/api/`), usa bloques `handle`. Caddy evalúa los `handle` en orden y ejecuta solo el primero que coincide. Este bloque sustituiría al de `your_domain` del paso 4: ```caddy your_domain { encode zstd gzip handle /api/* { reverse_proxy 127.0.0.1:3000 } handle { root * /var/www/your_domain file_server } } ``` Si el backend espera las rutas sin el prefijo `/api`, usa `handle_path /api/*` en lugar de `handle /api/*`: elimina el prefijo antes de reenviar la petición. ### Repartir carga entre varios backends Con varias instancias de la aplicación, lista todas en `reverse_proxy` y activa las comprobaciones de salud activas para que Caddy deje de enviar tráfico a las que no respondan: ```caddy app.your_domain { reverse_proxy 127.0.0.1:3001 127.0.0.1:3002 { lb_policy round_robin health_uri /health health_interval 10s } } ``` La aplicación debe responder con un código 2xx en `/health`. Ajusta la ruta a la que exponga tu aplicación. ## Solución de problemas - **`could not get certificate from issuer` o errores de reto en el journal**: la autoridad de certificación no llega a tu servidor. Comprueba con `dig +short your_domain` que el DNS apunta a la IP correcta y que los puertos 80 y 443 están abiertos en UFW y en el firewall del proveedor. - **`bind: address already in use` al arrancar**: otro servidor web ocupa el puerto 80 o 443. Identifícalo con `sudo ss -tlnp | grep -E ':80|:443'` y detenlo, por ejemplo con `sudo systemctl disable --now nginx`. - **Los cambios del Caddyfile no se aplican**: `systemctl reload` conserva la configuración anterior si la nueva tiene errores. Ejecuta `caddy validate --config /etc/caddy/Caddyfile` y revisa `sudo journalctl -u caddy -n 50`. - **`403 Forbidden` o `404` en el sitio estático**: comprueba que la ruta de `root` es correcta y que el usuario `caddy` puede leerla con `sudo -u caddy ls /var/www/your_domain`. - **502 Bad Gateway en el proxy inverso**: el backend no responde. Verifica que escucha en la dirección configurada con `curl http://127.0.0.1:3000`. ## Conclusión Tienes Caddy instalado desde el repositorio oficial, sirviendo un sitio estático con HTTPS automático, redirección de `www`, cabeceras de seguridad y compresión, y publicando una aplicación local como proxy inverso. Como siguientes pasos, puedes servir aplicaciones PHP con la directiva `php_fastcgi` y PHP-FPM, organizar cada sitio en su propio archivo con la directiva `import`, o proteger zonas privadas con `basic_auth`.