Guía de despliegue

Caddy como reverse proxy en VPS: guía completa

Desplegar en un VPS Cloud →

Tutorial

Caddy como reverse proxy en VPS: guía completa

Despliegue8 min de lectura7 pasos

Caddy es un servidor web escrito en Go que gestiona todo el ciclo TLS — negociación ACME, renovación, redirección HTTP → HTTPS — sin ninguna configuración adicional. Donde Nginx necesita Certbot, un cron y un vhost por dominio, un único `Caddyfile` de diez líneas basta para exponer varias aplicaciones en el mismo VPS sobre HTTPS. Esta guía cubre la instalación, la configuración multi-aplicación, el hardening y los errores más frecuentes.

Contenido· ¿Por qué elegir Caddy como reverse proxy en tu VPS?1/9
  1. 01¿Por qué elegir Caddy como reverse proxy en tu VPS?
  2. 02Lo que Caddy aporta en producción
  3. 03Requisitos previos
  4. 04Desplegar Caddy como reverse proxy
  5. 05Cómo funciona el HTTPS automático de Caddy
  6. 06Caddy vs Nginx: cuándo elegir uno u otro
  7. 07Solución de problemas: errores comunes
  8. 08Para alojar múltiples aplicaciones en el mismo VPS
  9. 09Documentación oficial

¿Por qué elegir Caddy como reverse proxy en tu VPS?

La mayoría de los reverse proxies delegan la gestión TLS a una herramienta externa — Certbot, acme.sh o un script cron propio. Caddy integra este mecanismo de extremo a extremo: en cuanto se declara un nombre de dominio en el Caddyfile, contacta con Let's Encrypt, obtiene el certificado y lo renueva antes de que caduque, sin intervención manual. El resultado es una configuración que se lee en pocas líneas y se despliega de forma idéntica en todos tus VPS, sin estado externo que sincronizar.

Lo que Caddy aporta en producción

  • HTTPS automático: Let's Encrypt ACME HTTP-01 activado en cuanto se declara un nombre de dominio — sin cron, sin plugin que instalar
  • Sintaxis concisa: un bloque de cinco líneas reemplaza un vhost de Nginx de cuarenta líneas con su archivo de configuración de Certbot
  • Recarga sin corte: caddy reload aplica el nuevo Caddyfile sin interrumpir las conexiones en curso
  • HTTP/2 y HTTP/3 (QUIC) por defecto: activados sin configuración adicional en todas las versiones 2.x
  • JSON API: la configuración puede modificarse en caliente vía REST API, útil para entornos dinámicos o en contenedores
  • Imagen Docker oficial ligera: caddy:2-alpine pesa menos de 20 MB y cubre la mayoría de los casos de producción

Requisitos previos

Antes de empezar, verifica que tu VPS cumple los siguientes requisitos.

Recursos mínimos: 512 MB de RAM y 1 vCPU son suficientes para Caddy solo. Cuenta con 1 GB de RAM y 2 vCPU si alojas varias aplicaciones detrás.

Puertos 80 y 443 libres: Caddy los ocupa para ACME HTTP-01 (puerto 80) y para el tráfico HTTPS (puerto 443). Comprueba que ningún otro proceso los esté usando:

ss -tlnp | grep -E ':80|:443'

Nombre de dominio apuntando al VPS: Let's Encrypt valida la propiedad del dominio consultando el puerto 80 de tu IP. Tu registro DNS A debe estar activo y propagado antes de arrancar Caddy.

Sistema operativo: Debian 11/12 o Ubuntu 22.04/24.04. Los comandos de esta guía están probados en estas distribuciones.

Docker (opcional): si despliegas Caddy en un contenedor, se necesitan Docker Engine 24+ y Docker Compose v2.

