# Desplegar

Despliega la aplicación en un servidor previamente aprovisionado. Cualquier proyecto de SvelteKit se puede desplegar, con o sin backend de PocketBase.

### Sintaxis

```
$ vela deploy
```

```
$ vela deploy --server root@example.com --domain example.com
```

Deploy no acepta argumentos posicionales. Compila la aplicación localmente, sube la release por SSH, ejecuta las migraciones pendientes contra la base de datos del servidor, reinicia los servicios y comprueba la salud del resultado. Una release que falla su comprobación de salud — sin respuesta, un 5xx, o un 404 en la ruta de salud — se revierte automáticamente, migraciones incluidas. Una redirección o un 401 cuentan como sana: algo está respondiendo.

### Objetivos

Un **objetivo** nombra una copia de la aplicación, nunca una máquina. `production` es el valor por defecto; cualquier nombre que elijas, como `staging`, es una copia separada en el mismo servidor o en otro. `local` es el proyecto en tu propio ordenador. `preview:<rama>` es una copia de una sola rama, que se elimina cuando la rama termina — consulta [Previsualizaciones](/es/deploy/previews).

El servidor detrás de un objetivo se registra la primera vez que lo nombras, en `.vela/project.json`, para no tener que reescribirlo en cada comando:

```
$ vela deploy --server root@example.com --domain example.com
$ vela deploy                                     # el mismo servidor, recordado
$ vela deploy -t staging --server root@staging.example.com --domain staging.example.com
$ vela deploy -t staging                          # staging, recordado
```

Sube `.vela/project.json` al repositorio. Contiene el id permanente de la aplicación con el que el servidor indexa cada release, archivo de entorno y base de datos — un id nuevo se instalaría como una aplicación distinta y dejaría huérfana la anterior. Usa [`vela targets`](/es/targets) para listar a qué está vinculado un proyecto.

Un `--server` distinto del registrado movería el objetivo a otra máquina, así que una terminal pide confirmación primero. En CI, o en cualquier lugar sin terminal, es un error: quita `--server` para usar el servidor registrado, o mueve el objetivo a propósito desde una terminal o editando `.vela/project.json`. Lo que se ejecutaba en el servidor anterior se queda allí.

### Opciones

- `-t, --target <target>` - Sobre qué copia de la aplicación actuar, por defecto `production`
- `--server <ssh>` - Servidor en el que se ejecuta este objetivo, registrado en el primer uso
- `--domain <hosts>` - Nombre(s) de host en los que servir, separados por comas. Opcional para un proyecto vinculado, que recibe un nombre `velastack.app`
- `--project <name>` - Sobrescribir el nombre del proyecto
- `--health-path <path>` - Ruta que solicita la comprobación de salud
- `--keep <count>` - Cuántas releases antiguas conservar en el servidor
- `--pb-version <version>` - Versión de PocketBase a ejecutar
- `--no-build` - Desplegar la salida de compilación existente sin recompilar
- `--lock-wait <seconds>` - Cuánto esperar a que termine otro despliegue, reversión o restauración del mismo objetivo antes de rendirse, por defecto `300`; `0` se rinde al instante
- `--remote-db` / `--no-remote-db` - Renderizar la compilación contra la base de datos del servidor, a través de un túnel SSH. Activado por defecto una vez que el objetivo ha sido desplegado con backend.
- `-i, --identity <file>` - Clave privada SSH con la que autenticarse
- `--ssh-port <port>` - Puerto SSH
- `--accept-host-keys` - Confiar en una clave de host desconocida en la primera conexión (CI)

### Nombres de host

Un objetivo se sirve en el nombre de host que le das con `--domain`, una vez que el DNS de ese nombre apunta al servidor. Un proyecto [vinculado](/es/link) a velastack.dev que se despliega con sesión iniciada no necesita uno: su primer despliegue reclama `<proyecto>.velastack.app`, los objetivos con nombre reciben `<proyecto>--staging.velastack.app`, y las previsualizaciones `<proyecto>--<rama>.velastack.app`. El despliegue imprime la URL, y un nombre nuevo está en línea en menos de un minuto.

Ambas cosas se pueden combinar. Con un dominio propio, ese dominio es el principal y el nombre gestionado redirige a él. Consulta [Dominios](/es/deploy/domains) para saber cómo se eligen los nombres, cómo se añaden tus propios dominios y qué necesita el servidor.

### Adaptador

`vela deploy` ejecuta la aplicación como un servidor Node, así que el proyecto tiene que compilarse con `@sveltejs/adapter-node`. Los proyectos nuevos de la plantilla por defecto ya lo hacen. Un proyecto con `@sveltejs/adapter-auto`, que es lo que da `sv create`, o sin ningún adaptador, se cambia en su primer despliegue: se reescriben la configuración y `package.json` y se instala el paquete. En una terminal el despliegue pregunta antes, indicando los archivos que va a editar; responde que no y no se cambia ni se despliega nada. En CI, o en cualquier sitio sin terminal, lo cambia sin preguntar. Sube al repositorio los archivos que lista el despliegue, lockfile incluido, para que cada despliegue compile igual.

Un proyecto con `@sveltejs/adapter-static` o con el adaptador de una plataforma de alojamiento ya ha elegido otra cosa. El despliegue no lo toca y se detiene antes de compilar, mostrando las líneas que cambiar. Aloja un [sitio estático](/es/static) en otro sitio, o consulta [Serverless](/es/serverless) para las plataformas.

### Backend

El despliegue comprueba cada vez si el proyecto tiene backend, en lugar de leer una opción: un directorio `data/` junto con el cliente de PocketBase en `package.json` (`pocketbase-sveltekit` o `@velastack/pocketbase`) significa PocketBase. Un proyecto sin ellos se despliega solo como aplicación.

Añade un backend con [`vela enable backend`](/es/enable/backend) y despliega de nuevo, y el mismo objetivo gana PocketBase. Despliega después de quitarlo y PocketBase se detiene; su base de datos se queda en el servidor hasta [`vela destroy deployment --purge`](/es/destroy/deployment). El despliegue avisa cuando ocurre cualquiera de las dos cosas. [`vela disable backend`](/es/disable/backend) también cambia el adaptador a static, así que vuelve a ponerlo en `@sveltejs/adapter-node` antes de desplegar de nuevo.

### Dependencias

El servidor instala las dependencias de producción de la release con npm: `npm ci` cuando el proyecto tiene un `package-lock.json`, y `npm install` en caso contrario. El árbol instalado se guarda en caché en el servidor, con el lockfile como clave, así que un despliegue que no cambia dependencias se salta la instalación.

Un `pnpm-lock.yaml`, `yarn.lock`, `bun.lock` o `bun.lockb` también se sube y forma parte de esa clave, así que un cambio en él provoca una reinstalación. Pero npm no puede reproducir esos lockfiles: las versiones se resuelven a partir de los rangos de `package.json` y pueden diferir de las tuyas, y el despliegue avisa de ello. Sube al repositorio un `package-lock.json` para un despliegue reproducible:

```
$ npm install --package-lock-only
```

El script `prepare` del proyecto no se ejecuta en el servidor. Es un hook de desarrollo, y las herramientas que llama son dependencias de desarrollo, que allí no se instalan. Los scripts de instalación de las propias dependencias se siguen ejecutando.

### Páginas prerenderizadas

Una página prerenderizada se renderiza una vez, en tiempo de compilación, contra la base de datos que la compilación pueda ver. En una copia limpia del repositorio esa es una base de datos vacía y desechable, así que esas páginas salen llenas de valores por defecto.

Los despliegues renderizan la compilación contra la base de datos a la que se despliega, tunelizada por la misma conexión SSH, en cuanto hay una contra la que renderizar. La compilación solo lee, y las credenciales de superusuario salen del propio servidor. Pasa `--no-remote-db` para usar una base de datos local desechable. El primer despliegue de un objetivo, y el primero después de añadir un backend, lo hacen de todos modos, ya que aún no hay base de datos en el servidor.

El nombre y la URL de la aplicación en esas páginas no salen de la base de datos: ambos se leen de [`src/lib/site.ts`](/es/cli/project-structure), así que los enlaces canónicos y las URLs de las imágenes Open Graph son correctos en cualquier compilación una vez definida ahí `url`. El origen que SvelteKit da a esas páginas como `url.origin` es aparte: el prerenderizado no tiene una petición de la que tomarlo, así que `vela build` lo establece a partir del dominio del objetivo. Sin un dominio configurado, es el host de marcador de posición de SvelteKit y la compilación lo indica.

### Nombre y URL de la aplicación

El despliegue avisa cuando `url` en `src/lib/site.ts` sigue siendo una dirección de localhost o no coincide con el dominio al que despliega.

Con backend, cada despliegue también define el nombre de aplicación del PocketBase desplegado como `site.name`, que es el que usan sus correos de verificación y de restablecimiento de contraseña. Un nombre cambiado en el [panel de administración](/es/admin) desplegado solo dura hasta el siguiente despliegue. El primer despliegue de un objetivo copia además el nombre y la dirección del remitente de tu base de datos local y define la URL de aplicación de PocketBase con el dominio desplegado.

### Dos despliegues a la vez

Solo se ejecuta un despliegue por objetivo a la vez. Un segundo — CI y un portátil, o dos personas — espera a que termine el primero, hasta `--lock-wait` segundos, y después se rinde con un mensaje que nombra lo que estaba esperando. Las reversiones y las restauraciones toman el mismo cerrojo, así que ninguna puede ejecutarse debajo de un despliegue.

Los ids de release se sellan con el reloj del servidor, así que todas las máquinas coinciden en cuál es más reciente. Un despliegue que termina de esperar y se encuentra con una release más reciente ya en línea se descarta en lugar de ponerse por delante: su subida se elimina y el comando falla, y lo que está en línea no se toca. Despliega de nuevo si no era eso lo que querías. Un id de release tiene esta forma: `20260910T141203Z-a3f9`.

### Configuración

Los valores por defecto pueden versionarse en `velastack.config.ts` en la raíz del proyecto, para no tener que pasarlos cada vez:

```ts
export default {
    project: 'my-app',
    deploy: {
        domain: 'example.com',
        healthCheckPath: '/',
        keepReleases: 5,
        buildAgainstRemote: false
    }
};
```

Todos los campos son opcionales, y también se leen `velastack.config.js`, `.mjs` y `.json`. Las opciones de la línea de comandos ganan al archivo de configuración, que a su vez gana a lo registrado en el último despliegue.

### Variables de entorno

Las variables de entorno de producción viven en el servidor, no en la release. Un despliegue nunca las lee, sube ni sobrescribe. Gestiónalas con [`vela env`](/es/env):

```
$ vela env set STRIPE_SECRET_KEY
$ vela env import .env.production
$ vela env list
```

### Después de desplegar

- [`vela status`](/es/status) - Mostrar qué está desplegado
- [`vela logs`](/es/logs) - Seguir los logs de una aplicación desplegada
- [`vela rollback`](/es/rollback) - Restaurar la release anterior
- [`vela destroy deployment`](/es/destroy/deployment) - Eliminar un entorno desplegado

### Historial de despliegues

Un proyecto [vinculado](/es/link) registra cada despliegue en velastack.dev: quién desplegó qué, desde qué commit, en qué nombre de host, y si tuvo éxito. Para ello hace falta una clave de API en la máquina que despliega — [`vela login`](/es/account/login) guarda una, y `VELA_API_KEY` en el entorno es lo que usa CI. Un proyecto vinculado sin clave avisa y despliega de todos modos; nada del despliegue en sí depende de que velastack.dev esté accesible.

El registro es también lo que da de alta el servidor y emite los nombres de host `velastack.app` de arriba. Un proyecto sin vincular nunca toca la red más allá de SSH.

### Acción de GitHub

Usa [`velastack/action`](/es/helpers/github-action) para desplegar desde un workflow de GitHub. Compila en el runner y entrega la release a `vela deploy` por SSH, de modo que un despliegue desde CI y uno desde tu portátil hacen lo mismo. La acción gestiona la clave SSH por sí misma.

```yaml
name: Deploy

on:
  push:
    branches: [main]

concurrency:
  group: deploy-prod
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: velastack/action@v1
        with:
          server: root@your-server
          ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
          domain: example.com
```

Aprovisiona el servidor y despliega una vez desde tu máquina primero — ese primer despliegue es el que genera el id de la aplicación. Usa un grupo de `concurrency` para que dos pushes se pongan en cola en lugar de competir; el servidor también serializa los despliegues de un mismo objetivo, así que no se pierde nada si dos llegan a solaparse.

### Previsualizaciones de pull requests

Varias copias de la aplicación pueden ejecutarse en un mismo servidor, cada una en su propio objetivo e internamente en su propio puerto. La acción aprovecha eso para dar a cada pull request una [previsualización](/es/deploy/previews): escucha los eventos de pull request, añade `pull-requests: write` para el comentario que mantiene actualizado, y pasa una clave de API para que la previsualización reciba su nombre de host `velastack.app`.

```yaml
on:
  push:
    branches: [main]
  pull_request:
    types: [opened, synchronize, reopened, closed]

permissions:
  contents: read
  pull-requests: write

concurrency:
  group: deploy-${{ github.head_ref || github.ref_name }}
  cancel-in-progress: false

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: velastack/action@v1
        with:
          server: root@your-server
          ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
          api-key: ${{ secrets.VELA_API_KEY }}
          domain: example.com
```

Un push a `main` despliega producción. Un pull request despliega `preview:<rama>` en `<proyecto>--<rama>.velastack.app`, y cerrarlo elimina la previsualización de nuevo, datos incluidos. Los pull requests de Dependabot o desde forks no llevan secretos; la [página de la acción](/es/helpers/github-action) muestra cómo saltárselos.