← Blog

Poner PrintStash detrás de un proxy inverso con TLS

Usa el Compose de producción con Caddy, Traefik o nginx, mantén la API fuera de la red del host y conserva subidas y estado por WebSocket.

guíaseguridaddespliegue

PrintStash está pensado para una red de confianza. Si necesitas llegar a él a través de un nombre de host público, usa el archivo Compose de producción y pon un proxy inverso con TLS delante del contenedor web.

El stack de producción publica el frontend en 127.0.0.1:3000. No publica el puerto de la API en el host. La instancia de nginx del frontend hace de proxy del tráfico de la API y del WebSocket por la red interna de Docker, así que tu proxy inverso solo necesita un upstream.

Arranca el stack de producción con:

Terminal window
docker compose -f docker-compose.prod.yml up -d

Antes de hacerlo, pon un VAULT_JWT_SECRET robusto en .env. El archivo Compose de producción se niega a arrancar sin él.

Caddy

Caddy se encarga de los certificados y de los WebSockets sin reglas adicionales:

printstash.example.com {
reverse_proxy 127.0.0.1:3000
}

Apunta el nombre de host al servidor, deja que Caddy alcance los puertos 80 y 443, y recarga su configuración. No publiques el puerto 8000.

Traefik

Cuando Traefik se ejecuta en Docker, conéctalo a la misma red que el frontend de PrintStash y añade etiquetas al servicio del frontend:

labels:
- "traefik.enable=true"
- "traefik.http.routers.printstash.rule=Host(`printstash.example.com`)"
- "traefik.http.routers.printstash.entrypoints=websecure"
- "traefik.http.routers.printstash.tls.certresolver=le"
- "traefik.http.services.printstash.loadbalancer.server.port=3000"

Si Traefik llega al contenedor por la red de Docker, quita el mapeo del puerto del host en el frontend. Si no, deja el mapeo a localhost y configura Traefik para usar el upstream del host.

nginx

nginx necesita las cabeceras de upgrade para el estado en vivo de la impresora y un límite de tamaño de cuerpo suficiente para subir modelos:

server {
listen 443 ssl;
server_name printstash.example.com;
ssl_certificate /etc/letsencrypt/live/printstash.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/printstash.example.com/privkey.pem;
client_max_body_size 512m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Ajusta client_max_body_size a VAULT_MAX_UPLOAD_MB si cambias el valor por defecto de 512 MB.

Comprueba el límite antes de abrir un puerto

Confirma que el host solo escucha donde esperas:

Terminal window
docker compose -f docker-compose.prod.yml ps
curl -I http://127.0.0.1:3000

El puerto 8000 no debería estar publicado. Las peticiones a /api/v1 y el WebSocket de estado en vivo tienen que pasar por el frontend, no por una segunda ruta pública del proxy.

Usa contraseñas de cuenta robustas y mantén actualizados PrintStash, el proxy y el host. La autenticación básica del proxy puede añadir otra petición de credenciales, pero no sustituye a la autenticación de PrintStash ni a un secreto JWT único.

Si solo tus propios dispositivos necesitan acceso, una VPN como WireGuard o Tailscale suele ser más sencilla que exponer un servicio público. Puedes dejar PrintStash en la red privada y evitar el reenvío de puertos entrante.

La guía de instalación contiene los ejemplos de despliegue actuales. El modelo de seguridad explica lo que significa el límite de red de confianza para el resto de la aplicación.