Desplegar Caddy como reverse proxy

  1. Método 1 — Instalación desde el repositorio APT oficial

    Caddy ofrece un repositorio APT firmado. Añádelo e instala el paquete:

    apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
      | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
      | tee /etc/apt/sources.list.d/caddy-stable.list
    apt update && apt install caddy

    Verifica la versión instalada: caddy version debe mostrar v2.9.x o superior.

  2. Método 2 — Despliegue con Docker Compose

    Si tus aplicaciones ya corren con Docker, añadir un servicio Caddy al mismo compose.yml es el enfoque más sencillo. Crea un archivo compose.yml en la raíz de tu proyecto:

    services:
      caddy:
        image: caddy:2-alpine
        restart: unless-stopped
        ports:
          - "80:80"
          - "443:443"
          - "443:443/udp"
        volumes:
          - ./Caddyfile:/etc/caddy/Caddyfile
          - caddy_data:/data
          - caddy_config:/config
        networks:
          - proxy
    
    volumes:
      caddy_data:
      caddy_config:
    
    networks:
      proxy:
        external: true

    Crea la red compartida una sola vez: docker network create proxy. Tus otros servicios se unen a esta red para ser accesibles por Caddy.

  3. Crear el Caddyfile básico

    El Caddyfile es el archivo de configuración central. Para una instalación APT se encuentra en /etc/caddy/Caddyfile. Para Docker, colócalo junto a tu compose.yml.

    Ejemplo mínimo que expone una aplicación en el puerto 3000:

    myapp.com {
        reverse_proxy localhost:3000
    }

    Eso es todo. Caddy detecta que myapp.com es un nombre de dominio, contacta con Let's Encrypt vía ACME HTTP-01, obtiene un certificado y redirige automáticamente todo el tráfico HTTP a HTTPS. Los certificados se almacenan en ~/.local/share/caddy/ (APT) o en el volumen caddy_data (Docker).

  4. Configuración multi-aplicación (multi-vhost)

    Alojar varias aplicaciones en el mismo VPS solo requiere bloques adicionales en el mismo archivo:

    app1.tudominio.com {
        reverse_proxy localhost:3000
    }
    
    app2.tudominio.com {
        reverse_proxy localhost:4000
    }
    
    blog.tudominio.com {
        reverse_proxy localhost:8080
    }

    Cada bloque obtiene su propio certificado de Let's Encrypt. Caddy gestiona las renovaciones de forma independiente para cada dominio, en paralelo, sin interrupción de servicio.

  5. Aplicar el Caddyfile sin interrupción

    Para APT, recarga la configuración sin cortar conexiones:

    systemctl reload caddy
    # o si modificaste el archivo fuera de /etc/caddy/:
    caddy reload --config /ruta/al/Caddyfile

    Para Docker:

    docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile

    Verifica que la sintaxis es correcta antes de recargar: caddy validate --config /etc/caddy/Caddyfile.

  6. Añadir cabeceras de seguridad y rate limiting

    Caddy soporta cabeceras de seguridad nativas mediante la directiva header. Aquí hay un bloque reforzado para una aplicación en producción:

    myapp.com {
        reverse_proxy localhost:3000
    
        header {
            Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
            X-Content-Type-Options "nosniff"
            X-Frame-Options "SAMEORIGIN"
            Referrer-Policy "strict-origin-when-cross-origin"
            -Server
        }
    
        log {
            output file /var/log/caddy/myapp.log {
                roll_size 10mb
                roll_keep 5
            }
        }
    }

    Para el rate limiting, el módulo caddy-ratelimit se instala con xcaddy build y se usa con la directiva rate_limit. La imagen oficial de Docker no lo incluye — construye tu propia imagen o usa un firewall de aplicaciones en capa superior si la necesidad es crítica.

  7. Activar y verificar el servicio systemd (APT)

    Tras la instalación con APT, el servicio se activa automáticamente. Controla su estado y los registros:

    systemctl status caddy
    journalctl -u caddy -f

    Para que Caddy arranque en cada reinicio: systemctl enable caddy (ya hecho por el paquete). Comprueba que el certificado de Let's Encrypt se emitió correctamente:

    curl -sv https://myapp.com 2>&1 | grep -E 'subject|issuer|expire'

Cómo funciona el HTTPS automático de Caddy

Caddy implementa el protocolo ACME (Automated Certificate Management Environment) de forma nativa. En cuanto un bloque del Caddyfile contiene un nombre de dominio cualificado, Caddy activa automáticamente el desafío ACME HTTP-01: Let's Encrypt coloca un token de verificación en http://tudominio.com/.well-known/acme-challenge/, Caddy responde a esa petición y demuestra así que controla el servidor. Let's Encrypt emite entonces un certificado válido por 90 días.

