From 0df70a626acc08b076cba76fca3e13f4357ba7c4 Mon Sep 17 00:00:00 2001 From: Doar Mihai Date: Sat, 4 Apr 2026 02:19:32 +0300 Subject: [PATCH] switched to php 8.3 --- DEPLOYMENT.md | 464 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 217 ++++++++++++++++++++++- composer.lock | 64 +++---- 3 files changed, 698 insertions(+), 47 deletions(-) create mode 100644 DEPLOYMENT.md diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..ec5cbad --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,464 @@ +# JobifyGarden Deployment Guide + +## Requirements + +- **PHP**: 8.3.x (minimum) +- **MySQL**: 8.0+ or MariaDB 10.3+ +- **Composer**: 2.x +- **Node.js**: 18.x or 20.x +- **Redis**: 6.x+ (for caching and queues) +- **Nginx** or **Apache** +- **Supervisor** (for queue workers) + +## Server Setup + +### 1. Install PHP 8.3 and Extensions + +```bash +# Ubuntu/Debian +sudo apt update +sudo apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-mysql php8.3-redis \ + php8.3-xml php8.3-mbstring php8.3-curl php8.3-zip php8.3-gd \ + php8.3-intl php8.3-bcmath php8.3-opcache + +# Verify PHP version +php -v +# Should show: PHP 8.3.x +``` + +### 2. Install MySQL + +```bash +sudo apt install -y mysql-server +sudo mysql_secure_installation + +# Create database +sudo mysql -u root -p +CREATE DATABASE jobifygarden CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE USER 'jobifygarden'@'localhost' IDENTIFIED BY 'your_secure_password'; +GRANT ALL PRIVILEGES ON jobifygarden.* TO 'jobifygarden'@'localhost'; +FLUSH PRIVILEGES; +EXIT; +``` + +### 3. Install Redis + +```bash +sudo apt install -y redis-server +sudo systemctl enable redis-server +sudo systemctl start redis-server +``` + +### 4. Install Composer + +```bash +curl -sS https://getcomposer.org/installer | php +sudo mv composer.phar /usr/local/bin/composer +sudo chmod +x /usr/local/bin/composer +``` + +### 5. Install Node.js + +```bash +curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - +sudo apt install -y nodejs +``` + +## Application Deployment + +### 1. Clone the Repository + +```bash +cd /var/www +sudo git clone jobifygarden +sudo chown -R www-data:www-data jobifygarden +cd jobifygarden +``` + +### 2. Install Dependencies + +```bash +# Install PHP dependencies +composer install --no-dev --optimize-autoloader + +# Install Node.js dependencies +npm ci + +# Build frontend assets +npm run build +``` + +### 3. Configure Environment + +```bash +# Copy environment file +cp .env.example .env + +# Edit .env file +nano .env +``` + +Update the following in `.env`: + +```env +APP_NAME=JobifyGarden +APP_ENV=production +APP_DEBUG=false +APP_URL=https://your-domain.com + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=jobifygarden +DB_USERNAME=jobifygarden +DB_PASSWORD=your_secure_password + +CACHE_STORE=redis +SESSION_DRIVER=redis +QUEUE_CONNECTION=redis + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 +``` + +### 4. Generate Application Key + +```bash +php artisan key:generate +``` + +### 5. Run Database Migrations + +```bash +php artisan migrate --force +``` + +### 6. Optimize Application + +```bash +php artisan config:cache +php artisan route:cache +php artisan view:cache +php artisan event:cache +``` + +### 7. Set Permissions + +```bash +sudo chown -R www-data:www-data storage bootstrap/cache +sudo chmod -R 775 storage bootstrap/cache +``` + +## Web Server Configuration + +### Nginx Configuration + +Create `/etc/nginx/sites-available/jobifygarden`: + +```nginx +server { + listen 80; + listen [::]:80; + server_name your-domain.com; + root /var/www/jobifygarden/public; + + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-Content-Type-Options "nosniff"; + + index index.php; + + charset utf-8; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; + fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; + include fastcgi_params; + fastcgi_hide_header X-Powered-By; + } + + location ~ /\.(?!well-known).* { + deny all; + } + + # Gzip compression + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; +} +``` + +Enable the site: + +```bash +sudo ln -s /etc/nginx/sites-available/jobifygarden /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl reload nginx +``` + +### Apache Configuration (Alternative) + +Create `/etc/apache2/sites-available/jobifygarden.conf`: + +```apache + + ServerName your-domain.com + DocumentRoot /var/www/jobifygarden/public + + + AllowOverride All + Require all granted + + + ErrorLog ${APACHE_LOG_DIR}/jobifygarden_error.log + CustomLog ${APACHE_LOG_DIR}/jobifygarden_access.log combined + +``` + +Enable the site: + +```bash +sudo a2enmod rewrite +sudo a2ensite jobifygarden +sudo systemctl reload apache2 +``` + +## SSL Certificate (Let's Encrypt) + +```bash +sudo apt install -y certbot python3-certbot-nginx +sudo certbot --nginx -d your-domain.com +``` + +## Queue Worker Setup (Supervisor) + +Create `/etc/supervisor/conf.d/jobifygarden-worker.conf`: + +```ini +[program:jobifygarden-worker] +process_name=%(program_name)s_%(process_num)02d +command=php /var/www/jobifygarden/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600 +autostart=true +autorestart=true +stopasgroup=true +killasgroup=true +user=www-data +numprocs=4 +redirect_stderr=true +stdout_logfile=/var/www/jobifygarden/storage/logs/worker.log +stopwaitsecs=3600 +``` + +Start the workers: + +```bash +sudo supervisorctl reread +sudo supervisorctl update +sudo supervisorctl start jobifygarden-worker:* +``` + +## Scheduled Tasks (Cron) + +Add to crontab for `www-data` user: + +```bash +sudo crontab -u www-data -e +``` + +Add this line: + +```cron +* * * * * cd /var/www/jobifygarden && php artisan schedule:run >> /dev/null 2>&1 +``` + +## Database Optimization + +Run regularly to maintain database performance: + +```bash +php artisan db:optimize +``` + +Consider adding to scheduler in `app/Console/Kernel.php`: + +```php +$schedule->command('db:optimize')->weekly(); +``` + +## Monitoring & Maintenance + +### Clear Caches + +```bash +php artisan cache:clear +php artisan config:clear +php artisan route:clear +php artisan view:clear +``` + +### View Logs + +```bash +tail -f storage/logs/laravel.log +``` + +### Monitor Queue + +```bash +php artisan queue:monitor +``` + +### Database Backup + +```bash +# Create backup directory +mkdir -p /var/backups/jobifygarden + +# Add to cron (daily at 2 AM) +0 2 * * * mysqldump -u jobifygarden -p'password' jobifygarden | gzip > /var/backups/jobifygarden/backup-$(date +\%Y\%m\%d).sql.gz +``` + +## Performance Tuning + +### PHP-FPM Configuration + +Edit `/etc/php/8.3/fpm/pool.d/www.conf`: + +```ini +pm = dynamic +pm.max_children = 50 +pm.start_servers = 10 +pm.min_spare_servers = 5 +pm.max_spare_servers = 35 +pm.max_requests = 500 +``` + +### OPcache Configuration + +Edit `/etc/php/8.3/fpm/conf.d/10-opcache.ini`: + +```ini +opcache.enable=1 +opcache.memory_consumption=256 +opcache.interned_strings_buffer=16 +opcache.max_accelerated_files=10000 +opcache.revalidate_freq=0 +opcache.validate_timestamps=0 +``` + +Restart PHP-FPM: + +```bash +sudo systemctl restart php8.3-fpm +``` + +## Security Checklist + +- [ ] Update `.env` with strong `APP_KEY` +- [ ] Set `APP_DEBUG=false` in production +- [ ] Configure firewall (UFW/iptables) +- [ ] Set up fail2ban for brute force protection +- [ ] Keep PHP and dependencies updated +- [ ] Regular security audits: `composer audit` +- [ ] Monitor error logs regularly +- [ ] Set up automated backups +- [ ] Use HTTPS only (redirect HTTP to HTTPS) +- [ ] Configure proper file permissions + +## Updating the Application + +```bash +cd /var/www/jobifygarden + +# Enable maintenance mode +php artisan down + +# Pull latest code +git pull origin main + +# Update dependencies +composer install --no-dev --optimize-autoloader +npm ci +npm run build + +# Run migrations +php artisan migrate --force + +# Clear and rebuild caches +php artisan config:cache +php artisan route:cache +php artisan view:cache + +# Disable maintenance mode +php artisan up + +# Restart queue workers +sudo supervisorctl restart jobifygarden-worker:* +``` + +## Troubleshooting + +### Permission Issues + +```bash +sudo chown -R www-data:www-data /var/www/jobifygarden +sudo chmod -R 775 storage bootstrap/cache +``` + +### Queue Not Processing + +```bash +# Check supervisor status +sudo supervisorctl status + +# Restart workers +sudo supervisorctl restart jobifygarden-worker:* + +# Check worker logs +tail -f storage/logs/worker.log +``` + +### Database Connection Issues + +```bash +# Test database connection +php artisan tinker +>>> DB::connection()->getPdo(); +``` + +### Performance Issues + +```bash +# Check slow query log +php artisan db:monitor + +# Optimize database +php artisan db:optimize + +# Clear all caches +php artisan optimize:clear +php artisan optimize +``` + +## Support + +For issues and questions, check: +- Application logs: `storage/logs/laravel.log` +- Web server logs: `/var/log/nginx/error.log` or `/var/log/apache2/error.log` +- PHP-FPM logs: `/var/log/php8.3-fpm.log` +- Supervisor logs: `/var/log/supervisor/supervisord.log` + +--- + +**Last Updated**: April 4, 2026 diff --git a/README.md b/README.md index 5ad1377..4c679e4 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,214 @@ -

