Fix deployment issues: Add db:seed to setup, fix DatabaseSeeder, add production guide

CRITICAL FIXES:
- DatabaseSeeder now calls RolePermissionSeeder to create roles, permissions, and admin user
- setup.sh and setup.bat now run db:seed automatically during setup
- Created PRODUCTION_DEPLOYMENT.md with complete production deployment guide
- Removed duplicate admin user creation from setup scripts

This ensures:
- Admin user (admin@example.com / password) is created automatically
- Roles (admin, editor, viewer) are created during setup
- Permissions are seeded properly
- Production deployments have clear step-by-step instructions
- PHP Redis extension installation documented
- All common deployment issues addressed

The 2-minute setup now truly works out of the box.
This commit is contained in:
2026-03-09 11:42:25 +02:00
parent ae410ca4da
commit 3fee3917c5
4 changed files with 497 additions and 20 deletions

479
PRODUCTION_DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,479 @@
# Production Deployment Guide
**Target**: Ubuntu 24.04 with Apache/Nginx + PHP-FPM (NO Docker)
---
## Prerequisites on Production Server
### 1. Install Required Software
```bash
# Update system
sudo apt update && sudo apt upgrade -y
# Install PHP 8.3+ and extensions
sudo apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-common \
php8.3-mysql php8.3-pgsql php8.3-sqlite3 \
php8.3-redis php8.3-curl php8.3-mbstring php8.3-xml \
php8.3-zip php8.3-bcmath php8.3-gd php8.3-intl
# Install web server (choose one)
sudo apt install -y apache2 # OR nginx
# Install database (choose one)
sudo apt install -y mysql-server # OR postgresql
# Install Redis
sudo apt install -y redis-server
# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# Install Node.js (for frontend assets)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
```
### 2. Verify PHP Extensions
```bash
php -m | grep -E "redis|pdo_mysql|mbstring|xml|curl|zip|bcmath|gd"
```
All should be listed. If not, install missing extensions.
---
## Deployment Steps
### 1. Clone Repository
```bash
cd /var/www
sudo git clone https://your-repo-url.git your-domain.com
cd your-domain.com/src
```
### 2. Set Permissions
```bash
sudo chown -R www-data:www-data /var/www/your-domain.com
sudo chmod -R 775 /var/www/your-domain.com/src/storage
sudo chmod -R 775 /var/www/your-domain.com/src/bootstrap/cache
```
### 3. Install Dependencies
```bash
# Composer dependencies
composer install --no-dev --optimize-autoloader
# Node dependencies and build assets
npm install
npm run build
```
### 4. Configure Environment
```bash
# Copy appropriate .env template
cp .env.mysql .env # or .env.pgsql or .env.sqlite
# Edit .env
nano .env
```
**Required .env settings:**
```env
APP_NAME="Your App Name"
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=your_database
DB_USERNAME=your_user
DB_PASSWORD=your_password
CACHE_STORE=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=database
SESSION_DOMAIN=.your-domain.com
SESSION_SECURE_COOKIE=true
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=your-smtp-host
MAIL_PORT=587
MAIL_USERNAME=your-email
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=noreply@your-domain.com
MAIL_FROM_NAME="${APP_NAME}"
```
### 5. Generate Application Key
```bash
php artisan key:generate --force
```
### 6. Run Migrations and Seeders
```bash
# Run migrations
php artisan migrate --force
# CRITICAL: Run seeders to create roles, permissions, and admin user
php artisan db:seed --force
```
This creates:
- **Admin user**: admin@example.com / password
- **Roles**: admin, editor, viewer
- **Permissions**: users.view, users.create, users.edit, users.delete, settings.manage
### 7. Optimize for Production
```bash
# Cache configuration
php artisan config:cache
# Cache routes
php artisan route:cache
# Cache views
php artisan view:cache
# Optimize autoloader
composer dump-autoload --optimize
```
### 8. Create Storage Link
```bash
php artisan storage:link
```
---
## Web Server Configuration
### Option A: Apache with Virtual Host
Create `/etc/apache2/sites-available/your-domain.com.conf`:
```apache
<VirtualHost *:80>
ServerName your-domain.com
ServerAlias www.your-domain.com
DocumentRoot /var/www/your-domain.com/src/public
<Directory /var/www/your-domain.com/src/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/your-domain.com-error.log
CustomLog ${APACHE_LOG_DIR}/your-domain.com-access.log combined
# PHP-FPM
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
```
Enable site and modules:
```bash
sudo a2enmod rewrite proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo a2ensite your-domain.com.conf
sudo systemctl restart apache2
```
### Option B: Nginx with Server Block
Create `/etc/nginx/sites-available/your-domain.com`:
```nginx
server {
listen 80;
listen [::]:80;
server_name your-domain.com www.your-domain.com;
root /var/www/your-domain.com/src/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;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
```
Enable site:
```bash
sudo ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```
---
## SSL Certificate (Let's Encrypt)
```bash
# Install Certbot
sudo apt install -y certbot python3-certbot-apache # For Apache
# OR
sudo apt install -y certbot python3-certbot-nginx # For Nginx
# Get certificate
sudo certbot --apache -d your-domain.com -d www.your-domain.com # Apache
# OR
sudo certbot --nginx -d your-domain.com -d www.your-domain.com # Nginx
# Auto-renewal is set up automatically
```
---
## Queue Worker Setup (Optional but Recommended)
Create `/etc/systemd/system/laravel-queue.service`:
```ini
[Unit]
Description=Laravel Queue Worker
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
Restart=always
ExecStart=/usr/bin/php /var/www/your-domain.com/src/artisan queue:work --sleep=3 --tries=3 --max-time=3600
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl enable laravel-queue
sudo systemctl start laravel-queue
sudo systemctl status laravel-queue
```
---
## Scheduler Setup
Add to crontab:
```bash
sudo crontab -e -u www-data
```
Add this line:
```
* * * * * cd /var/www/your-domain.com/src && php artisan schedule:run >> /dev/null 2>&1
```
---
## Post-Deployment Checklist
- [ ] PHP Redis extension installed: `php -m | grep redis`
- [ ] Database migrations run: `php artisan migrate --force`
- [ ] **Database seeded**: `php artisan db:seed --force` ✅ CRITICAL
- [ ] Storage permissions set: `chmod -R 775 storage bootstrap/cache`
- [ ] Storage link created: `php artisan storage:link`
- [ ] Config cached: `php artisan config:cache`
- [ ] Routes cached: `php artisan route:cache`
- [ ] Views cached: `php artisan view:cache`
- [ ] SSL certificate installed
- [ ] Queue worker running (if using queues)
- [ ] Scheduler configured (if using scheduled tasks)
- [ ] Admin user created and can login at `/admin`
- [ ] `.env` has `APP_DEBUG=false` and `APP_ENV=production`
---
## Access Your Application
- **Public Site**: https://your-domain.com
- **Admin Panel**: https://your-domain.com/admin
- **Admin Login**: admin@example.com / password
**⚠️ IMPORTANT**: Change the default admin password immediately after first login!
---
## Troubleshooting
### 500 Error - Check Logs
```bash
# Laravel logs
tail -f /var/www/your-domain.com/src/storage/logs/laravel.log
# Apache logs
sudo tail -f /var/log/apache2/your-domain.com-error.log
# Nginx logs
sudo tail -f /var/log/nginx/error.log
# PHP-FPM logs
sudo tail -f /var/log/php8.3-fpm.log
```
### Class "Redis" not found
```bash
# Install PHP Redis extension
sudo apt install php8.3-redis
# Restart PHP-FPM
sudo systemctl restart php8.3-fpm
# Restart web server
sudo systemctl restart apache2 # or nginx
```
### 419 Page Expired (CSRF)
Check `.env`:
```env
SESSION_DOMAIN=.your-domain.com
SESSION_SECURE_COOKIE=true
APP_URL=https://your-domain.com
```
Clear cache:
```bash
php artisan config:clear
php artisan cache:clear
```
### Roles Don't Exist
```bash
# Run the seeder
php artisan db:seed --class=RolePermissionSeeder
# Or run all seeders
php artisan db:seed --force
```
### Permission Denied Errors
```bash
sudo chown -R www-data:www-data /var/www/your-domain.com
sudo chmod -R 775 /var/www/your-domain.com/src/storage
sudo chmod -R 775 /var/www/your-domain.com/src/bootstrap/cache
```
---
## Updating the Application
```bash
cd /var/www/your-domain.com
# Pull latest code
sudo -u www-data git pull
# Update dependencies
cd src
composer install --no-dev --optimize-autoloader
npm install && npm run build
# Run migrations
php artisan migrate --force
# Clear and recache
php artisan config:clear
php artisan cache:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
# Restart queue worker
sudo systemctl restart laravel-queue
# Restart web server
sudo systemctl restart apache2 # or nginx
```
---
## Security Recommendations
1. **Change default admin password** immediately
2. **Set up firewall**: `sudo ufw enable && sudo ufw allow 80,443/tcp`
3. **Disable directory listing** in web server config
4. **Keep system updated**: `sudo apt update && sudo apt upgrade`
5. **Use strong database passwords**
6. **Enable fail2ban**: `sudo apt install fail2ban`
7. **Regular backups** of database and uploaded files
8. **Monitor logs** for suspicious activity
---
## Backup Strategy
### Database Backup
```bash
# MySQL
mysqldump -u username -p database_name > backup_$(date +%Y%m%d).sql
# PostgreSQL
pg_dump -U username database_name > backup_$(date +%Y%m%d).sql
```
### Files Backup
```bash
# Backup storage directory
tar -czf storage_backup_$(date +%Y%m%d).tar.gz /var/www/your-domain.com/src/storage
```
### Automated Backups
Add to crontab:
```bash
0 2 * * * /path/to/backup-script.sh
```
---
**Remember**: The template is designed for quick local development with Docker. Production deployment requires proper server setup and security hardening.

