Self-Hosting Saltcorn with Docker Compose

Saltcorn started as a research project at the University of Cambridge, aiming to prove that a genuinely open-source no-code platform could match proprietary tools like Airtable and Bubble for building data-driven web applications. The result is a platform where you define database tables, build views, create pages, and set up authentication — all through a browser UI, without writing a single line of code.

What Is Saltcorn?

Saltcorn is an open-source no-code platform for building database-backed web applications. You design your data model visually, create list/show/edit views, add user authentication and role-based access, install plugins from a marketplace, and deploy — all without code. It supports PostgreSQL for production and SQLite for lightweight deployments. Think of it as a self-hosted Airtable with the ability to build full web apps on top of your data.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of RAM minimum (2 GB recommended)
  • 2 GB of free disk space
  • A domain name (optional, for remote access)

Docker Compose Configuration

Create a docker-compose.yml:

services:
  saltcorn:
    image: saltcorn/saltcorn:1.4.3
    container_name: saltcorn
    restart: unless-stopped
    command: "serve"
    ports:
      - "3000:3000"
    environment:
      SALTCORN_SESSION_SECRET: "${SALTCORN_SECRET}"
      PGHOST: saltcorn-db
      PGUSER: "${PGUSER}"
      PGDATABASE: "${PGDATABASE}"
      PGPASSWORD: "${PGPASSWORD}"
      NODE_ENV: "production"
    depends_on:
      saltcorn-db:
        condition: service_healthy
    networks:
      - saltcorn

  saltcorn-db:
    image: postgres:16-alpine
    container_name: saltcorn-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: "${PGUSER}"
      POSTGRES_PASSWORD: "${PGPASSWORD}"
      POSTGRES_DB: "${PGDATABASE}"
    volumes:
      - saltcorn-data:/var/lib/postgresql/data
    networks:
      - saltcorn
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${PGUSER}"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  saltcorn-data:

networks:
  saltcorn:

Create a .env file:

# Database credentials
PGUSER=saltcorn
PGPASSWORD=change-this-strong-password
PGDATABASE=saltcorn

# Session encryption — generate with: openssl rand -hex 32
SALTCORN_SECRET=change-this-run-openssl-rand-hex-32

Generate the session secret and start:

sed -i "s/change-this-run-openssl-rand-hex-32/$(openssl rand -hex 32)/" .env

docker compose up -d

Initial Setup

  1. Open http://your-server-ip:3000 in your browser
  2. Saltcorn starts with a setup wizard — choose your initial configuration
  3. Create your admin account with email and password
  4. You’ll land on the builder — start by creating a Table to define your data model
  5. Add fields (text, number, date, file, foreign key) to your table
  6. Create a View (list, show, edit, or filter) to display and interact with data
  7. Build Pages to compose views into a full application layout

Configuration

SettingEnvironment VariableDefaultNotes
Session secretSALTCORN_SESSION_SECRETNone (required)Encrypts session cookies
Multi-tenant modeSALTCORN_MULTI_TENANTfalseHost multiple independent sites
File store pathSALTCORN_FILE_STORE~/.local/share/saltcornWhere uploaded files are stored
Worker countSALTCORN_NWORKERSAutoNumber of Node.js worker processes
Database URLDATABASE_URLIndividual PG varsFull connection string (overrides PG* vars)
SSL modePGSSLMODENonePostgreSQL SSL connection mode

Persisting File Uploads

The default file store location inside the container is /root/.local/share/saltcorn. To persist uploaded files across container recreations, add a volume mount:

  saltcorn:
    volumes:
      - saltcorn-files:/root/.local/share/saltcorn

Add saltcorn-files: to the volumes: section.

Advanced Configuration

Multi-Tenant Mode

Saltcorn supports hosting multiple independent applications on subdomains:

SALTCORN_MULTI_TENANT=true

Each tenant gets its own database schema, users, and configuration. Tenants are created via the admin UI and accessed via subdomains (tenant1.yourdomain.com).

SQLite for Lightweight Deployments

For single-user or development setups, skip PostgreSQL entirely:

services:
  saltcorn:
    image: saltcorn/saltcorn:1.4.3
    container_name: saltcorn
    restart: unless-stopped
    command: "serve"
    ports:
      - "3000:3000"
    environment:
      SALTCORN_SESSION_SECRET: "your-secret-key"
      SQLITE_FILEPATH: "/data/saltcorn.db"
    volumes:
      - saltcorn-sqlite:/data

