Administrator Guide
Advanced configuration and administrative tasks for TheiaCast
Table of Contents
User Management
Creating Users
TheiaCast supports multiple administrator accounts.
Creating a New User:
- Navigate to Users in the left sidebar (👥 Users)
- Click "Create User"
- Fill in user details:
- Username (required)
- Email (optional)
- Display Name (optional)
- Password (minimum 8 characters)
- Click "Create User"
[Screenshot: User Management page with user list and Create User button]
Note: All users currently have the same permissions (full access). Role-based access control is planned for a future release.
Editing User Details
- Navigate to Users in the left sidebar (👥 Users)
- Find the user in the list
- Click "Edit"
- Modify details (username, email, display name)
- Click "Save"
[Screenshot: Edit user modal with fields]
Deleting Users
- Navigate to Users in the left sidebar (👥 Users)
- Find the user in the list
- Click "Delete"
- Confirm deletion
Warning: You cannot delete yourself.
Password Reset
For Your Own Account:
Users can change their own password using the /auth/change-password API endpoint.
For Other Users:
Admins can edit users and set new passwords via the Edit User modal.
System Settings
Access system settings by navigating to ⚙️ Settings in the left sidebar.
[Screenshot: Settings page with all sections]
General Settings
System Name:
- Customize the application name shown in the dashboard
- Default: "TheiaCast"
Time Zone:
- Set the server time zone for accurate scheduling
- Affects all time window calculations
- Individual devices can override this with their own IANA time zone — see the User Guide, Scheduling and Time Zones
Date Format:
Choose date display format (MM/DD/YYYY, DD/MM/YYYY, YYYY-MM-DD)
Language:
Select interface language (currently English only)
Display Settings
Default Playlist Duration:
- Default duration (in seconds) for new playlist items
- Applied when adding content to playlists
- Can be overridden per item
Screenshot Interval:
- How often devices should capture screenshots (in minutes)
- Default: 5 minutes
- Minimum: 1 minute
- Lower values increase server storage usage
Health Report Interval:
- How often devices should report health metrics (in seconds)
- Default: 60 seconds
- Minimum: 10 seconds
- Lower values increase network traffic
Broadcast Settings
Default Broadcast Duration:
- Default duration for broadcast messages (in seconds)
- Default: 30 seconds
Broadcast Priority:
- Whether broadcasts should interrupt current content immediately
- Default: Enabled
Advanced Settings
Enable Debug Logging:
- Enable detailed logging for troubleshooting
- Warning: Creates large log files
API Rate Limiting:
- Maximum API requests per minute per client
- Default: 100
- Prevents abuse
WebSocket Ping Interval:
- How often to ping clients to check connection (in seconds)
- Default: 30 seconds
Email & Alerts
Configure outbound email and device-offline notifications under ⚙️ Settings → Email & Alerts. TheiaCast sends mail only for alerts you enable here — there is no other outbound email.
Device Offline Alerts
Recipients:
One or more email addresses that receive offline notifications.
Offline Threshold:
- How long a device must be silent before an alert is sent
- Acts as a debounce — brief reconnects never alert
- One email per outage; the device is not re-alerted until it recovers and drops again
Alert state is held in memory. After a backend restart every device looks offline until it reconnects; the threshold suppresses that startup burst rather than emailing about it. If a send fails, the outage is not marked as alerted — it retries on the next check.
Choosing a Send Method
Three transports are available. All secrets (SMTP passwords, OAuth client secrets) are encrypted at rest and never returned by the API — the settings form shows only whether a secret is stored, and leaving the field on its placeholder keeps the existing value.
1. SMTP (password auth):
- Provider presets fill host, port, and security for Gmail, Google Workspace, Microsoft 365, Outlook.com, Yahoo, iCloud, Zoho, Fastmail, and relays (SendGrid, Mailgun, Postmark, SES, Brevo)
- Most mailbox providers no longer allow plain password SMTP: Gmail needs a 16-character App Password; Microsoft 365 needs SMTP AUTH enabled per mailbox; Google Workspace often allows neither. Each preset states its own requirement.
- Dedicated relay services are unaffected by these restrictions
2. SMTP with OAuth 2.0:
- App-only (client-credentials) authentication — no interactive sign-in, nothing to re-authorize when a token lapses
- Microsoft 365: Entra app with the
SMTP.SendAsApppermission, plus an Exchange service principal granted mailbox access (New-ServicePrincipal/Add-MailboxPermission) - Google Workspace: service account with domain-wide delegation for
https://mail.google.com/, impersonating the sending mailbox - Tokens are cached in memory, dropped when credentials change, and never written to disk
- Access is scoped to one mailbox by
Add-MailboxPermission, which makes this the tightest option
3. Microsoft Graph (recommended for Microsoft 365):
- Uses
POST /users/{mailbox}/sendMailwith theMail.Sendapplication permission - No SMTP AUTH, no Exchange PowerShell service-principal setup, and it works where outbound port 587 is blocked — setup is two Entra steps
- Use a licence-free shared mailbox as the sender identity (e.g.
[email protected])
Security trade-off
By default Mail.Send lets the app send as any mailbox in the tenant. Scope it with New-ApplicationAccessPolicy targeting a mail-enabled security group (with your shared mailbox as a member — a shared mailbox address is not a valid policy scope on its own). Verify with Test-ApplicationAccessPolicy against both an allowed and a denied mailbox. Policy changes can take up to 24 hours to apply, so a 403 immediately after creating one is usually propagation, not misconfiguration.
Testing
Use the Send Test Email button after saving. Failures are reported with the specific fix (App Password required, basic auth disabled, missing service principal / mailbox permission, wrong tenant or client, port or security mismatch, DNS/firewall) rather than a raw server response.
Branding Customization
Branding customization is available on paid tiers only.
Customizing Logo
- Navigate to Settings → Branding
- Click "Upload Logo"
- Select image file:
- Supported formats: PNG, SVG (recommended), JPG
- Recommended size: 200x50 pixels
- Maximum file size: 2MB
- Click "Save"
[Screenshot: Branding section with logo upload]
Your logo will appear:
- In the top-left corner of the dashboard
- On the login page
- In device client displays (if configured)
Customizing Colors
- Navigate to Settings → Branding
- Select "Custom Colors"
- Choose colors:
- Primary color (buttons, links)
- Secondary color (highlights)
- Accent color (notifications)
- Preview changes in real-time
- Click "Save"
[Screenshot: Color picker interface with preview]
Custom Login Message
- Navigate to Settings → Branding
- Enter custom message in "Login Message" field
- Click "Save"
Displayed below the login form. Useful for:
- Welcome messages
- Company policies
- Support contact information
SSL Certificate Management
TheiaCast supports custom SSL certificates for HTTPS connections.
Uploading SSL Certificate
Prerequisites:
- SSL certificate file (.crt or .pem)
- Private key file (.key)
- Optional: Certificate chain/intermediate certificates
Steps:
- Navigate to Settings → SSL
- Click "Upload Certificate"
- Select files:
- Certificate file
- Private key file
- Chain file (optional)
- Enter private key password (if encrypted)
- Click "Upload and Apply"
[Screenshot: SSL certificate upload form]
The server will restart to apply the new certificate (approximately 10 seconds of downtime).
Certificate Status
The SSL section shows:
- Current certificate: Domain name and issuer
- Expiration date: When certificate expires
- Days remaining: Visual indicator (red if <30 days)
[Screenshot: SSL status showing certificate details]
Let's Encrypt Integration (Coming Soon)
Automatic SSL certificate generation and renewal via Let's Encrypt will be available in a future update.
License Management
License Tiers
TheiaCast offers multiple licensing tiers:
| Feature | Free | Basic | Professional | Enterprise |
|---|---|---|---|---|
| Devices | Up to 3 | Up to 10 | Up to 50 | Unlimited |
| Users | 1 | 3 | 10 | Unlimited |
| Branding | ❌ | ✅ | ✅ | ✅ |
| SSL Upload | ❌ | ✅ | ✅ | ✅ |
| Advanced Scheduling | ✅ | ✅ | ✅ | ✅ |
| Broadcasting | ✅ | ✅ | ✅ | ✅ |
| Remote Control | ✅ | ✅ | ✅ | ✅ |
| Support | Community | Priority Email | Phone + Email |
Viewing Current License
- Navigate to Settings → License
- View license details:
- Current tier
- Licensed devices
- Licensed users
- Expiration date
- License key (masked)
[Screenshot: License information panel]
Upgrading License
- Navigate to Settings → License
- Click "Upgrade"
- Select desired tier
- Complete purchase (external link)
- Enter license key received via email
- Click "Activate"
[Screenshot: License activation modal]
License Expiration
When a license expires:
- System reverts to Free tier limitations
- Excess devices become inactive (oldest devices first)
- Excess users cannot log in (last created users first)
- Branding customization is disabled
- You have 30 days to renew before data cleanup
Email notifications are sent at:
- 30 days before expiration
- 7 days before expiration
- On expiration day
Database Management
Database Configuration
TheiaCast uses PostgreSQL as its database backend.
Connection String:
Located in docker-compose.yml (Docker) or appsettings.json (manual installation):
ConnectionStrings__Default=Host=postgres;Port=5432;Database=theiacast;Username=postgres;Password=your-password
Viewing Database Size
- SSH into the server
- Run command:
docker exec -it theiacast-postgres psql -U postgres -d theiacast -c "SELECT pg_size_pretty(pg_database_size('theiacast'));"Database Maintenance
Automatic Maintenance:
- Entity Framework Core handles schema migrations automatically on startup
- No manual migration steps required for updates
Manual Vacuum (Performance):
docker exec -it theiacast-postgres psql -U postgres -d theiacast -c "VACUUM ANALYZE;"
Run this monthly to optimize database performance.
Cleaning Old Data
Screenshots:
Screenshots are automatically cleaned up based on retention policy (default: 30 days).
To change retention:
- Navigate to Settings → Advanced
- Set "Screenshot Retention Days"
- Click "Save"
Device Logs:
Device logs are retained indefinitely. To clean old logs:
# Delete logs older than 90 days docker exec -it theiacast-postgres psql -U postgres -d theiacast -c "DELETE FROM device_logs WHERE timestamp < NOW() - INTERVAL '90 days';"
Security Best Practices
Password Policies
Enforce Strong Passwords:
- Navigate to Settings → Security
- Enable "Enforce Password Complexity"
- Set requirements:
- Minimum length (default: 8)
- Require uppercase
- Require numbers
- Require special characters
- Click "Save"
Multi-Factor Authentication (MFA)
Enabling MFA for Your Account:
MFA can be enabled using the following API endpoints:
POST /auth/mfa/setup- Get QR code- Scan QR code with authenticator app (Google Authenticator, Authy, etc.)
POST /auth/mfa/enable- Confirm with verification code
Disabling MFA:
POST /auth/mfa/disable - Disable MFA for current user
Note: UI for MFA management is available in the settings interface.
Device Token Security
Token Rotation:
Device tokens should be rotated periodically for security.
- Navigate to Devices
- Flip device card
- Click "Rotate Token"
- Copy new token
- Update device client
.envfile - Restart device client
Auto-Rotation Policy (Coming Soon): Automatic token rotation every 90 days.
Network Security
Firewall Configuration:
- Only expose ports 80 (HTTP) and 443 (HTTPS) to public internet
- Keep port 5432 (PostgreSQL) internal only
- Use VPN or SSH tunnel for administrative database access
Reverse Proxy:
Use nginx or similar reverse proxy for additional security:
- Rate limiting
- DDoS protection
- SSL termination
- Request filtering
Advanced Troubleshooting
Viewing Server Logs
Docker Deployment:
# Backend logs docker-compose logs -f backend # Frontend logs docker-compose logs -f frontend # Database logs docker-compose logs -f postgres # All logs docker-compose logs -f
Manual Deployment:
- Backend logs: Check application output or system journal
- Frontend logs: Check nginx error logs
Enabling Debug Logging
- Navigate to Settings → Advanced
- Enable "Debug Logging"
- Click "Save"
- Restart backend to apply
Warning: Debug logging creates large log files. Disable after troubleshooting.
WebSocket Connection Issues
Symptoms:
- Devices showing as offline when they should be online
- Real-time updates not appearing in dashboard
- Screenshot thumbnails not updating
Troubleshooting:
1. Check WebSocket endpoint:
# Test WebSocket connection curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" http://your-server:5001/ws
2. Check reverse proxy configuration:
- Ensure WebSocket upgrade headers are passed through
- nginx example:
location /ws {
proxy_pass http://backend:8080/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}3. Check firewall:
- Ensure port 5001 (or your configured port) is open
- Check for WebSocket-specific firewall rules
Device Not Connecting
Symptoms:
- Device shows as offline immediately after registration
- Device client logs show connection errors
Troubleshooting Steps:
1. Verify device token:
# In device client .env file DEVICE_TOKEN=<correct-token>
2. Verify server URL:
# Should NOT include /ws path SERVER_URL=http://your-server:5001
3. Check device client logs:
# Windows journalctl -u theiacast-client -f # Raspberry Pi pm2 logs kiosk-client
4. Test network connectivity:
# From device, test HTTP
curl http://your-server:5001/health
# Should return: {"status":"healthy"}Playlist Not Updating on Device
Symptoms:
- Assign playlist to device in dashboard
- Device continues showing old content
Troubleshooting:
1. Check device connection:
- Device should show green "Online" status
- If offline, device is not receiving updates
2. Check WebSocket events:
- Enable debug logging
- Look for
content:updateevent in device client logs
3. Manual refresh:
- Flip device card → Click "Refresh Page"
- Or use Remote Control to navigate
High CPU Usage
Symptoms:
- Backend container using high CPU
- Slow dashboard performance
Possible Causes:
1. Too many screenshots:
- Increase screenshot interval (Settings → Display)
- Reduce screenshot retention period
2. Too many devices:
- Check if you've exceeded license tier device limit
- Consider upgrading license
3. Database query performance:
- Run manual VACUUM (see Database Maintenance section)
- Check for missing indexes (should be automatic)
4. Memory leak:
- Restart backend container
- Report issue on GitHub
Performance Optimization
Server Performance
Recommended Specifications (by number of devices):
| Devices | RAM | CPU | Storage |
|---|---|---|---|
| 1-10 | 2GB | 2 cores | 20GB |
| 11-50 | 4GB | 4 cores | 50GB |
| 51-100 | 8GB | 8 cores | 100GB |
| 100+ | 16GB+ | 16+ cores | 200GB+ |
Optimization Tips:
1. Increase screenshot interval:
- Settings → Display → Screenshot Interval
- 5 minutes → 10 minutes reduces database writes by 50%
2. Reduce health report frequency:
- Settings → Display → Health Report Interval
- 60 seconds → 120 seconds reduces WebSocket traffic by 50%
3. Use content CDN:
- Host large video files on external CDN
- Reference CDN URLs in content items
- Reduces server bandwidth and storage
4. Enable database connection pooling:
- Already enabled by default (100 connections)
- Increase in
appsettings.jsonif needed:
"ConnectionStrings": {
"Default": "Host=postgres;...;Maximum Pool Size=200;"
}Client Performance
Raspberry Pi Optimization:
1. Use H.264 video codec:
- Most efficient for Raspberry Pi hardware decoding
- Avoid VP9, AV1 (no hardware support)
2. Limit video resolution:
- 1080p maximum for Raspberry Pi 4
- 720p for Raspberry Pi 3
3. Disable unnecessary features:
- Reduce screenshot quality (lower JPEG quality)
- Increase screenshot interval
Windows Client Optimization:
1. Use hardware acceleration:
- Enabled by default in Puppeteer
- Ensure GPU drivers are up to date
2. Close other applications:
- Dedicated kiosk devices should run client only
Backup and Recovery
Backup Strategy
What to Backup:
1. Database (Critical):
- Contains all devices, content, playlists, users, settings
- Backup daily at minimum
2. Media Files (Important):
- Uploaded images, videos, presentations
- Located in Docker volume:
theiacast_media
3. Configuration Files (Important):
docker-compose.yml.envfiles- SSL certificates (if uploaded)
Database Backup
Manual Backup:
# Create backup directory mkdir -p ~/theiacast-backups # Backup database docker exec theiacast-postgres pg_dump -U postgres theiacast > ~/theiacast-backups/backup-$(date +%Y%m%d-%H%M%S).sql
Automated Daily Backup (Cron):
# Edit crontab crontab -e # Add this line (runs at 2 AM daily) 0 2 * * * docker exec theiacast-postgres pg_dump -U postgres theiacast > ~/theiacast-backups/backup-$(date +\%Y\%m\%d).sql
Keep last 30 days:
# Add to crontab (runs at 3 AM daily) 0 3 * * * find ~/theiacast-backups -name "backup-*.sql" -mtime +30 -delete
Media Files Backup
Manual Backup:
# Backup media volume to tar archive docker run --rm -v theiacast_media:/data -v ~/theiacast-backups:/backup ubuntu tar czf /backup/media-$(date +%Y%m%d).tar.gz -C /data .
Automated Backup:
# Add to crontab (runs at 1 AM daily) 0 1 * * * docker run --rm -v theiacast_media:/data -v ~/theiacast-backups:/backup ubuntu tar czf /backup/media-$(date +\%Y\%m\%d).tar.gz -C /data .
Database Restoration
Restore from Backup:
# Stop backend to prevent connections docker-compose stop backend # Drop and recreate database (WARNING: Deletes all current data!) docker exec -it theiacast-postgres psql -U postgres -c "DROP DATABASE theiacast;" docker exec -it theiacast-postgres psql -U postgres -c "CREATE DATABASE theiacast;" # Restore from backup file cat ~/theiacast-backups/backup-20250102.sql | docker exec -i theiacast-postgres psql -U postgres theiacast # Restart backend docker-compose start backend
Media Files Restoration
Restore from Backup:
# Stop backend to prevent writes docker-compose stop backend # Extract backup to volume docker run --rm -v theiacast_media:/data -v ~/theiacast-backups:/backup ubuntu tar xzf /backup/media-20250102.tar.gz -C /data # Restart backend docker-compose start backend
Disaster Recovery
Complete System Restoration:
- Install TheiaCast on new server (follow Installation Guide)
- Stop all services:
docker-compose down
- Restore database (see Database Restoration above)
- Restore media files (see Media Files Restoration above)
- Restore configuration:
# Copy docker-compose.yml and .env files from backup cp ~/theiacast-backups/docker-compose.yml .
- Start services:
docker-compose up -d
- Verify restoration:
- Check dashboard loads
- Verify devices appear
- Test content playback
Device Re-connection:
- Devices should automatically reconnect when server comes online
- No action needed on device side (tokens persist)
Support and Resources
Getting Help
- • Community Support: GitHub Discussions
- • Bug Reports: GitHub Issues
- • Email Support: Available on paid tiers (see License Management section)
Additional Resources
- • User Guide - Daily operations and features
- • Installation Guide - Setup instructions
- • FAQ - Common questions and answers
- • GitHub Repository - Source code and releases
Note: Screenshots in this guide are indicated with [Screenshot: description] placeholders. Actual screenshots will be added in a future update.