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
- Open
http://your-server-ip:3000in your browser - Saltcorn starts with a setup wizard — choose your initial configuration
- Create your admin account with email and password
- You’ll land on the builder — start by creating a Table to define your data model
- Add fields (text, number, date, file, foreign key) to your table
- Create a View (list, show, edit, or filter) to display and interact with data
- Build Pages to compose views into a full application layout
Configuration
| Setting | Environment Variable | Default | Notes |
|---|---|---|---|
| Session secret | SALTCORN_SESSION_SECRET | None (required) | Encrypts session cookies |
| Multi-tenant mode | SALTCORN_MULTI_TENANT | false | Host multiple independent sites |
| File store path | SALTCORN_FILE_STORE | ~/.local/share/saltcorn | Where uploaded files are stored |
| Worker count | SALTCORN_NWORKERS | Auto | Number of Node.js worker processes |
| Database URL | DATABASE_URL | Individual PG vars | Full connection string (overrides PG* vars) |
| SSL mode | PGSSLMODE | None | PostgreSQL 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
| Resource | Minimum | Recommended |
|---|---|---|
| RAM | 512 MB (SQLite) / 1 GB (PostgreSQL) | 2 GB |
| CPU | 1 core | 2 cores |
| Disk | 2 GB | 10 GB |
| Containers | 1 (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.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments