I Built An Open-Source Crm That You Can Self-Host - Relaticle
I Built An Open-Source CRM That You Can Self-Host - Relaticle
Introduction
In an era where SaaS solutions dominate the CRM landscape, DevOps engineers and system administrators face an uncomfortable truth: every proprietary platform we adopt means surrendering control of critical business data while accumulating recurring costs. The 2023 Flexera State of the Cloud Report reveals that 82% of enterprises cite cloud cost management as a primary challenge, with SaaS subscriptions being a major contributor. This is where self-hosted solutions shine.
Relaticle emerges as a modern answer to these challenges. Built with Laravel and Filament PHP, this open-source CRM gives you complete ownership of your customer data while eliminating per-seat pricing. For DevOps professionals managing on-premises infrastructure or private cloud environments, Relaticle represents more than just a CRM - it’s a statement about data sovereignty and infrastructure control.
In this comprehensive guide, we’ll explore:
- The technical architecture enabling self-hosted CRM operations
- Production-grade deployment strategies for enterprise environments
- Security hardening techniques for customer data protection
- Performance optimization for high-load scenarios
- Maintenance workflows that ensure long-term reliability
Understanding Relaticle
Technical Architecture
Relaticle employs a classic LEMP stack architecture with modern DevOps twists:
1
Client → Nginx → PHP-FPM (Laravel) → MySQL/PostgreSQL → Redis (Optional Caching)
Key components:
- Laravel 10: MVC framework providing core application logic
- Filament PHP 3: Admin panel and CRM interface builder
- Livewire: Reactive frontend components
- Alpine.js: Lightweight JavaScript interactions
Feature Breakdown
Core capabilities relevant to infrastructure management:
| Feature | Technical Implementation | DevOps Impact |
|---|---|---|
| Custom Fields | Database schema morphing | Requires DB migration planning |
| Data Export | Laravel Excel integration | Storage I/O considerations |
| API Access | Laravel Sanctum tokens | Rate limiting needed |
| Audit Logs | Database table tracking | Retention policy management |
| User Roles | Spatie Permission package | RBAC implementation |
Comparison Matrix: Self-Hosted CRM Options
| Solution | Stack | DB Requirements | Scalability | Maintenance Complexity |
|---|---|---|---|---|
| Relaticle | PHP/MySQL | Moderate | Vertical scaling | Medium |
| SuiteCRM | PHP/MySQL | Heavy | Requires clustering | High |
| EspoCRM | PHP/MySQL | Light | Limited | Low |
| Odoo | Python/PostgreSQL | Very Heavy | Horizontal scaling | Very High |
Security Model
Relaticle inherits Laravel’s security features but adds:
- Automatic password policy enforcement
- Configurable session timeout
- Optional 2FA via Time-based One-Time Password (TOTP)
- IP allowlisting at application layer
Prerequisites
Hardware Requirements
Production deployment recommendations:
| Component | Development | Small Business (50 users) | Enterprise (500+ users) |
|---|---|---|---|
| CPU | 2 cores | 4 cores | 8+ cores |
| RAM | 4GB | 16GB | 64GB+ |
| Storage | 40GB | 200GB (SSD) | 1TB+ NVMe RAID |
| Network | 1Gbps | 1Gbps | 10Gbps bonded |
Software Requirements
Officially supported stack:
1
2
3
4
5
- PHP 8.2+ with extensions: ctype, curl, dom, fileinfo, gd, json, mbstring, openssl, pdo, tokenizer, xml, zip
- MySQL 8.0+ or PostgreSQL 15+
- Redis 6+ (optional but recommended)
- Node.js 18+ (for build processes)
- Composer 2.5+
Security Pre-Checks
Before installation:
- Verify OS hardening (SSH config, firewall rules)
- Create dedicated service account with restricted privileges
- Configure separate database credentials with least-privilege access
- Validate TLS certificate availability
- Implement network segmentation for database tier
Installation & Setup
Deployment Options
Option 1: Docker Deployment (Recommended)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Clone repository
git clone https://github.com/relaticle/relaticle.git
cd relaticle
# Copy environment template
cp .env.example .env
# Build containers
docker compose build --no-cache
# Generate application key
docker compose run --rm artisan key:generate
# Launch services
docker compose up -d
# Run migrations
docker compose exec artisan migrate --seed
Option 2: Bare Metal Installation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Install PHP extensions
sudo apt install php8.2-fpm php8.2-mysql php8.2-gd php8.2-mbstring php8.2-xml
# Clone repository
git clone https://github.com/relaticle/relaticle.git
cd relaticle
# Install dependencies
composer install --optimize-autoloader --no-dev
npm ci && npm run build
# Set permissions
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
# Configure environment
vim .env # Set DB credentials, APP_URL, etc.
# Run migrations
php artisan migrate --seed
# Optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
Reverse Proxy Configuration (Nginx)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
listen 443 ssl http2;
server_name crm.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/crm.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/crm.yourdomain.com/privkey.pem;
root /var/www/relaticle/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/relaticle_error.log;
access_log /var/log/nginx/relaticle_access.log;
}
Verification Checklist
After installation:
- Validate service statuses:
1 2
docker compose ps # For Docker systemctl status php8.2-fpm nginx mysql # For bare metal
- Test HTTPS configuration:
1
curl -I https://crm.yourdomain.com - Verify database connections:
1 2 3
docker compose exec artisan tinker # Docker php artisan tinker # Bare metal >>> DB::connection()->getPdo()
- Check queue workers (if enabled):
1
supervisorctl status
Configuration & Optimization
Critical .env Settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
APP_ENV=production
APP_DEBUG=false
APP_URL=https://crm.yourdomain.com
DB_CONNECTION=mysql
DB_HOST=db-cluster.example.com
DB_PORT=3306
DB_DATABASE=relaticle_prod
DB_USERNAME=relaticle_user
DB_PASSWORD=strong_password_here
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=redis-cluster.example.com
REDIS_PASSWORD=redis_auth_password
REDIS_PORT=6379
SESSION_LIFETIME=43200 # 12 hours
SESSION_SECURE_COOKIE=true
Security Hardening
- Database Encryption
CREATE DATABASE relaticle_prod ENCRYPTION='Y' DEFAULT ENCRYPTION='Y'; - File System Protections
1 2
chattr +i storage/framework/sessions/* find storage -type d -exec chmod 750 {} \;
- Rate Limiting (In routes/api.php)
1 2 3
RateLimiter::for('api', function (Request $request) { return Limit::perMinute(300)->by($request->user()?->id ?: $request->ip()); });
Performance Tuning
- PHP-FPM Optimization
1 2 3 4 5 6 7
; /etc/php/8.2/fpm/pool.d/www.conf pm = dynamic pm.max_children = 100 pm.start_servers = 20 pm.min_spare_servers = 10 pm.max_spare_servers = 30 pm.max_requests = 1000
- OPcache Configuration
1 2 3 4 5 6
; /etc/php/8.2/fpm/conf.d/10-opcache.ini opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=32 opcache.max_accelerated_files=20000 opcache.validate_timestamps=0
- Redis Caching
1 2 3
# In .env CACHE_STORE=redis SESSION_STORE=redis
Backup Strategy
Sample backup script (/usr/local/bin/relaticle-backup.sh):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backups/relaticle"
# Database dump
mysqldump -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_DATABASE | gzip > $BACKUP_DIR/db-$DATE.sql.gz
# File backup
tar czf $BACKUP_DIR/files-$DATE.tar.gz /var/www/relaticle/storage
# Sync to remote
aws s3 sync $BACKUP_DIR s3://your-backup-bucket/relaticle/
# Retention (keep 30 days)
find $BACKUP_DIR -type f -mtime +30 -delete
Set cron job:
1
0 2 * * * /usr/local/bin/relaticle-backup.sh
Usage & Operations
Common Maintenance Commands
- Queue Management
1 2
php artisan queue:restart # Graceful restart php artisan queue:failed # View failed jobs
- Cache Management
1 2 3 4
php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
- User Management
1 2
php artisan relaticle:create-user # Interactive user creation php artisan relaticle:deactivate-user [email]
Monitoring Recommendations
Recommended Prometheus exporters:
- MySQLd Exporter - Database metrics
- PHP-FPM Exporter - Application metrics
- Blackbox Exporter - HTTP checks
- Node Exporter - Host metrics
Sample Grafana dashboard metrics to track:
- PHP-FPM active processes
- MySQL query latency
- Redis memory usage
- Application response times
- Queue backlog size
Scaling Approaches
Vertical Scaling:
- Increase PHP-FPM pm.max_children
- Add Redis persistent storage
- Enable MySQL query caching
Horizontal Scaling:
- Separate web and database tiers
- Implement Redis clustering
- Add read replicas for MySQL
- Use load balancer with multiple app servers
Troubleshooting
Common Issues and Solutions
- Migrations Fail with Foreign Key Errors
1 2
php artisan migrate:fresh --force php artisan db:seed - High Memory Usage
- Check PHP-FPM settings with
systemctl status php8.2-fpm - Enable OPCache file cache
1
opcache.file_cache=/tmp/opcache
- Check PHP-FPM settings with
- Queue Workers Stalling
1 2
supervisorctl restart all php artisan queue:retry all
- Mixed Content Warnings Ensure APP_URL in .env uses HTTPS
1
php artisan config:clear
Log Analysis Commands
- Error Log Tailing
1
tail -f storage/logs/laravel-$(date +%Y-%m-%d).log
- Database Slow Query Log
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; - Nginx Request Analysis
1
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
Recovery Procedures
Full System Restoration:
- Restore database from backup:
1
zcat db-backup.sql.gz | mysql -u root -p relaticle_prod
- Extract files backup:
1
tar xzf files-backup.tar.gz -C /
- Clear caches:
1
php artisan optimize:clear
Conclusion
Relaticle represents more than just another CRM option - it’s a battle-tested solution for organizations prioritizing data control and infrastructure autonomy. By implementing the techniques covered in this guide, DevOps teams can deploy a production-grade CRM that meets enterprise security standards while maintaining full ownership of critical customer data.
Key takeaways:
- Self-hosted CRM solutions eliminate vendor lock-in and reduce long-term costs
- Properly configured Laravel applications can meet enterprise performance demands
- Infrastructure-as-Code principles apply equally to CRM deployments
- Comprehensive monitoring is non-negotiable for business-critical systems
For further exploration:
- Laravel Horizon Documentation for advanced queue monitoring
- Filament PHP Admin Panel Guide for interface customization
- MySQL 8 Performance Tuning
- Redis Best Practices
The future of business software lies in solutions that respect infrastructure autonomy while delivering modern user experiences. Relaticle’s open-source model demonstrates that these goals aren’t mutually exclusive when implemented with DevOps best practices.