Skip to main content

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=false in production
  • Strong database passwords
  • SSL certificates installed
  • Firewall configured
  • Rate limiting enabled
  • CORS configured properly
  • API keys secured
  • Regular security updates