Español
Empezar

← Todas las plantillas · Productividad

Despliega NocoDB en un clic

Una base de datos sin código: tablas como hojas de cálculo, formularios, tableros kanban y calendarios, con API

Una alternativa autoalojada a Airtable.

¿Qué es NocoDB?

NocoDB es una plataforma de bases de datos sin código: las tablas se ven y funcionan como una hoja de cálculo, y cada una también se puede mostrar como formulario, galería, tablero kanban, calendario, mapa o diagrama de Gantt. Los campos guardan texto, números, fechas, selecciones, adjuntos, fórmulas, enlaces a otras tablas, búsquedas (lookup) y acumulados (rollup). Cada tabla tiene una API REST, los webhooks se disparan cuando se crean, actualizan o eliminan registros, y se pueden importar tablas desde Airtable, CSV, Excel y JSON.

Los equipos usan NocoDB en lugar de Airtable para llevar un CRM, un inventario, un calendario de contenidos o cualquier lista compartida en una base de datos que controlan. Esta plantilla ejecuta la edición Community gratuita con PostgreSQL, crea el Super Admin con los datos de los campos antes de que NocoDB responda a nadie y cierra el registro, así que solo se entra por invitación. El inconveniente: la Sustainable Use License de NocoDB permite usarlo de forma interna y personal, pero no revenderlo, y el SSO y los permisos por tabla y por campo están en los planes autoalojados de pago.

Hosting de NocoDB en Pethost

  1. Inicias sesión en Pethost con una passkey, GitHub o Google. ¿Aún no tienes máquina? Eliges un plan, y el enlace espera hasta que esté lista.
  2. Nuevo proyecto se abre en NocoDB. Rellenas lo que pide y haces clic en Crear proyecto: Correo electrónico, Contraseña de administrador.
  3. En un par de minutos NocoDB está en marcha en su propia dirección con HTTPS. Sus secretos se generan al azar, y sus datos entran en el backup de cada noche.
  4. Es un proyecto como cualquier otro: tú o tu agente lo pueden cambiar, volver a una versión anterior o restaurar.

Preguntas sobre NocoDB

¿NocoDB es gratis?

La edición Community autoalojada es gratis, con registros y puestos ilimitados, bajo la Sustainable Use License de NocoDB: puedes usarla dentro de tu propia empresa o para uso personal, pero no vendérsela a otros. Los planes autoalojados de pago cuestan desde 24 USD por puesto al mes, con facturación anual, y agregan SSO y permisos por tabla y por campo.

NocoDB frente a Airtable: ¿cuál es la diferencia?

Los dos muestran las tablas como hojas de cálculo, con formularios, kanban y galerías. Airtable solo funciona en su propia nube, con precio por puesto, mientras que NocoDB funciona donde lo despliegues, y su edición Community no pone límite de registros.

¿Puedo importar mis bases de Airtable a NocoDB?

Sí. NocoDB importa una base desde su enlace compartido con un token de acceso personal de Airtable que pueda leer registros, y trae sus tablas, vistas y registros. Los campos de fórmula no se importan, y el enlace de una vista compartida trae solo esa tabla.

¿NocoDB tiene una API?

Sí. Cada tabla tiene una API REST, que se llama con un token de API, y los webhooks envían una petición cuando se crea, actualiza o elimina un registro, así que otras apps y scripts pueden leer y escribir los datos.

¿Cómo agrego personas a NocoDB?

En Members & teams → Añadir miembros, por correo o con un enlace de invitación privado, eligiendo su rol. Esta plantilla cierra el registro público, así que nadie entra sin invitación. NocoDB envía las invitaciones por correo en cuanto NC_SMTP_HOST y los demás ajustes NC_SMTP_ están en el .env del proyecto.

¿Cuánta memoria y disco necesita NocoDB?

NocoDB ocupa unos 800 MB de memoria con Postgres, y su base de datos crece con tus registros; los adjuntos ocupan lo que ocupan sus archivos. En Pethost le basta el plan Starter, y queda sitio para otras apps a su lado.

El archivo Docker Compose de NocoDB

