On-Premise Installation Guide
Step-by-step guide to installing Captivo on your own server. With a Docker-ready Linux server, the entire process takes under 30 minutes.
1. Prerequisites
Make sure the following are installed on your server:
Quick Docker install (Ubuntu/Debian):
curl -fsSL https://get.docker.com | sh
Required Ports
| Port | Protocol | Purpose |
|---|---|---|
| 3000 | TCP | Management panel (HTTP without TLS) |
| 80 / 443 | TCP | Caddy when TLS is enabled |
| 1812 | UDP | RADIUS authentication |
| 1813 | UDP | RADIUS accounting |
2. Installation (Single Command)
2.1 Get the Installation Files
The install package (docker/ folder) is provided to you. Place all files in the same directory:
docker/ ├── docker-compose.onprem.yml ├── onprem/ │ ├── install.sh │ ├── Caddyfile │ ├── backup.sh │ └── .env.onprem.example
2.2 Run the Install Script
chmod +x docker/onprem/install.sh ./docker/onprem/install.sh
The script:
- Checks for docker and openssl dependencies.
- If docker/.env.onprem does not exist, asks for your server address and auto-generates all secrets (POSTGRES_PASSWORD, AUTH_SECRET, DATA_ENCRYPTION_KEY, etc.) with openssl rand.
- Starts all services with docker compose up -d.
- Prints the panel URL when done.
Example output:
✓ Secrets generated (.env.onprem)
✓ Starting services...
✔ Container captivo-postgres Started
✔ Container captivo-migrator Exited
✔ Container captivo-radius Started
✔ Container captivo-web Started
✓ Installation complete!
Panel: http://localhost:3000
3. First Launch — Setup Wizard
The first time you open the panel (http://<server-ip>:3000), you will be automatically redirected to the /setup wizard. It has 9 steps:
Admin Account
Set the super-admin email and password.
Organisation
Company/organisation name, logo, language preference.
Portal Design
Captive portal appearance (background, colours, heading).
RADIUS
RADIUS shared secret and NAS configuration.
Login Methods
Social login, SMS OTP, guest form options.
SMS
SMS provider (your own account: Netgsm, Twilio, etc.) — optional.
SMTP
Outbound email server (for notifications) — optional.
Licence
Upload a .lic file or start the 15-day free trial.
Done
Setup summary and sign in to the panel.
4. TLS / HTTPS (Recommended for Production)
The default http://localhost:3000 is for local testing only. HTTPS is required in production.
4.1 Configure Your Domain
Edit docker/.env.onprem:
NEXTAUTH_URL=https://wifi.company.com SITE_DOMAIN=wifi.company.com
4.2 Start Caddy with the TLS Profile
docker compose -f docker/docker-compose.onprem.yml \ --profile tls \ --env-file docker/.env.onprem \ up -d
5. RADIUS — Connecting Your NAS
The FreeRADIUS container starts automatically and listens on UDP 1812/1813. Configure the following on your NAS or gateway device:
| Setting | Value |
|---|---|
| RADIUS server IP | This server's LAN IP address |
| Authentication port | 1812 UDP |
| Accounting port | 1813 UDP |
| RADIUS method | PAP |
| Shared secret | The value generated in wizard Step 4 or shown at Settings → RADIUS |
Supported NAS/gateway models: pfSense, OPNsense, MikroTik, FortiGate, Cisco Meraki, and other devices supporting PAP/CHAP.
6. Licence
A 15-day free trial starts automatically after installation with all features enabled.
Once you have your licence file (.lic) from your vendor:
- Go to Settings → Licence in the panel.
- Upload the .lic file.
- Licence details (expiry date, quota) are displayed on screen.
When the trial or licence expires, the system winds down gradually: a warning first, then read-only mode (new guest registration stops, existing data is visible), and finally panel access is restricted until the licence is renewed.
7. Backups
Database Backup
docker/onprem/backup.sh runs pg_dump from PostgreSQL, compresses the output and stores it (7-day rotation).
Run manually:
POSTGRES_USER=captivo BACKUP_DIR=/opt/captivo-backups \ ./docker/onprem/backup.sh
Schedule with cron (daily at 03:15):
15 3 * * * POSTGRES_USER=captivo BACKUP_DIR=/opt/captivo-backups \ /opt/captivo/docker/onprem/backup.sh >> /var/log/captivo-backup.log 2>&1
8. Air-Gapped (Offline) Installation
For networks with no internet access, Docker images can be pre-packaged.
Bundle on an internet-connected machine
# Bundle the latest release ./scripts/onprem/build-offline-bundle.sh # For a specific version: ./scripts/onprem/build-offline-bundle.sh 1.0.0
Output: captivo-onprem-1.0.0.tar (includes web, RADIUS, postgres and caddy images)
Install on the target machine
# Load images into Docker docker load -i captivo-onprem-1.0.0.tar # Run the install script (no internet needed) ./docker/onprem/install.sh
9. Troubleshooting
Panel won't open
- •docker compose … ps — are all containers in the Up state?
- •Did the migrator service complete successfully (Exited (0))?
- •Is port 3000 open in your firewall?
- •Logs: docker compose … logs web
RADIUS connection error (guests can't log in)
- •Is the RADIUS server IP on the NAS correct? (This server's LAN IP)
- •Is UDP 1812/1813 reachable from the NAS?
- •Is the shared secret exactly the same on the NAS and in Captivo?
- •Is captivo-radius running? (docker logs captivo-radius)
SMS not arriving
- •Were SMS provider credentials entered in wizard Step 6?
- •Is this server's IP in the NAS walled garden list?
Email notifications not sent
- •Were SMTP settings configured in wizard Step 7?
- •Verify SMTP port and password in the container logs.
General log inspection
# All service logs (last 50 lines) docker compose -f docker/docker-compose.onprem.yml \ --env-file docker/.env.onprem \ logs --tail=50 # FreeRADIUS logs docker logs captivo-radius
Need help? Contact our support team.