volumes:
  saltcorn-sqlite:

Custom Plugins

Saltcorn has a plugin marketplace accessible from the admin UI. Plugins extend functionality with new field types, view templates, authentication providers, and page elements. Install them directly from the UI under Settings → Plugins.

Reverse Proxy

Saltcorn serves on port 3000 by default. For Nginx Proxy Manager, proxy to http://saltcorn:3000. For Caddy:

saltcorn.yourdomain.com {
    reverse_proxy saltcorn:3000
}

See Reverse Proxy Setup for full configuration.

Backup

Back up the PostgreSQL database and the file store:

# Database backup
docker exec saltcorn-db pg_dump -U saltcorn saltcorn > saltcorn-backup.sql

# File store backup (if using volume mount)
docker run --rm -v saltcorn-files:/data -v $(pwd):/backup alpine \
  tar czf /backup/saltcorn-files.tar.gz -C /data .

Saltcorn also has built-in backup from the admin UI under Settings → Backup — it exports the full application state (tables, views, pages, users, plugins) as a single .zip file that can be restored on any Saltcorn instance.

See Backup Strategy for automated approaches.

Troubleshooting

”ECONNREFUSED” error on startup

Symptom: Saltcorn exits with a PostgreSQL connection refused error. Fix: The database container isn’t ready yet. The health check and depends_on condition should handle this, but if you see the error on first boot, wait 30 seconds and restart: docker compose restart saltcorn.

Plugins fail to install

Symptom: Installing a plugin from the marketplace hangs or errors. Fix: The container needs outbound internet access to download plugins from npm. Verify DNS resolution works inside the container: docker exec saltcorn ping -c 1 registry.npmjs.org. If behind a firewall, ensure port 443 outbound is open.

File uploads disappear after container restart

Symptom: Uploaded files show broken links after recreating the container. Fix: Add a volume mount for the file store directory. Without it, /root/.local/share/saltcorn inside the container is ephemeral. See the “Persisting File Uploads” section above.

App shows “Internal Server Error” on page load

Symptom: Pages that worked previously return 500 errors. Fix: Check logs with docker logs saltcorn. Common causes: a plugin update broke compatibility (downgrade via Settings → Plugins), or a view references a deleted table field. The error log usually identifies the specific view or plugin causing the issue.

Resource Requirements

ResourceMinimumRecommended
RAM512 MB (SQLite) / 1 GB (PostgreSQL)2 GB
CPU1 core2 cores
Disk2 GB10 GB
Containers1 (SQLite) / 2 (PostgreSQL)2

Saltcorn is one of the lightest no-code platforms available. The Node.js server idles at around 100-150 MB RAM. PostgreSQL adds another 100-200 MB. Total stack footprint is under 500 MB idle — a fraction of what Appsmith or Appwrite require.

Verdict

The practical choice for Saltcorn is clear: if you want a no-code app builder that runs on minimal hardware and genuinely requires zero code, this is it. It fills the gap between “spreadsheet with a UI” (Airtable, NocoDB) and “full low-code IDE” (Appsmith, ToolJet). You won’t build a complex internal dashboard with 50 API integrations — that’s ToolJet’s territory. But for database-backed web apps with forms, lists, authentication, and role-based access, Saltcorn delivers with a fraction of the complexity and resource requirements.

FAQ

Can Saltcorn replace Airtable?

For the data management and views aspect, yes — Saltcorn handles tables, views, filters, and forms. It goes beyond Airtable by letting you build full web applications with pages, authentication, and custom layouts. It lacks Airtable’s collaboration features and polished UI, but you own all the data. See Self-Hosted Alternatives to Airtable.

Does Saltcorn support user authentication?

Yes. Built-in email/password authentication with role-based access control (admin, staff, public, and custom roles). You can restrict views and pages by role. OAuth plugins are available for Google and GitHub login.

Can I export my Saltcorn app?

Yes. Saltcorn supports full export/import of applications including tables, views, pages, plugins, and data. Export from Settings → Backup as a .zip file, and import on any Saltcorn instance. There’s also a mobile app builder for packaging apps as Android/iOS apps.

What’s the difference between Saltcorn and NocoDB?

NocoDB is a spreadsheet-database hybrid (like Airtable) — it turns any database into a spreadsheet interface. Saltcorn is an application builder — you create full web apps with pages, views, forms, and authentication. NocoDB is better for data management; Saltcorn is better for building end-user applications.

Comments