Ctrl K
ring2all.com

πŸ–₯️ Part 7: Single-Server Installation (Quick & All-in-One) on Debian 13

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 FreeSWITCH, 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 FreeSWITCH operates telephony services locally.

Plaintext
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          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              β”‚     β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                    β”‚                                             β”‚
β”‚                                    β–Ό                                             β”‚
β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚   β”‚                         FreeSWITCH                                     β”‚     β”‚
β”‚   β”‚         SIP UDP/TCP: 5060 | SIP TLS: 5061 | RTP: 16384-32768         β”‚     β”‚
β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                                                  β”‚
β”‚                         Single Server: <SERVER_IP>                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


πŸ–₯️ Server Requirements

Before proceeding, ensure your server meets the following criteria for a standard single-server deployment:

ComponentMinimumRecommended
CPU4 vCPU8 vCPU
RAM8 GB16 GB
Storage100 GB SSD250 GB SSD
OSDebian 13 (Trixie)Debian 13 (Trixie)
Node.js22.x LTS22.x LTS
PostgreSQL1717
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:

PackageRoleDescription
softswitch-allAIO Meta-packageOrchestrator package handling the installation order of the suite.
softswitch-dbDatabase SchemaDatabase schemas, default migrations, and seed data.
softswitch-apiREST APIREST API backend (Node.js, listening on Port 3001).
softswitch-monitoring-apiTelemetry APIReal-time ESL telemetry & WebSocket server (Port 3500).
softswitch-adminFrontend AdminStatic React administration portal + authoritative Nginx configuration.
softswitch-portalFrontend PortalStatic React end-user self-service portal.
softswitch-switchboardFrontend SwitchboardStatic React real-time operator console.
softswitch-telephonyTelephony ConfigFreeSWITCH configurations, dialplans, Lua scripts, and AI module.
softswitch-musicAudio AssetsDefault Music on Hold audio assets (WAV, multi-rate).
softswitch-voiceguide-emmaAudio PromptsEnglish (US) system prompts for interactive voice response (IVR).
softswitch-voiceguide-palomaAudio PromptsSpanish (US/LATAM) system prompts for IVR.
---

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 FreeSWITCH Core Status

Ensure that the FreeSWITCH instance is running and has bound to local databases via ODBC:

Bash
fs_cli

# Within the FreeSWITCH 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=<RANDOM_GENERATED_PASSWORD>
DB_HOST=127.0.0.1
DB_PORT=5432

Do not share this file. It is read by FreeSWITCH 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:

Plaintext
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 FreeSWITCH 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. FreeSWITCH Capacity Limits

Open /etc/freeswitch/autoload_configs/switch.conf.xml and scale concurrent session counts to matching boundaries:

Xml
<configuration name="switch.conf">
  <settings>
    <!-- Adjust maximum concurrent call threads based on CPU capabilities -->
    <param name="max-sessions"       value="200"/>
    <param name="sessions-per-second" value="30"/>

    <!-- Restrict RTP ports to prevent socket exhaustion -->
    <param name="rtp-start-port" value="16384"/>
    <param name="rtp-end-port"   value="32768"/>
  </settings>
</configuration>

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. FreeSWITCH 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.
AI Assistant

πŸ‘‹ Hello! I'm your Ring2All documentation assistant. I can help you find information about configuring and using the Ring2All PBX platform.

How can I help you today?