La plantilla es este compose.yaml y las variables que se escriben en el .env del proyecto al crearlo. Pethost ejecuta el archivo tal como está escrito.

Contenedores: nocodb (nocodb/nocodb:2026.10.0), postgres (postgres:18-alpine).

Volúmenes, en el backup de cada noche: data, db.

services:
  nocodb:
    image: nocodb/nocodb:2026.10.0
    restart: unless-stopped
    # Any setting of NocoDB can be added to the project's .env, such as NC_SMTP_HOST and the other
    # NC_SMTP_ settings, which send its invitations and password resets by email.
    env_file: .env
    environment:
      NC_DB: pg://postgres:5432?u=nocodb&p=${POSTGRES_PASSWORD}&d=nocodb
      NC_AUTH_JWT_SECRET: ${JWT_SECRET}
      NC_SITE_URL: ${URL}
      # The super admin is made from these at the first start, before NocoDB answers anyone, and
      # its email and password are set again from them at every start: change them here.
      NC_ADMIN_EMAIL: ${ADMIN_EMAIL}
      NC_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
      # Uploaded files are served only to those signed in, through links that expire.
      NC_SECURE_ATTACHMENTS: "true"
    # A new NocoDB lets anyone sign up, and only its super admin closes that, in Account → Setup.
    # So until that setting has been saved once, NocoDB runs on port 8081, which nobody reaches,
    # and the super admin closes sign-up there; only then does it answer on 8080. Turned on again
    # in NocoDB later, sign-up stays open.
    command:
      - sh
      - -c
      - |
        set -e
        cd /usr/src/app
        if ! node -e '
          const { Client } = require("pg");
          const url = new URL(process.env.NC_DB);
          const params = url.searchParams;
          const connection = { host: url.hostname, port: Number(url.port), user: params.get("u"), password: params.get("p"), database: params.get("d") };
          (async () => {
            for (let i = 0; i < 60; i++) {
              const db = new Client(connection);
              try {
                await db.connect();
                const result = await db.query("select 1 from nc_store where key = $$1", ["nc-app-settings"]);
                process.exit(result.rowCount > 0 ? 0 : 1);
              } catch (error) {
                // No such table: a new database, which the migrations of NocoDB have yet to fill.
                if (error.code === "42P01") process.exit(1);
                await db.end().catch(() => {});
                await new Promise((done) => setTimeout(done, 1000));
              }
            }
            process.exit(1);
          })();
        '; then
          PORT=8081 node --no-wasm-dynamic-tiering --no-wasm-tier-up docker/index.js &
          setup=$$!
          node -e '
            const base = "http://127.0.0.1:8081";
            const call = async (path, body, token) => {
              const response = await fetch(base + path, {
                method: "POST",
                headers: { "content-type": "application/json", ...(token ? { "xc-auth": token } : {}) },
                body: JSON.stringify(body)
              });
              if (!response.ok) throw new Error(path + ": " + response.status + " " + (await response.text()));
              return response.json();
            };
            const closeSignUp = async () => {
              const { token } = await call("/api/v1/auth/user/signin", { email: process.env.NC_ADMIN_EMAIL, password: process.env.NC_ADMIN_PASSWORD });
              await call("/api/v1/app-settings", { invite_only_signup: true }, token);
            };
            (async () => {
              let failure;
              for (let i = 0; i < 300; i++) {
                try {
                  return await closeSignUp();
                } catch (error) {
                  failure = error;
                  await new Promise((done) => setTimeout(done, 1000));
                }
              }
              console.error(failure);
              process.exit(1);
            })();
          '
          kill $$setup
          wait $$setup || true
        fi
        exec /usr/src/appEntry/start.sh
    volumes:
      - data:/usr/app/data
    depends_on:
      postgres:
        condition: service_healthy
    # The port listens before NocoDB is ready: the deploy waits for its health.
    healthcheck:
      test: ["CMD-SHELL", "wget -q --tries=1 --spider http://127.0.0.1:8080/api/v1/health || exit 1"]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 120s

  postgres:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: nocodb
      POSTGRES_USER: nocodb
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U nocodb -d nocodb"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s

volumes:
  data:
  db:

Más en Productividad