Deployment
Launch Formlander locally or on a server with environment-driven configuration.
Quick install (recommended)
Section titled “Quick install (recommended)”One command installs everything on a fresh Ubuntu/Debian server:
curl -fsSL https://raw.githubusercontent.com/karloscodes/formlander/main/install.sh | sudo bashThe installer:
- Prompts for your domain and email
- Installs Docker and SQLite if needed
- Deploys Formlander with SSL via Caddy
- Sets up automatic daily updates at 3 AM
After installation, visit https://your-domain.com to log in.
Manual deployment
Section titled “Manual deployment”Formlander is a self-contained Go binary. Configuration is powered by Viper, giving you flexible options:
- Environment variables (prefix:
FORMLANDER_) - highest priority .envfile - for easier local development- Environment variables always override
.envfile values
SQLite stores submissions and configuration in the storage/ directory by default.
Current status: Formlander v1.0.0 is now available as an open-source project. Pull the Docker image from Docker Hub or download binaries from GitHub Releases.
1. Configuration options
Section titled “1. Configuration options”1.1 Using environment variables
Section titled “1.1 Using environment variables”For production deployments, you must set this security variable:
FORMLANDER_SESSION_SECRET=your-secret-here # Generate with: openssl rand -hex 32⚠️ Important: Required in production. In development/test, a fixed default secret is used (sessions persist across restarts).
Common configuration options:
FORMLANDER_ENV=production # Environment: development, production (default: development)FORMLANDER_PORT=8080 # HTTP port (default: 8080)FORMLANDER_SESSION_SECRET=your-secret # HMAC secret (REQUIRED in production)FORMLANDER_LOG_LEVEL=info # Log level: debug, info, warn, error (default: info)FORMLANDER_DATA_DIR=./storage # Data directory (default: ./storage)1.2 Using .env file
Section titled “1.2 Using .env file”Create a .env file in your project root for easier local development:
# Required in productionFORMLANDER_SESSION_SECRET=your-secret-here
# Optional overridesFORMLANDER_ENV=productionFORMLANDER_PORT=8080FORMLANDER_LOG_LEVEL=infoFORMLANDER_DATA_DIR=./storageConfiguration precedence: Environment variables always override
.envfile values. This is useful for keeping secrets in environment variables while maintaining other settings in the.envfile.
1.3 All configuration options
Section titled “1.3 All configuration options”| Environment Variable | Default | Description |
|---|---|---|
FORMLANDER_SESSION_SECRET | (required in production) | HMAC secret (fixed default in dev/test) |
FORMLANDER_ENV | production | Environment: development, production |
FORMLANDER_PORT | 8080 | HTTP server port |
FORMLANDER_LOG_LEVEL | error | Log level: debug, info, warn, error |
FORMLANDER_DATA_DIR | storage | Base directory for data files |
For a complete list of advanced configuration options, see the Formlander GitHub repository.
First-time setup: After starting Formlander for the first time, visit the web interface at
http://localhost:8080with default credentials:
- Email:
[email protected]- Password:
formlanderYou’ll be required to change the password on first login.
2. Run with Docker
Section titled “2. Run with Docker”Quick start (recommended)
Section titled “Quick start (recommended)”docker run -d \ -p 8080:8080 \ -e FORMLANDER_SESSION_SECRET=$(openssl rand -hex 32) \ -v $(pwd)/storage:/app/storage \ karloscodes/formlander:latestThen visit http://localhost:8080 to log in with default credentials.
Using a .env file
Section titled “Using a .env file”You can use a .env file with Docker for easier configuration management.
Create a .env file:
# Required in productionFORMLANDER_SESSION_SECRET=your-secret-here
# Optional overridesFORMLANDER_ENV=productionFORMLANDER_PORT=8080FORMLANDER_LOG_LEVEL=infoRun with .env file:
docker run -d \ --env-file .env \ -p 8080:8080 \ -v $(pwd)/storage:/app/storage \ karloscodes/formlander:latestOr mix both (environment variables override .env file):
This is useful for keeping secrets in environment variables while maintaining other settings in the .env file:
docker run -d \ -e FORMLANDER_SESSION_SECRET=$(openssl rand -hex 32) \ --env-file .env \ -p 8080:8080 \ -v $(pwd)/storage:/app/storage \ karloscodes/formlander:latestDocker tag options
Section titled “Docker tag options”Formlander images are published for both AMD64 and ARM64 architectures on each release:
# Latest stable release (multi-arch manifest)docker pull karloscodes/formlander:latest
# Architecture-specific latest tagsdocker pull karloscodes/formlander:latest-amd64docker pull karloscodes/formlander:latest-arm64
# Specific version (multi-arch manifest)docker pull karloscodes/formlander:v1.0.0
# Architecture-specific version tagsdocker pull karloscodes/formlander:v1.0.0-amd64docker pull karloscodes/formlander:v1.0.0-arm64Note: Docker will automatically pull the correct architecture for your system when using the multi-arch tags (
latestor version without suffix).
3. Run the binary
Section titled “3. Run the binary”Option 1: Using environment variables
Section titled “Option 1: Using environment variables”- Download the latest release from GitHub Releases
- Extract and set required environment variables:
Terminal window export FORMLANDER_SESSION_SECRET=$(openssl rand -hex 32)export FORMLANDER_DATA_DIR=./storage - Run the binary:
Terminal window ./formlander
Option 2: Using a .env file
Section titled “Option 2: Using a .env file”- Download the latest release from GitHub Releases
- Create a
.envfile:Terminal window FORMLANDER_ENV=productionFORMLANDER_PORT=8080FORMLANDER_SESSION_SECRET=your-secret-hereFORMLANDER_DATA_DIR=./storage - Run the binary:
Terminal window ./formlander
The binary will automatically detect and load the .env file from the current directory.
4. Production deployment (recommended)
Section titled “4. Production deployment (recommended)”For production, use a reverse proxy like Cloudflare Tunnel, Nginx, or Caddy to add HTTPS and DDoS protection.
Cloudflare Tunnel (recommended)
Section titled “Cloudflare Tunnel (recommended)”The simplest way to expose Formlander with automatic HTTPS:
# Install cloudflaredcurl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflaredchmod +x cloudflared && sudo mv cloudflared /usr/local/bin/
# Authenticate and create tunnelcloudflared tunnel logincloudflared tunnel create formlander
# Configure tunnel (~/.cloudflared/config.yml)tunnel: <your-tunnel-id>credentials-file: /root/.cloudflared/<tunnel-id>.jsoningress: - hostname: forms.yourdomain.com service: http://localhost:8080 - service: http_status:404
# Route DNS and startcloudflared tunnel route dns formlander forms.yourdomain.comcloudflared service installsudo systemctl start cloudflaredNo firewall configuration needed. Your Formlander instance is now at https://forms.yourdomain.com.
Alternative: Nginx
Section titled “Alternative: Nginx”server { listen 443 ssl http2; server_name forms.yourdomain.com;
ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem;
location / { proxy_pass http://127.0.0.1:8080; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}Alternative: Caddy
Section titled “Alternative: Caddy”forms.yourdomain.com { reverse_proxy localhost:8080}Caddy automatically handles SSL certificates via Let’s Encrypt.
5. Background workers
Section titled “5. Background workers”Webhook and email deliveries run in the same process. Keep the container running so queued jobs continue.
6. Persistent storage
Section titled “6. Persistent storage”The storage/ directory contains everything Formlander needs to persist:
| Path | Contents |
|---|---|
storage/formlander.db | SQLite database (forms, submissions, settings) |
storage/uploads/ | Uploaded files from form submissions |
Docker volume is required. Without it, you lose all data when the container restarts:
# Always mount the storage volumedocker run -d \ -v $(pwd)/storage:/app/storage \ ...Storage sizing: Uploads are limited to 10MB per file. Plan your volume size based on expected submission volume.
7. Backups
Section titled “7. Backups”Back up the storage/ directory to preserve your database, uploads, and logs. To migrate, copy storage/ to the new host and restart.