Laravel Logo

+# JobifyGarden -

-Build Status -Total Downloads -Latest Stable Version -License -

+A comprehensive job aggregator platform built with Laravel 13 that fetches, stores, and displays job listings from multiple free job APIs. + +## Requirements + +- **PHP**: 8.3.x or higher +- **MySQL**: 8.0+ or MariaDB 10.3+ +- **Composer**: 2.x +- **Node.js**: 18.x or 20.x +- **Redis**: 6.x+ (for caching and queues) + +## Features + +### Core Functionality +- **Multi-Source Job Aggregation**: Fetch jobs from multiple APIs +- **Advanced Search & Filtering**: Full-text search, location, job type, experience level, salary range +- **Smart Deduplication**: Automatic detection and removal of duplicate listings +- **Job Enrichment**: Auto-categorization, geocoding, salary normalization +- **Real-time Analytics**: Track job views, searches, and user engagement + +### SEO & Marketing +- **Dynamic Meta Tags**: Job-specific title, description, and keywords +- **Structured Data**: Schema.org JobPosting markup for Google Jobs integration +- **XML Sitemaps**: Automatic sitemap generation for search engines +- **Social Sharing**: Open Graph and Twitter Card support +- **Mobile-First**: Responsive design optimized for all devices + +### Performance +- **Redis Caching**: Aggressive caching strategy for fast page loads +- **Database Optimization**: Proper indexing and query optimization +- **Queue Processing**: Background job processing for API fetching +- **Asset Optimization**: Minified CSS/JS with lazy loading + +### Monitoring & Analytics +- **API Metrics**: Track success rates, response times, errors +- **User Analytics**: Popular searches, viewed jobs, click-through rates +- **Admin Dashboard**: Real-time monitoring and statistics +- **Error Tracking**: Comprehensive logging and error handling + +## Installation + +### Development Setup + +1. **Clone the repository** +```bash +git clone +cd jobifygarden +``` + +2. **Install dependencies** +```bash +composer install +npm install +``` + +3. **Configure environment** +```bash +cp .env.example .env +php artisan key:generate +``` + +4. **Update `.env` with your database credentials** +```env +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=jobifygarden +DB_USERNAME=your_username +DB_PASSWORD=your_password +``` + +5. **Run migrations** +```bash +php artisan migrate +``` + +6. **Seed the database (optional)** +```bash +php artisan db:seed +``` + +7. **Build frontend assets** +```bash +npm run dev +``` + +8. **Start the development server** +```bash +php artisan serve +``` + +Visit `http://localhost:8000` to view the application. + +### Docker Setup (Laravel Sail) + +```bash +# Install dependencies +composer install + +# Start Docker containers +./vendor/bin/sail up -d + +# Run migrations +./vendor/bin/sail artisan migrate + +# Build assets +./vendor/bin/sail npm install +./vendor/bin/sail npm run dev +``` + +## Production Deployment + +See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed production deployment instructions. + +## Available Commands + +### Job Management +```bash +# Fetch jobs from all sources +php artisan jobs:fetch + +# Clean expired jobs +php artisan jobs:clean + +# Remove duplicate jobs +php artisan jobs:deduplicate + +# Enrich job data (categories, experience levels) +php artisan jobs:enrich + +# Test API integrations +php artisan jobs:test-apis +``` + +### Database Optimization +```bash +# Optimize database tables and rebuild indexes +php artisan db:optimize +``` + +### Cache Management +```bash +# Clear all caches +php artisan cache:clear +php artisan config:clear +php artisan route:clear +php artisan view:clear + +# Build caches for production +php artisan config:cache +php artisan route:cache +php artisan view:cache +``` + +## Project Structure + +``` +app/ +├── Console/Commands/ # Artisan commands +├── Http/Controllers/ # Web and API controllers +├── Models/ # Eloquent models +├── Repositories/ # Data access layer +├── Services/ # Business logic +└── Traits/ # Reusable traits + +database/ +├── migrations/ # Database migrations +└── seeders/ # Database seeders + +resources/ +├── views/ # Blade templates +├── js/ # JavaScript files +└── css/ # CSS files + +routes/ +├── web.php # Web routes +└── api.php # API routes +``` + +## API Endpoints + +### Public API +``` +GET /api/jobs # List jobs with filters +GET /api/jobs/{id} # Get job details +GET /api/categories # List categories +GET /api/jobs/autocomplete/titles # Title autocomplete +GET /api/jobs/autocomplete/locations # Location autocomplete +GET /api/jobs/autocomplete/companies # Company autocomplete +``` + +## Technology Stack + +### Backend +- **Laravel 13**: PHP framework +- **MySQL 8**: Primary database +- **Redis**: Caching and queues +- **Guzzle**: HTTP client for API requests + +### Frontend +- **Blade Templates**: Server-side rendering +- **Alpine.js**: Lightweight JavaScript framework +- **TailwindCSS**: Utility-first CSS framework +- **Vite**: Frontend build tool + +## License + +This project is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). + +--- ## About Laravel diff --git a/composer.lock b/composer.lock index 66ad3e7..c709ef2 100644 --- a/composer.lock +++ b/composer.lock @@ -6786,33 +6786,33 @@ }, { "name": "pestphp/pest", - "version": "v4.4.3", + "version": "v4.4.5", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495" + "reference": "9797a71dbc776f46d6fcacb708b002755da6f37a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/e6ab897594312728ef2e32d586cb4f6780b1b495", - "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495", + "url": "https://api.github.com/repos/pestphp/pest/zipball/9797a71dbc776f46d6fcacb708b002755da6f37a", + "reference": "9797a71dbc776f46d6fcacb708b002755da6f37a", "shasum": "" }, "require": { - "brianium/paratest": "^7.19.2", - "nunomaduro/collision": "^8.9.1", + "brianium/paratest": "^7.20.0", + "nunomaduro/collision": "^8.9.2", "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^4.0.0", "pestphp/pest-plugin-arch": "^4.0.0", "pestphp/pest-plugin-mutate": "^4.0.1", "pestphp/pest-plugin-profanity": "^4.2.1", "php": "^8.3.0", - "phpunit/phpunit": "^12.5.14", - "symfony/process": "^7.4.5|^8.0.5" + "phpunit/phpunit": "^12.5.16", + "symfony/process": "^7.4.8|^8.0.8" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">12.5.14", + "phpunit/phpunit": ">12.5.16", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, @@ -6820,7 +6820,7 @@ "pestphp/pest-dev-tools": "^4.1.0", "pestphp/pest-plugin-browser": "^4.3.0", "pestphp/pest-plugin-type-coverage": "^4.0.3", - "psy/psysh": "^0.12.21" + "psy/psysh": "^0.12.22" }, "bin": [ "bin/pest" @@ -6886,7 +6886,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.4.3" + "source": "https://github.com/pestphp/pest/tree/v4.4.5" }, "funding": [ { @@ -6898,7 +6898,7 @@ "type": "github" } ], - "time": "2026-03-21T13:14:39+00:00" + "time": "2026-04-03T13:43:28+00:00" }, { "name": "pestphp/pest-plugin", @@ -7935,16 +7935,16 @@ }, { "name": "phpunit/phpunit", - "version": "12.5.14", + "version": "12.5.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0" + "reference": "b2429f58ae75cae980b5bb9873abe4de6aac8b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/47283cfd98d553edcb1353591f4e255dc1bb61f0", - "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b2429f58ae75cae980b5bb9873abe4de6aac8b58", + "reference": "b2429f58ae75cae980b5bb9873abe4de6aac8b58", "shasum": "" }, "require": { @@ -7966,7 +7966,7 @@ "sebastian/cli-parser": "^4.2.0", "sebastian/comparator": "^7.1.4", "sebastian/diff": "^7.0.0", - "sebastian/environment": "^8.0.3", + "sebastian/environment": "^8.0.4", "sebastian/exporter": "^7.0.2", "sebastian/global-state": "^8.0.2", "sebastian/object-enumerator": "^7.0.0", @@ -8013,31 +8013,15 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.14" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.16" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" + "url": "https://phpunit.de/sponsoring.html", + "type": "other" } ], - "time": "2026-02-18T12:38:40+00:00" + "time": "2026-04-03T05:26:42+00:00" }, { "name": "sebastian/cli-parser", @@ -9237,12 +9221,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.3" }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" + "platform-dev": [], + "plugin-api-version": "2.2.0" }