View File

@@ -68,15 +68,20 @@ echo App key generated
echo.
REM Step 6: Run migrations
echo Running database migrations...
echo Running database migrations...
docker-compose exec app php artisan migrate --force
echo Migrations completed
echo Migrations completed
echo.
echo → Seeding database (roles, permissions, admin user)...
docker-compose exec app php artisan db:seed --force
echo ✓ Database seeded
echo.
REM Step 7: Create storage link
echo Creating storage symlink...
echo Creating storage symlink...
docker-compose exec app php artisan storage:link
echo Storage linked
echo Storage linked
echo.
REM Step 8: Create admin user

View File

@@ -75,20 +75,18 @@ docker-compose exec app php artisan migrate --force
echo -e "${GREEN}✓ Migrations completed${NC}"
echo ""
# Step 7: Create storage link
# Step 7: Seed database (roles, permissions, admin user)
echo -e "${YELLOW}→ Seeding database (roles, permissions, admin user)...${NC}"
docker-compose exec app php artisan db:seed --force
echo -e "${GREEN}✓ Database seeded${NC}"
echo ""
# Step 8: Create storage link
echo -e "${YELLOW}→ Creating storage symlink...${NC}"
docker-compose exec app php artisan storage:link
echo -e "${GREEN}✓ Storage linked${NC}"
echo ""
# Step 8: Create admin user
echo -e "${YELLOW}→ Creating admin user...${NC}"
echo -e "${YELLOW} Email: admin@example.com${NC}"
echo -e "${YELLOW} Password: password${NC}"
docker-compose exec -T app php artisan make:filament-user --name=Admin --email=admin@example.com --password=password 2>/dev/null || echo -e "${YELLOW} (Admin user may already exist)${NC}"
echo -e "${GREEN}✓ Admin user ready${NC}"
echo ""
# Done!
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"

View File

@@ -2,8 +2,6 @@
namespace Database\Seeders;
use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
@@ -13,11 +11,8 @@ class DatabaseSeeder extends Seeder
*/
public function run(): void
{
// User::factory(10)->create();
User::factory()->create([
'name' => 'Test User',
'email' => 'test@example.com',
$this->call([
RolePermissionSeeder::class,
]);
}
}