--- title: "πŸ–₯️ Part 7: Single-Server Installation (Quick & All-in-One) on Debian 13" description: "Documentation for 7. Single Server Setup" --- *Welcome to the seventh installment of our "Debian 13 Clustering & Distribution" series. In the previous parts, we explored setting up a custom APT repository, compiling and packaging Telephony Server, Kamailio, and RTPEngine, and designing high-availability database and storage clusters. Now, we shift our focus to deployment. In this guide, we will walk through the single-server installation process of the Ring2All platform on Debian 13 (Trixie). This all-in-one deployment is ideal for small businesses, demonstrations, and development environments where all services run on a single machine. We will cover the automatic one-command script installation using the `softswitch-all` orchestrator meta-package, a detailed step-by-step manual installation path, system verification, Nginx reverse proxy setup, firewall configuration, SSL bootstrapping, resource optimization tuning, and backup strategies.* --- ## πŸ—οΈ Architecture Overview In a single-server deployment, all components of the Ring2All platform run on the same virtual or physical machine. Nginx acts as the front-facing reverse proxy, distributing requests to the various frontend static React apps, backend REST APIs, and ESL (Event Socket Library) monitoring services. PostgreSQL 17 handles the data store, while Telephony Server operates telephony services locally. ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SINGLE SERVER ARCHITECTURE β”‚ β”‚ (All-in-One Deployment) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ NGINX (Reverse Proxy) β”‚ β”‚ β”‚ β”‚ Port 80 / 443 (HTTP/S) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚Admin β”‚ β”‚Portal β”‚ β”‚Switchboardβ”‚ β”‚ API β”‚ β”‚ Monitoring β”‚ β”‚ β”‚ β”‚ Web β”‚ β”‚ Web β”‚ β”‚ Web β”‚ β”‚ :3001 β”‚ β”‚ API :3500 β”‚ β”‚ β”‚ β”‚/adminβ”‚ β”‚/portal β”‚ β”‚/switchboardβ”‚ β”‚ /api β”‚ β”‚ /monitoring β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ PostgreSQL 17 β”‚ β”‚ β”‚ β”‚ ss_admin | ss_telephony | ss_cdr | ss_cc | ss_ccr | ss_logs β”‚ β”‚ β”‚ β”‚ ss_switchboard | freeswitch Port 5432 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Telephony Server β”‚ β”‚ β”‚ β”‚ SIP UDP/TCP: 5060 | SIP TLS: 5061 | RTP: 16384-32768 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ Single Server: β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## πŸ–₯️ Server Requirements Before proceeding, ensure your server meets the following criteria for a standard single-server deployment: | Component | Minimum | Recommended | |-----------|---------|-------------| | **CPU** | 4 vCPU | 8 vCPU | | **RAM** | 8 GB | 16 GB | | **Storage** | 100 GB SSD | 250 GB SSD | | **OS** | Debian 13 (Trixie) | Debian 13 (Trixie) | | **Node.js** | 22.x LTS | 22.x LTS | | **PostgreSQL** | 17 | 17 | | **Concurrent Calls** | ~50 | ~100–150 | --- ## πŸ“¦ Package Suite (11 Packages) The platform is distributed as a suite of 10 functional packages plus 1 meta-package orchestrator: | Package | Role | Description | |---------|------|-------------| | `softswitch-all` | **AIO Meta-package** | Orchestrator package handling the installation order of the suite. | | `softswitch-db` | Database Schema | Database schemas, default migrations, and seed data. | | `softswitch-api` | REST API | REST API backend (Node.js, listening on Port 3001). | | `softswitch-monitoring-api` | Telemetry API | Real-time ESL telemetry & WebSocket server (Port 3500). | | `softswitch-admin` | Frontend Admin | Static React administration portal + authoritative Nginx configuration. | | `softswitch-portal` | Frontend Portal | Static React end-user self-service portal. | | `softswitch-switchboard` | Frontend Switchboard | Static React real-time operator console. | | `softswitch-telephony` | Telephony Config | Telephony Server configurations, dialplans, Lua scripts, and AI module. | | `softswitch-music` | Audio Assets | Default Music on Hold audio assets (WAV, multi-rate). | | `softswitch-voiceguide-emma` | Audio Prompts | English (US) system prompts for interactive voice response (IVR). | | `softswitch-voiceguide-paloma` | Audio Prompts | Spanish (US/LATAM) system prompts for IVR. | --- ## ⚑ Automatic Installation (Recommended) The recommended path is the automated script. Running it as `root` bootstraps system configurations and installs the `softswitch-all` meta-package, which installs the remaining suite in the correct dependency order. ```bash wget -O- https://repo.softswitchone.com/apt/install-softswitch.sh | bash ``` This installer executes the following steps automatically: 1. Configures system prerequisites and DNS settings. 2. Installs Node.js 22.x, PostgreSQL 17, and security packages (`fail2ban`, `nftables`, `openvpn`). 3. Registers the Ring2All APT repository components (`base`, `core`, `devel`, `extras`, `audios`). 4. Installs all 11 Softswitch packages in the correct dependency order. 5. Generates secure, random database credentials in `/etc/softswitch/db-credentials`. 6. Initializes all 8 databases, applies migrations, and seeds default records. 7. Deploys Nginx virtual host configurations and starts all system services. > [!NOTE] > **Default Access Credentials (First Login)** > - **URL**: `http:///admin` (redirects to HTTPS) > - **Email**: `admin@main.local` > - **Password**: *(leave blank to trigger the initial setup wizard)* ## πŸ” Verifying the Automatic Installation Once the automatic installation script completes, perform the following validation checks to ensure all core services are active and properly configured. ### 1. Check System Services Verify that all key components are active and running: ```bash systemctl status postgresql systemctl status freeswitch systemctl status softswitch-api systemctl status softswitch-monitoring-api systemctl status nginx ``` ### 2. Verify Database Connection Check that all 8 databases were created and successfully seeded: ```bash # View the generated database credentials cat /etc/softswitch/db-credentials # List all databases sudo -u postgres psql -c "\l" ``` *Expected databases: `ss_admin`, `ss_telephony`, `ss_cdr`, `ss_cc`, `ss_ccr`, `ss_logs`, `ss_switchboard`, and `freeswitch`.* ### 3. Check Telephony Core Status Ensure that the Telephony Server instance is running and has bound to local databases via ODBC: ```bash fs_cli # Within the Telephony Server CLI: sofia status ``` *Expected: The `internal` and `external` SIP profiles must show as `RUNNING`.* To exit the CLI, type: `/exit` ### 4. API Endpoints Health Check Validate the health check JSON responses from the backend services: ```bash # Main REST API curl -s http://127.0.0.1:3001/api/health # Monitoring / ESL WS API curl -s http://127.0.0.1:3500/health ``` --- ## πŸ”Œ Installing Optional Complements & Add-ons While the automated installer configures the core softswitch backend and includes Nginx and recommended voice guide audio assets (`softswitch-music`, `softswitch-voiceguide-emma`, and `softswitch-voiceguide-paloma`) out of the box, you can customize and expand your deployment with additional frontend web portals. ### 1. User Self-Service Portal (`softswitch-portal`) The User Portal allows end-users to manage their extensions, view personal call detail records (CDRs), configure call forwarding, and manage voicemails. ```bash apt-get install -y softswitch-portal ``` *The post-installation script automatically deploys the static files under `/var/www/softswitch/portal/`, registers the path within Nginx `/portal`, and reloads the web service.* ### 2. Operator Switchboard Console (`softswitch-switchboard`) The Switchboard is a real-time console designed for operators to monitor extension states, park calls, drag-and-drop transfers, and view queue statistics. ```bash apt-get install -y softswitch-switchboard ``` *The post-installation script automatically deploys the static files under `/var/www/softswitch/switchboard/`, registers the path within Nginx `/switchboard`, and reloads the web service.* --- ## 🌐 Nginx Web Server Configuration The Nginx configuration is fully automated. The `softswitch-admin` package deploys and activates a production-ready virtual host configuration file at `/etc/nginx/sites-available/softswitch` during setup. This automatic configuration handles: - Redirecting port 80 traffic to secure HTTPS on port 443. - Proxying REST API requests to the Node.js backend on port 3001 (`/api` and `/ws/`). - Proxying real-time ESL telemetry WebSockets to port 3500 (`/monitoring-api`). No manual configuration is necessary. Installing optional add-ons (`softswitch-portal` or `softswitch-switchboard`) will automatically update the Nginx configuration with the `/portal` and `/switchboard` virtual folders and trigger a clean reload. --- ## πŸ”’ Firewall Configuration The platform's firewall is configured and managed automatically during the initial script installation using `nftables` and `fail2ban`. The automated installer sets up all necessary rules to open HTTP/S web ports (80/443), SSH (22), SIP signaling (5060/5061), and media RTP stream port ranges (16384-32768) out of the box. No manual firewall rule modifications or external tools (such as UFW) are required. Dynamic security rules (such as automatic SIP brute-force blocking) are handled automatically by `fail2ban` interacting directly with `nftables` rules via the pre-installed `r2a-fail2ban` CLI. --- ## πŸ”‘ SSL Configuration (Let's Encrypt) To secure the HTTP interface and allow WebRTC connections (which strictly require secure contexts), configure Certbot: ```bash # Install Certbot and Nginx plugin apt-get install -y certbot python3-certbot-nginx # Obtain SSL Certificate (Replace pbx.example.com with your actual domain) certbot --nginx -d pbx.example.com # Verify automated renewal checks systemctl status certbot.timer ``` --- ## βš™οΈ Credentials & Privileged Settings ### 1. Database Credentials File This file is generated during the `softswitch-db` package configuration at `/etc/softswitch/db-credentials`: ```ini DB_USER=ss_db_user DB_PASSWORD= DB_HOST=127.0.0.1 DB_PORT=5432 ``` *Do not share this file. It is read by Telephony Server via `/etc/odbc.ini` and by the REST API via `/etc/softswitch/api.env`.* ### 2. Sudoers Configuration The API service requires elevated permissions to manage systemd, nftables, and fail2ban rules dynamically. A custom sudoers file is configured at `/etc/sudoers.d/softswitch`: ``` softswitch ALL=(ALL) NOPASSWD: /usr/sbin/r2a-nftables softswitch ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client softswitch ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart fail2ban softswitch ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nftables ``` Ensure permissions are locked down: ```bash chmod 440 /etc/sudoers.d/softswitch ``` ### 3. Grant Database Permissions Ensure the application database user has full access to the Telephony Server registry schema: ```bash sudo -u postgres psql -d freeswitch -c \ "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ss_db_user;" sudo -u postgres psql -d freeswitch -c \ "GRANT USAGE ON SCHEMA public TO ss_db_user;" ``` --- ## ⚑ Resource Optimization (Single Server) Because all platform components share a single operating system instance, tuning service parameters is essential to prevent resources from exhausting during peak call hours. ### 1. PostgreSQL 17 Optimization Open `/etc/postgresql/17/main/postgresql.conf` and adjust memory boundaries based on total RAM: ```ini # Memory allocations (Recommended for a 16 GB RAM server) shared_buffers = 4GB # 25% of overall memory effective_cache_size = 12GB # 75% of overall memory work_mem = 64MB maintenance_work_mem = 1GB # Session management max_connections = 300 # Write-Ahead Log (WAL) performance wal_buffers = 64MB checkpoint_completion_target = 0.9 ``` Restart PostgreSQL to apply changes: ```bash systemctl restart postgresql ``` ### 2. Telephony Server Capacity Limits Open `/etc/freeswitch/autoload_configs/switch.conf.xml` and scale concurrent session counts to matching boundaries: ```xml ``` Reload configurations dynamically: ```bash fs_cli -x "reloadxml" ``` --- ## πŸ’Ύ Backup Strategy Set up a daily automated backup script at `/opt/softswitch-backup.sh` to prevent data loss: ```bash #!/bin/bash # Softswitch Single Server Backup Script BACKUP_DIR="/var/backups/softswitch" DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=7 mkdir -p "$BACKUP_DIR" # Backup all platform databases for db in ss_admin ss_telephony ss_cdr ss_cc ss_ccr ss_logs ss_switchboard freeswitch; do sudo -u postgres pg_dump "$db" | gzip > "$BACKUP_DIR/${db}_${DATE}.sql.gz" echo "βœ… Backed up database: $db" done # Backup config directories tar -czf "$BACKUP_DIR/freeswitch_config_${DATE}.tar.gz" /etc/freeswitch # Backup local recordings and web uploads if [ -d "/var/lib/freeswitch/recordings" ]; then tar -czf "$BACKUP_DIR/recordings_${DATE}.tar.gz" /var/lib/freeswitch/recordings fi if [ -d "/var/www/softswitch/uploads" ]; then tar -czf "$BACKUP_DIR/uploads_${DATE}.tar.gz" /var/www/softswitch/uploads fi # Backup configuration env files cp /etc/softswitch/db-credentials "$BACKUP_DIR/db-credentials_${DATE}" cp /etc/softswitch/api.env "$BACKUP_DIR/api.env_${DATE}" # Prune old archives find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete echo "βœ… Backup process finished. Retention check completed." ``` Apply executable permissions and configure a root cron job: ```bash chmod +x /opt/softswitch-backup.sh # Run every night at 2:00 AM echo "0 2 * * * root /opt/softswitch-backup.sh >> /var/log/softswitch-backup.log 2>&1" >> /etc/crontab ``` --- ## πŸ” Troubleshooting ### 1. The API Service fails to start (exit code 226/NAMESPACE) - **Cause**: Nginx is missing. The systemd unit file is configured to secure the directory `/etc/nginx`. If this path does not exist, systemd will fail to mount the system namespaces. - **Fix**: Install Nginx, and reinstall the API package: ```bash apt-get install -y nginx apt-get install --reinstall softswitch-api ``` ### 2. Telephony Server fails on start (ODBC / CORE DATABASE INITIALIZATION FAILURE) - **Cause**: Database access credentials are misaligned in `/etc/odbc.ini` or `/etc/softswitch/db-credentials`. - **Fix**: Test database logging with `isql`: ```bash isql -v ss_telephony ss_db_user $(grep DB_PASSWORD /etc/softswitch/db-credentials | cut -d= -f2) ``` Ensure `/etc/odbc.ini` points to `127.0.0.1` and matches the generated credentials password. --- *In the next and final installment of our series, **Part 8: Enterprise-Grade Distributed Deployment**, we will scale this architecture by separating all components onto dedicated servers, configuring Patroni database replication, mounting a distributed GlusterFS file cluster, and setting up local HAProxy load balancing for seamless redundancy.*