1203 lines
24 KiB
Markdown
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
|