Caddy renueva este certificado por adelantado (a partir de 30 días antes de su caducidad) y recarga la configuración en caliente, sin interrupción de servicio. Los certificados y los datos ACME se conservan localmente — en ~/.local/share/caddy/ para una instalación APT, en el volumen caddy_data para Docker. No elimines este volumen: Caddy también almacena ahí el estado ACME, y demasiadas peticiones a Let's Encrypt activan límites de velocidad que pueden bloquear la emisión de nuevos certificados durante varias horas.

Para certificados wildcard (*.tudominio.com), ACME HTTP-01 no funciona: se requiere el desafío DNS-01, que necesita acceso a la API de tu proveedor DNS. Caddy soporta nativamente varios proveedores mediante módulos (caddy-dns/cloudflare, caddy-dns/ovh…) compilados con xcaddy.

Caddy vs Nginx: cuándo elegir uno u otro

Desplace la tabla

CriterioCaddyNginx
Configuración TLSAutomática, cero configuración manualManual (Certbot o acme.sh requeridos)
Curva de aprendizajeBaja — sintaxis legible, pocas directivasModerada — sintaxis verbosa, muchos contextos
Rendimiento bruto (req/s)Excelente para la mayoría de cargasLigeramente superior bajo carga muy alta
Módulos y ecosistemaCreciente, xcaddy para compilar módulosMuy amplio, numerosos módulos de terceros maduros
Recarga sin interrupciónNativo (`caddy reload`)Nativo (`nginx -s reload`), similar
Caso de uso idealVPS personal, proyectos de equipo, microservicios DockerGrandes plataformas, frontal CDN, casos avanzados (GeoIP, Lua…)
Soporte HTTP/3 (QUIC)Activado por defecto desde Caddy 2.6Experimental, requiere compilación con quiche o ngx_http_v3

Solución de problemas: errores comunes

Puerto 80 ya en uso. Caddy necesita el puerto 80 para ACME HTTP-01. Si Apache o Nginx ya están corriendo, detenerlos antes de arrancar Caddy: systemctl stop apache2 o systemctl stop nginx. Verifica después con ss -tlnp | grep :80.

Fallo ACME / certificado no emitido. Let's Encrypt no puede contactar con tu servidor. Comprueba: (1) tu registro DNS A apunta a la IP del VPS — dig +short tu-dominio.com debe devolver tu IP; (2) el puerto 80 es accesible desde el exterior — los firewalls del VPS (iptables, ufw) a veces bloquean este puerto aunque Caddy lo esté escuchando. Consulta los logs de Caddy con journalctl -u caddy para leer el mensaje de error ACME preciso.

permission denied en los puertos 80/443. Los puertos inferiores a 1024 están reservados en Linux. Para una instalación APT, el paquete configura automáticamente la capacidad CAP_NET_BIND_SERVICE en el binario de Caddy. Si compilaste Caddy manualmente, aplícala: setcap cap_net_bind_service=+ep $(which caddy).

DNS no resuelto / no such host. Caddy resuelve los nombres de los backends declarados en reverse_proxy. Si tu aplicación se llama app en Docker Compose, asegúrate de que Caddy y la aplicación comparten la misma red Docker. Verifica con: docker compose exec caddy nslookup app.

Volumen caddy_data eliminado por error. Caddy debe renegociar todos los certificados desde cero. Let's Encrypt impone un límite de 5 certificados por dominio en 7 días. Si alcanzas este límite, usa el entorno de staging ACME (acme_ca https://acme-staging-v02.api.letsencrypt.org/directory en el Caddyfile) para pruebas, y vuelve a producción una vez que haya pasado la ventana.

Para alojar múltiples aplicaciones en el mismo VPS

Crea una red Docker compartida (docker network create proxy) y conecta cada servicio a esa red. El Caddyfile referencia entonces los servicios por su nombre de contenedor en lugar de localhost:PORT — la configuración no cambia al añadir o quitar aplicaciones. Ejemplo: reverse_proxy mi-servicio:3000 en lugar de reverse_proxy localhost:3000.

Documentación oficial

La referencia completa de directivas, módulos y JSON API está disponible en <a href="https://caddyserver.com/docs/">caddyserver.com/docs</a>. El foro de la comunidad (<a href="https://caddy.community">caddy.community</a>) es el mejor recurso para preguntas avanzadas — los mantenedores responden directamente.

Tu VPS, listo para Caddy

Despliega Caddy en un VPS de ServOrbit y benefíciate de un entorno Debian 12, puertos 80 y 443 abiertos y acceso SSH inmediato.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva