> For the complete documentation index, see [llms.txt](https://docs.dapta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dapta.ai/dapta-docs-es/dforms/developers/self-hosting.md).

# Autoalojamiento

Ejecuta tu propia copia de dForms: las dos apps, las imágenes de Docker, PostgreSQL en producción, el puñado de ajustes que importan y qué cambia cuando dejas el app.dforms.ai alojado.

dForms es agnóstico al despliegue: es Node puro, sin APIs propias de un host, así que corre en Docker, Kubernetes, una sola máquina virtual o cualquier cosa entre medias. Esta página es un mapa. Las instrucciones de referencia viven en el repositorio y se mantienen al día con el código.

| Archivo del repositorio                                                                                     | Qué cubre                                                                                                                                                                                                                |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`README.md`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/README.md)                             | El ciclo de desarrollo local: clonar, instalar, ejecutar. Sin base de datos ni cuentas.                                                                                                                                  |
| [`SELF-HOSTING.md`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/SELF-HOSTING.md)                 | La guía de producción: construir las imágenes, la referencia completa de entorno, la base de datos, el proxy inverso y TLS, el inicio de sesión, el correo, las actualizaciones, el rollback y la solución de problemas. |
| [`.env.example`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/.env.example)                       | Cada ajuste con notas en línea y su valor por defecto.                                                                                                                                                                   |
| [`docker-compose.prod.yml`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/docker-compose.prod.yml) | Una pila de referencia con forma de producción que puedes levantar con un comando.                                                                                                                                       |

<figure><img src="https://365551146-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMUYDYzjmxpzlYaw0gcaZ%2Fuploads%2Fgit-blob-390e5a20d3049425191d2921c95edce4f1e58cd6%2Fforms-self-hosting-01-guide.png?alt=media" alt="La guía de producción SELF-HOSTING.md renderizada en GitHub dentro del repositorio dapta-forms"><figcaption><p><code>SELF-HOSTING.md</code> en el repositorio es la guía de producción. Empieza por ahí.</p></figcaption></figure>

***

## Las dos apps

Un despliegue de dForms son dos contenedores más una base de datos.

* **Web** (`apps/web`): las páginas públicas de los formularios y el panel. Escucha en el puerto `3000`.
* **API** (`apps/api`): los endpoints públicos de envío y los del panel. Escucha en el puerto `4000`, y expone `/health` y `/health/ready` para tu balanceador.

La app web nunca habla directamente con la base de datos: llama a la API por HTTP. Por eso las dos se pueden escalar y desplegar por separado.

Los dos Dockerfiles toman la raíz del repositorio como contexto de construcción:

```bash
docker build -f apps/api/Dockerfile -t dapta-forms-api .
docker build -f apps/web/Dockerfile -t dapta-forms-web \
  --build-arg NEXT_PUBLIC_API_URL=https://forms-api.example.com .
```

> **⚠️ Nota:** Cada valor `NEXT_PUBLIC_*` se hornea en la imagen web al construirla, no se lee al arrancar el contenedor. Si mueves la API o cambias cualquiera de esos valores, reconstruye la imagen web.

***

## La base de datos

PostgreSQL es la base de datos de producción. El repositorio también soporta un archivo SQLite para que puedas clonar el proyecto y tenerlo corriendo en un minuto, pero ese camino es solo para evaluación y desarrollo local.

* Apunta `DATABASE_URL` a tu instancia de PostgreSQL.
* **Ejecuta las migraciones antes de que arranque la API.** La imagen de la API no migra al arrancar, a propósito, para que escalar a varias réplicas nunca haga que varias migren a la vez. La pila de referencia lo hace con un servicio `migrate` de un solo uso que corre y termina.
* Las migraciones añaden cosas (tablas nuevas, columnas nuevas anulables), así que una actualización nunca borra datos de un despliegue en marcha. Algunas también actualizan datos guardados: por ejemplo, una añadió la variable `{{answers}}` a los avisos de nueva respuesta personalizados que no la tenían.

***

## Los ajustes que importan

Todo tiene un valor por defecto seguro, así que un despliegue pelado arranca. Estos son los que de verdad pondrás en un despliegue real. La lista completa está en `SELF-HOSTING.md` y `.env.example`.

