Deployment Guide
Production deployment guide for ZÈYA API.
Pre-Deployment Checklist
- All tests passing
- Environment variables configured
- Database migrations ready
- Queue workers configured
- Cron jobs set up
- SSL certificates installed
- Backup strategy in place
Build for Production
1. Install Production Dependencies
composer install --optimize-autoloader --no-dev
2. Cache Configuration
# Cache configuration
php artisan config:cache
# Cache routes
php artisan route:cache
# Cache views
php artisan view:cache
# Or cache everything
php artisan optimize
3. Run Migrations
php artisan migrate --force
4. Set Permissions
chmod -R 775 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
Environment Configuration
Production .env
Key production settings:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.zeya.app
# Database
DB_CONNECTION=mysql
DB_HOST=your-db-host
DB_DATABASE=zeya_production
DB_USERNAME=your-username
DB_PASSWORD=your-secure-password
# Cache/Queue
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=your-redis-host
REDIS_PASSWORD=your-redis-password
# AWS S3
AWS_ACCESS_KEY_ID=your-key
AWS_SECRET_ACCESS_KEY=your-secret
AWS_BUCKET=zeya-production
# JWT
JWT_SECRET=your-jwt-secret
JWT_TTL=60
# Firebase
FIREBASE_CREDENTIALS=/path/to/firebase-credentials.json
FIREBASE_DATABASE_URL=https://your-project.firebaseio.com
Queue Workers
Supervisor Configuration
Create /etc/supervisor/conf.d/zeya-worker.conf:
[program:zeya-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/api/artisan queue:work redis --sleep=3 --tries=3 --timeout=90
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/path/to/api/storage/logs/worker.log
stopwaitsecs=3600
Start supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start zeya-worker:*
Cron Jobs
Add to crontab:
* * * * * cd /path/to/api && php artisan schedule:run >> /dev/null 2>&1
Or add to /etc/cron.d/zeya:
* * * * * www-data cd /path/to/api && php artisan schedule:run >> /dev/null 2>&1
Web Server Configuration
Nginx Configuration
Example Nginx configuration:
server {
listen 80;
server_name api.zeya.app;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.zeya.app;
root /path/to/api/public;
ssl_certificate /path/to/ssl/cert.pem;
ssl_certificate_key /path/to/ssl/key.pem;
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.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Apache Configuration
Example Apache .htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Docker Deployment
Production Dockerfile
The project includes docker/Dockerfile.production:
# Build image
docker build -f docker/Dockerfile.production -t zeya-api:latest .
# Run container
docker run -d \
--name zeya-api \
-p 80:80 \
-v /path/to/.env:/var/www/html/.env \
zeya-api:latest
Docker Compose
Example docker-compose.yml:
version: '3.8'
services:
app:
build:
context: .
dockerfile: docker/Dockerfile.production
volumes:
- ./storage:/var/www/html/storage
- ./.env:/var/www/html/.env
depends_on:
- redis
- mysql
redis:
image: redis:alpine
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: zeya
MYSQL_ROOT_PASSWORD: password
Monitoring
Health Check Endpoint
Monitor application health:
curl https://api.zeya.app/api/health
Log Monitoring
Monitor application logs:
tail -f storage/logs/laravel.log
Queue Monitoring
Monitor queue status:
php artisan queue:monitor redis --max=100
Backup Strategy
Database Backup
# Daily backup script
mysqldump -u username -p zeya_production > backup_$(date +%Y%m%d).sql
File Backup
Backup S3 files or use S3 versioning.
Rollback Procedure
1. Revert Code
git checkout previous-version-tag
2. Rollback Migrations (if needed)
php artisan migrate:rollback --step=1
3. Clear Cache
php artisan optimize:clear
4. Restart Services
sudo supervisorctl restart zeya-worker:*
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
Performance Optimization
1. Enable OPcache
In php.ini:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
2. Database Optimization
- Add indexes for frequently queried columns
- Use query caching
- Optimize slow queries
3. Redis Optimization
- Configure Redis memory limits
- Use Redis persistence
- Monitor Redis performance
Security Checklist
-
APP_DEBUG=falsein production - Strong database passwords
- SSL certificates installed
- Firewall configured
- Rate limiting enabled
- CORS configured properly
- API keys secured
- Regular security updates