libra/docs/DEPLOYMENT.md

1203 lines
24 KiB
Markdown

# Libra Law Firm - Production Deployment Guide
**Domain:** libra.adv.ps
**Server Path:** /home/libra/public_html
**OS:** Rocky Linux 9
**Stack:** PHP 8.4, Laravel 12, MariaDB, Nginx, PHP-FPM
---
## Table of Contents
1. [Server Prerequisites](#1-server-prerequisites)
2. [System User Setup](#2-system-user-setup)
3. [PHP 8.4 Installation & Configuration](#3-php-84-installation--configuration)
4. [MariaDB Setup](#4-mariadb-setup)
5. [Nginx Configuration](#5-nginx-configuration)
6. [Application Deployment](#6-application-deployment)
7. [SSL Certificate (Let's Encrypt)](#7-ssl-certificate-lets-encrypt)
8. [Queue Worker (Systemd)](#8-queue-worker-systemd)
9. [Scheduler (Cron)](#9-scheduler-cron)
10. [Firewall Configuration](#10-firewall-configuration)
11. [SELinux Configuration](#11-selinux-configuration)
12. [Log Rotation](#12-log-rotation)
13. [Maintenance & Updates](#13-maintenance--updates)
14. [Troubleshooting](#14-troubleshooting)
---
## 1. Server Prerequisites
**Minimum Requirements:**
- Rocky Linux 9
- 2 GB RAM minimum (4 GB recommended)
- 20 GB disk space
- Root or sudo access
**Update System:**
```bash
sudo dnf update -y
```
**Install Essential Packages:**
```bash
sudo dnf install -y curl wget git unzip acl tar
sudo dnf install -y epel-release
sudo dnf install -y dnf-utils
```
---
## 2. System User Setup
```bash
# Create libra user with home directory
sudo useradd -m -d /home/libra -s /bin/bash libra
# Set password (optional, for SSH access)
sudo passwd libra
# Create directory structure
sudo mkdir -p /home/libra/public_html
sudo mkdir -p /home/libra/logs
sudo mkdir -p /home/libra/tmp
sudo mkdir -p /home/libra/sessions
sudo mkdir -p /home/libra/backups
# Set ownership
sudo chown -R libra:libra /home/libra
# Set permissions
sudo chmod 755 /home/libra
sudo chmod 755 /home/libra/public_html
```
---
## 3. PHP 8.4 Installation & Configuration
### 3.1 Install PHP 8.4
```bash
# Add Remi repository
sudo dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
# Reset PHP module and enable Remi 8.4
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.4 -y
# Install PHP 8.4 and required extensions
sudo dnf install -y \
php-fpm \
php-cli \
php-common \
php-mysqlnd \
php-xml \
php-curl \
php-gd \
php-mbstring \
php-zip \
php-bcmath \
php-intl \
php-opcache \
php-sodium \
php-pecl-zip
# Verify installation
php -v
```
### 3.2 PHP-FPM Pool Configuration
Create a dedicated pool for Libra:
```bash
sudo nano /etc/php-fpm.d/libra.conf
```
**Content:**
```ini
[libra]
; Pool identity
user = libra
group = libra
; Socket configuration
listen = /run/php-fpm/libra.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; Process manager settings
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 500
pm.process_idle_timeout = 10s
; Performance tuning
request_terminate_timeout = 300
request_slowlog_timeout = 30s
slowlog = /home/libra/logs/php-slow.log
; Security
chdir = /home/libra/public_html
security.limit_extensions = .php
; Environment
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /home/libra/tmp
env[TMPDIR] = /home/libra/tmp
env[TEMP] = /home/libra/tmp
; PHP settings for this pool
php_admin_value[error_log] = /home/libra/logs/php-error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M
php_admin_value[upload_max_filesize] = 50M
php_admin_value[post_max_size] = 50M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
php_admin_value[max_input_vars] = 5000
; Session configuration
php_admin_value[session.save_handler] = files
php_admin_value[session.save_path] = /home/libra/sessions
; OPcache settings
php_admin_value[opcache.enable] = 1
php_admin_value[opcache.memory_consumption] = 128
php_admin_value[opcache.interned_strings_buffer] = 16
php_admin_value[opcache.max_accelerated_files] = 10000
php_admin_value[opcache.validate_timestamps] = 0
php_admin_value[opcache.save_comments] = 1
```
### 3.3 Disable Default Pool (Optional)
```bash
# Rename default pool to disable it
sudo mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.disabled
```
### 3.4 PHP CLI Configuration
Create CLI config override:
```bash
sudo nano /etc/php.d/99-libra-cli.ini
```
**Content:**
```ini
memory_limit = 512M
max_execution_time = 0
```
### 3.5 Create Socket Directory
```bash
sudo mkdir -p /run/php-fpm
sudo chown root:root /run/php-fpm
sudo chmod 755 /run/php-fpm
```
### 3.6 Start and Enable PHP-FPM
```bash
sudo systemctl start php-fpm
sudo systemctl enable php-fpm
sudo systemctl status php-fpm
```
---
## 4. MariaDB Setup
### 4.1 Install MariaDB
```bash
sudo dnf install -y mariadb-server mariadb
```
### 4.2 Start and Secure Installation
```bash
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation
```
Answer the prompts:
- Enter current password for root: (press Enter)
- Switch to unix_socket authentication: Y
- Change the root password: Y (set a strong password)
- Remove anonymous users: Y
- Disallow root login remotely: Y
- Remove test database: Y
- Reload privilege tables: Y
### 4.3 Create Database and User
```bash
sudo mysql -u root -p
```
```sql
-- Create database with proper charset for Arabic support
CREATE DATABASE libra_production
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- Create dedicated user
CREATE USER 'libra_user'@'localhost' IDENTIFIED BY 'YOUR_STRONG_PASSWORD_HERE';
-- Grant privileges
GRANT ALL PRIVILEGES ON libra_production.* TO 'libra_user'@'localhost';
-- Apply changes
FLUSH PRIVILEGES;
-- Verify
SHOW DATABASES;
SELECT User, Host FROM mysql.user;
EXIT;
```
### 4.4 MariaDB Configuration
Create custom config:
```bash
sudo nano /etc/my.cnf.d/libra.cnf
```
**Content:**
```ini
[mysqld]
# Character set (Arabic support)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# Performance tuning
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
# Connection limits
max_connections = 100
wait_timeout = 600
interactive_timeout = 600
# Logging
slow_query_log = 1
slow_query_log_file = /var/log/mariadb/slow.log
long_query_time = 2
[client]
default-character-set = utf8mb4
```
```bash
# Create log directory
sudo mkdir -p /var/log/mariadb
sudo chown mysql:mysql /var/log/mariadb
sudo systemctl restart mariadb
```
---
## 5. Nginx Configuration
### 5.1 Install Nginx
```bash
sudo dnf install -y nginx
```
### 5.2 Create Directory Structure
Rocky Linux uses `/etc/nginx/conf.d/` for site configs:
```bash
sudo mkdir -p /etc/nginx/conf.d/libra.d
```
### 5.3 Main Site Configuration
```bash
sudo nano /etc/nginx/conf.d/libra.adv.ps.conf
```
**Content:**
```nginx
server {
listen 80;
listen [::]:80;
server_name libra.adv.ps www.libra.adv.ps;
# Redirect to HTTPS (uncomment after SSL setup)
# return 301 https://$server_name$request_uri;
# Root and index (remove after SSL setup)
root /home/libra/public_html/public;
index index.php;
# Include modular configuration
include /etc/nginx/conf.d/libra.d/*.conf;
}
# HTTPS server (uncomment after SSL setup)
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name libra.adv.ps www.libra.adv.ps;
#
# # SSL certificates
# ssl_certificate /etc/letsencrypt/live/libra.adv.ps/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/libra.adv.ps/privkey.pem;
# ssl_trusted_certificate /etc/letsencrypt/live/libra.adv.ps/chain.pem;
#
# # SSL configuration
# include /etc/nginx/conf.d/libra.d/ssl.conf;
#
# # Root and index
# root /home/libra/public_html/public;
# index index.php;
#
# # Include modular configuration
# include /etc/nginx/conf.d/libra.d/*.conf;
# }
```
### 5.4 Application Config
```bash
sudo nano /etc/nginx/conf.d/libra.d/app.conf
```
**Content:**
```nginx
# Charset
charset utf-8;
# Logging
access_log /home/libra/logs/nginx-access.log;
error_log /home/libra/logs/nginx-error.log;
# Request size limits
client_max_body_size 50M;
client_body_buffer_size 128k;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Main location
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP handling
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/libra.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_read_timeout 300;
}
# Deny access to hidden files
location ~ /\.(?!well-known).* {
deny all;
}
# Deny access to sensitive files
location ~ /\.env {
deny all;
}
```
### 5.5 Static Assets Config
```bash
sudo nano /etc/nginx/conf.d/libra.d/static.conf
```
**Content:**
```nginx
# Favicon
location = /favicon.ico {
access_log off;
log_not_found off;
}
# Robots
location = /robots.txt {
access_log off;
log_not_found off;
}
# Static assets caching
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Livewire assets
location ^~ /livewire {
try_files $uri $uri/ /index.php?$query_string;
}
```
### 5.6 SSL Configuration (for later use)
```bash
sudo nano /etc/nginx/conf.d/libra.d/ssl.conf
```
**Content:**
```nginx
# SSL protocols and ciphers
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# SSL session
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
```
### 5.7 Test and Enable Nginx
```bash
# Test configuration
sudo nginx -t
# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
```
---
## 6. Application Deployment
### 6.1 Install Composer
```bash
cd /tmp
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
composer --version
```
### 6.2 Install Node.js 20 LTS
```bash
# Add NodeSource repository
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
# Install Node.js
sudo dnf install -y nodejs
# Verify
node --version
npm --version
```
### 6.3 Clone Repository
```bash
# Switch to libra user
sudo -u libra -i
# Clone repository
cd /home/libra
git clone https://github.com/YOUR_REPO/libra.git public_html
# Or if deploying from local machine, use rsync:
# rsync -avz --exclude='.env' --exclude='vendor' --exclude='node_modules' --exclude='storage/logs/*' ./ libra@server:/home/libra/public_html/
```
### 6.4 Set Permissions
```bash
# As root or sudo user
cd /home/libra/public_html
# Set ownership
sudo chown -R libra:libra /home/libra/public_html
# Set directory permissions
sudo find /home/libra/public_html -type d -exec chmod 755 {} \;
# Set file permissions
sudo find /home/libra/public_html -type f -exec chmod 644 {} \;
# Make artisan executable
sudo chmod +x /home/libra/public_html/artisan
# Storage and cache writable
sudo chmod -R 775 /home/libra/public_html/storage
sudo chmod -R 775 /home/libra/public_html/bootstrap/cache
# Allow nginx user to write to storage
sudo setfacl -R -m u:nginx:rwx /home/libra/public_html/storage
sudo setfacl -R -d -m u:nginx:rwx /home/libra/public_html/storage
sudo setfacl -R -m u:nginx:rwx /home/libra/public_html/bootstrap/cache
sudo setfacl -R -d -m u:nginx:rwx /home/libra/public_html/bootstrap/cache
# Sessions directory writable by PHP-FPM
sudo chown libra:libra /home/libra/sessions
sudo chmod 770 /home/libra/sessions
```
### 6.5 Configure Environment
```bash
# Switch to libra user
sudo -u libra -i
cd /home/libra/public_html
# Copy environment file
cp .env.example .env
# Edit environment file
nano .env
```
**Production `.env` configuration:**
```env
APP_NAME="Libra Law Firm"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://libra.adv.ps
APP_LOCALE=ar
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=ar_SA
APP_MAINTENANCE_DRIVER=file
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=error
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=libra_production
DB_USERNAME=libra_user
DB_PASSWORD=YOUR_STRONG_PASSWORD_HERE
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
SESSION_DOMAIN=libra.adv.ps
SESSION_SECURE_COOKIE=true
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=database
CACHE_STORE=database
MAIL_MAILER=smtp
MAIL_HOST=your-smtp-host.com
MAIL_PORT=587
MAIL_USERNAME=your-smtp-username
MAIL_PASSWORD=your-smtp-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply@libra.adv.ps
MAIL_FROM_NAME="Libra Law Firm"
ADMIN_NOTIFICATION_EMAIL=admin@libra.adv.ps
SYSTEM_NOTIFICATIONS_ENABLED=true
ERROR_NOTIFICATION_THROTTLE_MINUTES=15
```
### 6.6 Install Dependencies and Build
```bash
# As libra user
cd /home/libra/public_html
# Install PHP dependencies (production)
composer install --optimize-autoloader --no-dev
# Generate application key
php artisan key:generate
# Install Node dependencies and build assets
npm ci --production
npm run build
# Run migrations
php artisan migrate --force
# Create storage link
php artisan storage:link
# Cache configuration
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan icons:cache
```
### 6.7 Create Admin User
```bash
php artisan tinker
```
```php
use App\Models\User;
use App\Enums\UserType;
use App\Enums\UserStatus;
use Illuminate\Support\Facades\Hash;
User::create([
'name' => 'Admin Name',
'email' => 'admin@libra.adv.ps',
'password' => Hash::make('YOUR_SECURE_PASSWORD'),
'type' => UserType::Admin,
'status' => UserStatus::Active,
'email_verified_at' => now(),
]);
exit
```
---
## 7. SSL Certificate (Let's Encrypt)
### 7.1 Install Certbot
```bash
sudo dnf install -y certbot python3-certbot-nginx
```
### 7.2 Obtain Certificate
```bash
sudo certbot --nginx -d libra.adv.ps -d www.libra.adv.ps
```
### 7.3 Update Nginx Configuration
After obtaining the certificate, edit `/etc/nginx/conf.d/libra.adv.ps.conf`:
```bash
sudo nano /etc/nginx/conf.d/libra.adv.ps.conf
```
Uncomment the HTTPS server block and the redirect in the HTTP block.
```bash
sudo nginx -t
sudo systemctl reload nginx
```
### 7.4 Auto-Renewal
Certbot sets up auto-renewal automatically via systemd timer. Verify:
```bash
sudo systemctl status certbot-renew.timer
sudo certbot renew --dry-run
```
---
## 8. Queue Worker (Systemd)
### 8.1 Create Service File
```bash
sudo nano /etc/systemd/system/libra-queue.service
```
**Content:**
```ini
[Unit]
Description=Libra Laravel Queue Worker
After=network.target mariadb.service
[Service]
User=libra
Group=libra
Restart=always
RestartSec=5
WorkingDirectory=/home/libra/public_html
ExecStart=/usr/bin/php artisan queue:work database --sleep=3 --tries=3 --max-time=3600
# Security
NoNewPrivileges=true
PrivateTmp=true
# Logging
StandardOutput=append:/home/libra/logs/queue-worker.log
StandardError=append:/home/libra/logs/queue-worker-error.log
[Install]
WantedBy=multi-user.target
```
### 8.2 Enable and Start
```bash
sudo systemctl daemon-reload
sudo systemctl enable libra-queue
sudo systemctl start libra-queue
sudo systemctl status libra-queue
```
### 8.3 Multiple Workers (Optional)
For higher throughput:
```bash
sudo nano /etc/systemd/system/libra-queue@.service
```
**Content:**
```ini
[Unit]
Description=Libra Queue Worker %i
After=network.target mariadb.service
[Service]
User=libra
Group=libra
Restart=always
RestartSec=5
WorkingDirectory=/home/libra/public_html
ExecStart=/usr/bin/php artisan queue:work database --sleep=3 --tries=3 --max-time=3600
NoNewPrivileges=true
PrivateTmp=true
StandardOutput=append:/home/libra/logs/queue-worker-%i.log
StandardError=append:/home/libra/logs/queue-worker-%i-error.log
[Install]
WantedBy=multi-user.target
```
```bash
# Enable 3 workers
sudo systemctl daemon-reload
sudo systemctl enable libra-queue@{1..3}
sudo systemctl start libra-queue@{1..3}
```
---
## 9. Scheduler (Cron)
### 9.1 Create Cron Job
```bash
sudo crontab -u libra -e
```
**Add this line:**
```cron
* * * * * cd /home/libra/public_html && /usr/bin/php artisan schedule:run >> /home/libra/logs/scheduler.log 2>&1
```
### 9.2 Verify Cron
```bash
sudo crontab -u libra -l
```
---
## 10. Firewall Configuration
```bash
# Start and enable firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld
# Allow HTTP
sudo firewall-cmd --permanent --add-service=http
# Allow HTTPS
sudo firewall-cmd --permanent --add-service=https
# Allow SSH
sudo firewall-cmd --permanent --add-service=ssh
# Reload firewall
sudo firewall-cmd --reload
# Verify
sudo firewall-cmd --list-all
```
---
## 11. SELinux Configuration
Rocky Linux has SELinux enabled by default. Configure it for the application:
### 11.1 Allow Nginx to Access Home Directory
```bash
# Allow nginx to read from home directories
sudo setsebool -P httpd_enable_homedirs 1
# Allow nginx to connect to network (for external APIs, mail, etc.)
sudo setsebool -P httpd_can_network_connect 1
# Allow nginx to send mail
sudo setsebool -P httpd_can_sendmail 1
```
### 11.2 Set Correct SELinux Context
```bash
# Set context for web content
sudo semanage fcontext -a -t httpd_sys_content_t "/home/libra/public_html(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/home/libra/public_html/storage(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/home/libra/public_html/bootstrap/cache(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/home/libra/logs(/.*)?"
# Apply contexts
sudo restorecon -Rv /home/libra/public_html
sudo restorecon -Rv /home/libra/logs
```
### 11.3 Allow PHP-FPM Socket
```bash
sudo semanage fcontext -a -t httpd_var_run_t "/run/php-fpm(/.*)?"
sudo restorecon -Rv /run/php-fpm
```
### 11.4 If Issues Persist (Check Audit Log)
```bash
# Check for SELinux denials
sudo ausearch -m avc -ts recent
# Generate policy from denials (if needed)
sudo ausearch -m avc -ts recent | audit2allow -M libra-policy
sudo semodule -i libra-policy.pp
```
---
## 12. Log Rotation
### 12.1 Create Logrotate Config
```bash
sudo nano /etc/logrotate.d/libra
```
**Content:**
```
/home/libra/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0644 libra libra
sharedscripts
postrotate
systemctl reload php-fpm > /dev/null 2>&1 || true
endscript
}
/home/libra/public_html/storage/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0664 libra libra
}
```
### 12.2 Test Logrotate
```bash
sudo logrotate -d /etc/logrotate.d/libra
```
---
## 13. Maintenance & Updates
### Updating the Application
When you need to deploy updates, run these commands in order:
```bash
# Switch to libra user
sudo -u libra -i
cd /home/libra/public_html
# 1. Enable maintenance mode
php artisan down --retry=60
# 2. Pull latest changes
git pull origin main
# 3. Install composer dependencies
composer install --optimize-autoloader --no-dev
# 4. Install npm dependencies and build assets
npm ci --production
npm run build
# 5. Run migrations
php artisan migrate --force
# 6. Clear and rebuild caches
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
php artisan icons:cache
# 7. Restart queue workers
php artisan queue:restart
# 8. Disable maintenance mode
php artisan up
```
### Common Commands
```bash
# Clear all caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
# Restart queue workers
php artisan queue:restart
# Monitor queue
php artisan queue:monitor database:default
# Check failed jobs
php artisan queue:failed
# Retry failed jobs
php artisan queue:retry all
# View logs
tail -f /home/libra/public_html/storage/logs/laravel.log
# Database backup
mysqldump -u libra_user -p libra_production > /home/libra/backups/backup-$(date +%Y%m%d).sql
```
---
## 14. Troubleshooting
### Common Issues
**502 Bad Gateway:**
```bash
# Check PHP-FPM status
sudo systemctl status php-fpm
# Check socket exists
ls -la /run/php-fpm/libra.sock
# Check nginx error log
tail -f /home/libra/logs/nginx-error.log
# Check PHP-FPM error log
tail -f /var/log/php-fpm/error.log
```
**Permission Denied:**
```bash
# Fix permissions
sudo chown -R libra:libra /home/libra/public_html/storage
sudo chmod -R 775 /home/libra/public_html/storage
# Reapply ACLs
sudo setfacl -R -m u:nginx:rwx /home/libra/public_html/storage
sudo setfacl -R -d -m u:nginx:rwx /home/libra/public_html/storage
```
**SELinux Blocking Access:**
```bash
# Check for denials
sudo ausearch -m avc -ts recent
# Temporarily set to permissive (for debugging only)
sudo setenforce 0
# Re-enable enforcing
sudo setenforce 1
# Check current mode
getenforce
```
**Database Connection Error:**
```bash
# Test database connection
mysql -u libra_user -p -e "SELECT 1"
# Check DB credentials in .env
grep DB_ /home/libra/public_html/.env
```
**Queue Not Processing:**
```bash
# Check queue service status
sudo systemctl status libra-queue
# Restart queue service
sudo systemctl restart libra-queue
# Check queue worker logs
tail -f /home/libra/logs/queue-worker.log
```
**CSS/JS Not Loading:**
```bash
# Rebuild assets
cd /home/libra/public_html
npm run build
# Clear view cache
php artisan view:clear
```
### Useful Monitoring Commands
```bash
# System resources
htop
df -h
free -m
# Nginx connections
ss -tuln | grep :80
ss -tuln | grep :443
# PHP-FPM processes
ps aux | grep php-fpm
# MariaDB status
sudo mysqladmin -u root -p status
# Laravel logs
tail -100 /home/libra/public_html/storage/logs/laravel.log
# SELinux status
sestatus
```
---
## Quick Reference
| Service | Start | Stop | Restart | Status |
|---------|-------|------|---------|--------|
| Nginx | `sudo systemctl start nginx` | `sudo systemctl stop nginx` | `sudo systemctl restart nginx` | `sudo systemctl status nginx` |
| PHP-FPM | `sudo systemctl start php-fpm` | `sudo systemctl stop php-fpm` | `sudo systemctl restart php-fpm` | `sudo systemctl status php-fpm` |
| MariaDB | `sudo systemctl start mariadb` | `sudo systemctl stop mariadb` | `sudo systemctl restart mariadb` | `sudo systemctl status mariadb` |
| Queue | `sudo systemctl start libra-queue` | `sudo systemctl stop libra-queue` | `sudo systemctl restart libra-queue` | `sudo systemctl status libra-queue` |
| Firewall | `sudo systemctl start firewalld` | `sudo systemctl stop firewalld` | `sudo systemctl restart firewalld` | `sudo systemctl status firewalld` |
---
## File Structure Summary
```
/home/libra/
├── public_html/ # Laravel application root
│ ├── public/ # Web root (Nginx points here)
│ ├── storage/ # Application storage
│ └── ...
├── logs/ # All application logs
│ ├── nginx-access.log
│ ├── nginx-error.log
│ ├── php-error.log
│ ├── php-slow.log
│ ├── queue-worker.log
│ └── scheduler.log
├── sessions/ # PHP sessions
├── tmp/ # Temporary files
└── backups/ # Database backups
/etc/nginx/conf.d/
├── libra.adv.ps.conf # Main site configuration
└── libra.d/ # Modular configs
├── app.conf
├── static.conf
└── ssl.conf
/etc/php-fpm.d/
└── libra.conf # PHP-FPM pool configuration
/etc/my.cnf.d/
└── libra.cnf # MariaDB custom configuration
/etc/systemd/system/
└── libra-queue.service # Queue worker service
```
---
**Document Version:** 1.0
**Last Updated:** January 2025
**For:** Libra Law Firm (libra.adv.ps)
**OS:** Rocky Linux 9