| Ajuste                                    | Por qué lo pones                                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NODE_ENV`                                | `production` en cualquier despliegue real.                                                                                                                                                                                                                                                                                                                                                                      |
| `DATABASE_URL`                            | Tu cadena de conexión a PostgreSQL.                                                                                                                                                                                                                                                                                                                                                                             |
| `PUBLIC_APP_URL`                          | Tu URL base pública, por ejemplo `https://forms.example.com`. Es el origen de confianza que se usa para construir las redirecciones de inicio de sesión y la lista por defecto de orígenes de navegador permitidos. También es la base del enlace a las respuestas en los avisos de nueva respuesta (que se omite si no está definida), y el host contra el que la protección contra spam comprueba cada token. |
| `NEXT_PUBLIC_API_URL`                     | Dónde alcanza el navegador tu API. Es un valor de construcción, así que se hornea en la imagen web.                                                                                                                                                                                                                                                                                                             |
| `AUTH_PROVIDER`                           | Qué adaptador de inicio de sesión usa el panel. Por defecto es un stub de desarrollo sin autenticar, y la API se niega a arrancar con él en producción. Mira **Auth options** en `SELF-HOSTING.md` para el valor de producción y los secretos que necesita.                                                                                                                                                     |
| `EMAIL_PROVIDER`                          | `log-only` por defecto, que imprime los avisos de respuesta en el log de la API en lugar de enviarlos. Cámbialo a SMTP o a una API HTTP de correo para enviar de verdad, y define `MAIL_FROM_EMAIL` y `MAIL_FROM_NAME`.                                                                                                                                                                                         |
| `CORS_ORIGINS`                            | Los dominios extra que pueden llamar a tu API desde un navegador. Solo hace falta cuando tu propio código llama a la API desde una página de otro dominio: los formularios insertados llegan a la API a través de la app web, así que no lo necesitan.                                                                                                                                                          |
| `TRUST_PROXY_HOPS`                        | Cuántos proxies de confianza hay delante de la API. Decide qué dirección cuenta el limitador de tasa, así que acierta o limitarás a todo el mundo como si fuera un solo cliente.                                                                                                                                                                                                                                |
| `HUBSPOT_PRIVATE_APP_TOKEN`               | Opcional. Ponlo y HubSpot funciona para todo el despliegue. Déjalo sin poner y el destino de HubSpot reporta un estado desactivado claro.                                                                                                                                                                                                                                                                       |
| `CAPTCHA_SITE_KEY` y `CAPTCHA_SECRET_KEY` | Opcionales, y siempre en pareja. Define las dos para que tus formularios puedan usar la [protección contra spam](/dapta-docs-es/dforms/connect/spam-protection.md). Mira [Flags de funcionalidad y entorno](/dapta-docs-es/dforms/developers/environment-flags.md#proteccion-contra-spam).                                                                                                                      |

Los ajustes del servidor se validan al arrancar la API, y un valor incorrecto falla de forma ruidosa con un mensaje que nombra la variable culpable.

***

## Inicio de sesión, TLS y correo

* Pon un proxy inverso delante de las dos apps y termina TLS ahí. Sirve cualquier proxy: nginx, Caddy, Traefik, un balanceador de nube. Reenvía a web en `3000` y a la API en `4000`.
* Las páginas públicas de formulario están siempre abiertas. El inicio de sesión solo protege el panel, y es un adaptador enchufable: el stub local por defecto vale para evaluar, y un despliegue real lo apunta a tu propio servicio de identidad. `SELF-HOSTING.md` tiene los valores y secretos exactos.
* La entrega de correo también es enchufable. Las notificaciones de respuesta se encolan y se reintentan con backoff, así que un proveedor de correo lento o inalcanzable nunca hace fallar el envío de quien responde.

***

## Qué es distinto respecto a app.dforms.ai

| En app.dforms.ai                                                                      | En tu propio despliegue                                                                                                     |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Entras con tu cuenta de Dapta.                                                        | Conectas tu propio inicio de sesión, o ejecutas el stub de desarrollo abierto para evaluar.                                 |
| Los workspaces, miembros, roles e invitaciones vienen de tu cuenta de Dapta.          | No hay workspaces de Dapta. La membresía viene del servicio de identidad que conectes.                                      |
| HubSpot y Calendly se conectan por cuenta desde **Conexiones**.                       | La misma pantalla, pero los tokens los pones tú, y además puedes definir un token de HubSpot para todo el despliegue.       |
| Los correos de respuesta se envían por ti.                                            | No se envía nada hasta que configuras un proveedor de correo. Hasta entonces, los avisos se escriben en el log de la API.   |
| La protección contra spam está lista para activarse en cada formulario.               | Necesita tus propias claves de Cloudflare Turnstile. Sin ellas, el interruptor de la pestaña **Conectar** está desactivado. |
| Dapta se encarga de las copias de seguridad, las actualizaciones y la disponibilidad. | Tú: las copias de la base de datos, las migraciones, las actualizaciones de imagen y los rollbacks son tuyos.               |
| El soporte y los reportes de fallos van por Dapta.                                    | El soporte es el repositorio: issues y pull requests en GitHub.                                                             |

Todo lo demás (el editor, la lógica, el puntaje, el diseño, los webhooks, las respuestas y las analíticas) es el mismo producto.

***

## Qué sigue

* [API pública y límites de tasa](/dapta-docs-es/dforms/developers/public-api.md): los endpoints que expone tu despliegue.
* [Flags de funcionalidad y entorno](/dapta-docs-es/dforms/developers/environment-flags.md): los ajustes que cambian lo que ve tu gente.
* [Conexiones (a nivel de cuenta)](/dapta-docs-es/dforms/connect/connections.md): la pantalla donde se conectan HubSpot y Calendly.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.dapta.ai/dapta-docs-es/dforms/developers/self-hosting.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
