Docs

How Submify works

Submify is a self-hosted backend for HTML/JS forms. You create projects, each with a public and secret key. Browsers POST JSON to /api/submit with the public key; you review rows in the dashboard and export when needed.

This page is a condensed quick reference. The full README, deployment guide, and API contract live in the GitHub repository.

Requirements

Install

One command clones the repo, generates strong random secrets on first run, and brings up the full stack. Requires Docker Engine and the Compose v2 plugin. If you installed Docker from Debian's docker.io package, see the Debian prerequisite steps in the docs before running.

One-line installer (requires git + Docker Compose v2)

curl -fsSL https://raw.githubusercontent.com/Raktim94/Submify/main/install.sh | bash

Requires Docker Engine and the Compose v2 plugin. Once the containers are up, open http://localhost:2512 and create your first account at /register.

Configuration

No .env is required to get started — compose-up.sh / Compose-Up.ps1 auto-create .env.auto with strong random POSTGRES_PASSWORD and JWT_SECRET values on first run. Copy .env.example to .env only to override defaults (custom CORS origins, port, cookie settings, and so on).

  • Single published port — Nginx is the only exposed port (default 2512), proxying /api/* to the Go API and everything else to the dashboard.
  • One account per instance — registration only works while no account exists yet (GET /api/v1/system/bootstrap-status). After the first account is created, sign-up closes and POST /api/v1/auth/register returns 403.
  • Optional storage — connect any S3-compatible bucket per project from the dashboard for presigned uploads. No storage container ships with the stack.

API overview

Dashboard and API routes live under /api/v1 and require a Bearer access token. Public form submissions use a separate route, POST /api/submit, authenticated with a project's public key in the x-api-key header — not your account password.

The full request/response contract for every endpoint (auth, projects, submissions, exports, uploads) is documented in docs/api.md on GitHub.

Accessing from another device (LAN / network IP)

By default Nginx binds to 127.0.0.1, so the dashboard and API are reachable only from the same machine. To access Submify from another device on your network — or from the internet — follow these three steps.

1. Add these two lines to your .env file (create it from .env.example if it does not exist yet):

# Bind Nginx to all interfaces so other devices can reach port 2512.
# Replace 0.0.0.0 with a specific IP to restrict to one interface.
SUBMIFY_BIND_IP=0.0.0.0

# Add your server IP or hostname to the CORS allowlist.
# Replace 192.168.1.100 with your actual server IP or domain.
ALLOWED_ORIGINS=http://localhost:2512,http://127.0.0.1:2512,http://192.168.1.100:2512

2. Restart the stack:

docker compose up -d

3. Open port 2512 on your host firewall:

# UFW (Ubuntu / Debian)
sudo ufw allow 2512/tcp

# firewalld (Fedora / RHEL / CentOS)
sudo firewall-cmd --add-port=2512/tcp --permanent && sudo firewall-cmd --reload

# iptables
sudo iptables -I INPUT -p tcp --dport 2512 -j ACCEPT

Then open http://<server-ip>:2512 from any device on the same network. For internet-facing deployments, put Submify behind a reverse proxy (Nginx, Caddy, Traefik) or a Cloudflare Tunnel with TLS rather than exposing port 2512 directly.

Troubleshooting

Debian: Docker Compose v2 not found

If the installer fails with Docker Compose v2 plugin is required, you likely installed Docker from Debian's repositories (apt install docker.io) rather than Docker's official source. The Compose v2 plugin is not included in Debian's Docker package. Run these commands before retrying the installer:

1. Add Docker's official repository:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| sudo tee /etc/apt/sources.list.d/docker.list

sudo apt update

2. Remove the conflicting Debian buildx package:

sudo apt remove docker-buildx

3. Install the official plugins:

sudo apt install docker-buildx-plugin docker-compose-plugin

If apt install reports broken packages, run sudo apt --fix-broken install first, then retry step 3.

4. Verify and re-run the installer:

docker compose version
curl -fsSL https://raw.githubusercontent.com/Raktim94/Submify/main/install.sh | bash

Other issues

  • API exits with a JWT_SECRET error — with GIN_MODE=release, the secret must be at least 32 characters. Set it in .env, or use ./scripts/compose-up.sh so .env.auto supplies one.
  • Nothing on the published port — check your firewall, docker compose ps, and the Nginx container logs.
  • Build fails on a small VPS — re-run with --progress=plain to read the full error; try --parallel 1 or add swap if the build runs out of memory.