Storage Groups
Overview
The Storage Server Groups page allows administrators to manage logical groupings of storage servers for distributing and load-balancing video content. Groups provide a way to organize multiple storage servers by content type, geographic region, or performance tier.
Key capabilities include:
- Create and manage storage server groups
- Configure load balancing strategies
- Set content type restrictions (videos, images, thumbnails)
- Enable automatic content synchronization
- View group statistics (servers, storage, video counts)
- Set group priority for content distribution
System Requirements
PHP Requirements
PHP Extensions Required
mysqli- Database connectivityjson- JSON encoding/decoding for geo rulessession- Session management for CSRF protection
PHP Settings
session.autostart = Off
date.timezone = Your/Timezone
Installation Requirements
Database Tables
-- Storage Server Groups Table
CREATE TABLE IF NOT EXISTS tblStorageServerGroups (
groupid INT(11) NOT NULL AUTOINCREMENT,
groupname VARCHAR(100) NOT NULL,
groupdescription TEXT DEFAULT NULL,
contenttype ENUM('videos', 'images', 'both', 'thumbnails') DEFAULT 'both',
loadbalancingtype ENUM('roundrobin', 'leastspace', 'weighted', 'geobased') DEFAULT 'leastspace',
georules JSON DEFAULT NULL COMMENT 'Geography-based distribution rules',
isactive TINYINT(1) DEFAULT 1,
autosyncnewcontent TINYINT(1) DEFAULT 1,
priority INT(11) DEFAULT 5 COMMENT '1-10, higher = preferred',
createdat DATETIME DEFAULT CURRENTTIMESTAMP,
updatedat DATETIME DEFAULT CURRENTTIMESTAMP ON UPDATE CURRENTTIMESTAMP,
PRIMARY KEY (groupid),
KEY idxcontenttype (contenttype),
KEY idxisactive (isactive),
KEY idxpriority (priority)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4unicodeci;
-- Storage Servers Table (referenced)
CREATE TABLE IF NOT EXISTS tblStorageServers (
serverid INT(11) NOT NULL AUTOINCREMENT,
groupid INT(11) NOT NULL,
servername VARCHAR(100) NOT NULL,
servertype ENUM('local', 'ftp', 'sftp', 'bunnycdn', 'vultr', 'digitaloceanspaces', 'cloudflarer2', 'keycdn', 'cdn77') NOT NULL,
connectionconfig JSON DEFAULT NULL,
baseurl VARCHAR(255) DEFAULT NULL,
maxstoragegb DECIMAL(10,2) DEFAULT 0,
currentusagegb DECIMAL(10,2) DEFAULT 0,
status ENUM('enabled', 'disabled') DEFAULT 'enabled',
isactive TINYINT(1) DEFAULT 1,
healthstatus ENUM('healthy', 'warning', 'critical', 'unknown') DEFAULT 'unknown',
lasthealthcheck DATETIME DEFAULT NULL,
controlscriptenabled TINYINT(1) DEFAULT 0,
controlscripturl VARCHAR(500) DEFAULT NULL,
nginxsecretkey VARCHAR(255) DEFAULT NULL,
createdat DATETIME DEFAULT CURRENTTIMESTAMP,
updatedat DATETIME DEFAULT CURRENTTIMESTAMP ON UPDATE CURRENTTIMESTAMP,
PRIMARY KEY (serverid),
KEY idxgroupid (groupid),
KEY idxstatus (status),
CONSTRAINT fkservergroup FOREIGN KEY (groupid)
REFERENCES tblStorageServerGroups (groupid) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4unicodeci;
Content Type Reference
Load Balancing Types
Config Variables
From ct/dat/config.inc.php:
$dbhost,$dbuser,$dbpasswd,$db- Database connection
File Dependencies
ct/admin/adminauth.php- Admin authenticationct/dat/config.inc.php- Configurationct/includes/header.php- Admin headerct/includes/annotateftr.php- Admin footer- Font Awesome 6+ - Icon library
Features & UI Elements
Page Header
[Screenshot: storage-groups-header]
The page header displays:
- Title: "Storage Server Groups"
- Icon:
fa-layer-group - Breadcrumb: Dashboard / Storage / Groups
- Subtitle: "Manage storage server groups for distributing and load-balancing video content"
Alert Messages
[Screenshot: storage-groups-alerts]
Success and error alerts for:
- Group created successfully
- Group updated successfully
- Group deleted successfully
- Deletion blocked (has servers)
- Database errors
Action Card
[Screenshot: storage-groups-action-card]
A card containing the primary action:
- Create New Storage Group button (green)
Groups Table
[Screenshot: storage-groups-table]
The main data table displaying all groups:
Status Indicators:
Action Buttons:
Create/Edit Modal
[Screenshot: storage-groups-modal]
A modal form for creating or editing groups:
Form Fields:
Content Type Options:
- Videos & Images (both)
- Videos Only
- Images Only
- Thumbnails Only
Load Balancing Options:
- Least Space Used
- Round Robin
- Weighted
- Geography Based
Geography Rules JSON
When "Geography Based" is selected, a JSON configuration field appears:
{"US": 80, "EU": 20}
This example routes 80% of traffic to US servers and 20% to EU servers.
Supported Region Codes:
- US - United States
- EU - Europe
- AS - Asia
- SA - South America
- AF - Africa
- OC - Oceania
Step-by-Step Usage
Creating a Storage Group
- Navigate to Admin Panel → Storage → Groups
- Click Create New Storage Group button
- Fill in the form:
- Group Name: Enter a descriptive name (e.g., "Primary Videos CDN")
- Description: Optional description of the group's purpose
- Content Type: Select what content this group will store
- Load Balancing Type: Choose distribution strategy
- Priority: Set 1-10 (higher = more preferred)
- Configure options:
- Check Active to enable immediately
- Check Auto-sync New Content for automatic uploads
- Click Save Group
Editing a Storage Group
- Find the group in the table
- Click the Edit button (pencil icon)
- Modify the desired fields
- Click Save Group
Deleting a Storage Group
- Ensure the group has 0 servers (check "Servers" column)
- If servers exist, click "Servers" and delete them first
- Click the Delete button (trash icon)
- Confirm the deletion
Viewing Group Servers
Find the group in the tableClick the Servers button (server icon)
- You'll be redirected to storageservers.php filtered by group
Setting Up Geography-Based Load Balancing
- Create or edit a storage group
- Set Load Balancing Type to "Geography Based"
- Enter Geography Rules in JSON format:
{
"US": 60,
"EU": 30,
"AS": 10
}
- Ensure percentages add up to 100
- Click Save Group
Best Practices
Group Organization Strategies
By Content Type:
By Performance Tier:
By Geographic Region:
Priority Settings
Load Balancing Selection
Troubleshooting
Common Issues
Tables Not Found Error
Cause: Storage tables haven't been created
Solutions:
- Run the SQL schema file:
mysql -u youruser -p yourdatabase < storageserverschema.sql
- Execute CREATE TABLE statements via phpMyAdmin
- Check database connection credentials
Cannot Delete Group
Cause: Group has servers assigned
Solutions:
- Check the "Servers" column for count > 0
- Click "Servers" button to view assigned servers
- Delete each server from the group
- Return and delete the group
Query Error on Page Load
Cause: Database connection or schema issue
Solutions:
- Verify database connection in config.inc.php
- Check if all required columns exist
- Verify foreign key constraints
- Check MySQL error logs
Geography Rules Not Working
Cause: Invalid JSON or misconfigured servers
Solutions:
- Validate JSON syntax:
{"US": 80, "EU": 20}
- Ensure percentages total 100
- Verify servers are tagged with regions
- Check server health status
Database Issues
Group Statistics Incorrect
Cause: Aggregation query issues
Solution:
-- Recalculate group statistics
SELECT
g.groupid,
g.groupname,
COUNT(DISTINCT s.serverid) as servercount,
SUM(s.maxstoragegb) as totalstorage,
SUM(s.currentusagegb) as usedstorage,
COUNT(DISTINCT v.videoid) as videocount
FROM tblStorageServerGroups g
LEFT JOIN tblStorageServers s ON g.groupid = s.groupid AND s.isactive = 1
LEFT JOIN tblVideos v ON g.groupid = v.storagegroupid
GROUP BY g.groupid;
Foreign Key Constraint Errors
Cause: Attempting to delete group with servers
Solution:
-- Check for dependent servers
SELECT serverid, servername
FROM tblStorageServers
WHERE groupid = {groupid};
-- Delete servers first (if intended)
DELETE FROM tblStorageServers WHERE groupid = {groupid};
-- Then delete group
DELETE FROM tblStorageServerGroups WHERE groupid = {groupid};
Security Considerations
Access Control
- Only administrators can access this page
- Admin authentication required via adminauth.php
- Session validation on every request
Input Validation
- All inputs sanitized with mysqlirealescapestring
- Prepared statements used for database operations
- Integer values validated with intval()
JSON Validation
Recommended validation:
$georules = jsondecode($POST['georules'], true);
if (jsonlasterror() !== JSONERRORNONE) {
$error = "Invalid JSON in geography rules";
}
Translatable Strings
{
"storagegroupstitle": "Storage Server Groups",
"storagegroupsbreadcrumb": "Dashboard / Storage / Groups",
"storagegroupssubtitle": "Manage storage server groups for distributing and load-balancing video content",
"storagegroupscreatebtn": "Create New Storage Group",
"storagegroupstablename": "Group Name",
"storagegroupstablecontenttype": "Content Type",
"storagegroupstableloadbalancing": "Load Balancing",
"storagegroupstableservers": "Servers",
"storagegroupstablestorage": "Storage",
"storagegroupstablevideos": "Videos",
"storagegroupstablestatus": "Status",
"storagegroupstableactions": "Actions",
"storagegroupsmodalcreatetitle": "Create Storage Group",
"storagegroupsmodaledittitle": "Edit Storage Group",
"storagegroupsformname": "Group Name",
"storagegroupsformdescription": "Description",
"storagegroupsformcontenttype": "Content Type",
"storagegroupsformloadbalancing": "Load Balancing Type",
"storagegroupsformgeorules": "Geography Rules (JSON)",
"storagegroupsformpriority": "Priority (1-10)",
"storagegroupsformactive": "Active",
"storagegroupsformautosync": "Auto-sync New Content",
"storagegroupscontentboth": "Videos & Images",
"storagegroupscontentvideos": "Videos Only",
"storagegroupscontentimages": "Images Only",
"storagegroupscontentthumbnails": "Thumbnails Only",
"storagegroupslbleastspace": "Least Space Used",
"storagegroupslbroundrobin": "Round Robin",
"storagegroupslbweighted": "Weighted",
"storagegroupslbgeobased": "Geography Based",
"storagegroupsgeoruleshint": "Example: {\"US\": 80, \"EU\": 20}",
"storagegroupsbtncancel": "Cancel",
"storagegroupsbtnsave": "Save Group",
"storagegroupsbtnedit": "Edit",
"storagegroupsbtnservers": "Servers",
"storagegroupsbtndelete": "Delete",
"storagegroupsstatusactive": "Active",
"storagegroupsstatusinactive": "Inactive",
"storagegroupsserverscount": "{count} server(s)",
"storagegroupsstorageused": "{used} / {total} GB ({percent}% used)",
"storagegroupssuccesscreated": "Storage group created successfully!",
"storagegroupssuccessupdated": "Storage group updated successfully!",
"storagegroupssuccessdeleted": "Storage group deleted successfully!",
"storagegroupserrorhasservers": "Cannot delete group with existing servers. Remove servers first.",
"storagegroupsconfirmdelete": "Are you sure you want to delete this storage group?"
}
Related Documentation
- Storage Servers - Server configuration within groups
- CDN Cost Calculator - CDN pricing comparison
- Video Processing - Video processor CDN integration