---
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`.