Documentation Index Fetch the complete documentation index at: https://mintlify.com/MiguelNavas19/miapibcv/llms.txt
Use this file to discover all available pages before exploring further.
Deployment Overview
This guide covers deploying Mi API BCV to a production environment with proper security, performance, and reliability configurations.
Prerequisites
Before deploying, ensure you have:
A server with PHP 8.2+ installed
Web server (Nginx or Apache)
Database server (MySQL, PostgreSQL, or SQLite)
Domain name with DNS configured
SSL certificate (Let’s Encrypt recommended)
SSH access to your server
Production Checklist
Server Setup
Option 1: Ubuntu/Debian Server
Install Required Packages
# Update system
sudo apt update && sudo apt upgrade -y
# Install PHP 8.2 and extensions
sudo apt install -y php8.2 php8.2-fpm php8.2-cli php8.2-common \
php8.2-mysql php8.2-xml php8.2-mbstring php8.2-curl \
php8.2-zip php8.2-bcmath php8.2-sqlite3 php8.2-redis
# Install Nginx
sudo apt install -y nginx
# Install MySQL (or use existing database)
sudo apt install -y mysql-server
# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
# Install Redis (optional but recommended)
sudo apt install -y redis-server
Edit /etc/php/8.2/fpm/php.ini:
upload_max_filesize = 20M
post_max_size = 20M
memory_limit = 256M
max_execution_time = 300
date.timezone = America/Caracas
Restart PHP-FPM:
sudo systemctl restart php8.2-fpm
Option 2: Using Docker
Create Dockerfile:
FROM php:8.2-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www
# Copy application
COPY . /var/www
# Install dependencies
RUN composer install --no-dev --optimize-autoloader
# Set permissions
RUN chown -R www-data:www-data /var/www
EXPOSE 9000
CMD [ "php-fpm" ]
Create docker-compose.yml:
version : '3.8'
services :
app :
build :
context : .
dockerfile : Dockerfile
container_name : mi-api-bcv
volumes :
- .:/var/www
networks :
- app-network
nginx :
image : nginx:alpine
container_name : mi-api-bcv-nginx
ports :
- "80:80"
- "443:443"
volumes :
- .:/var/www
- ./nginx.conf:/etc/nginx/conf.d/default.conf
networks :
- app-network
db :
image : mysql:8.0
container_name : mi-api-bcv-db
environment :
MYSQL_DATABASE : mi_api_bcv
MYSQL_ROOT_PASSWORD : secret
volumes :
- dbdata:/var/lib/mysql
networks :
- app-network
redis :
image : redis:alpine
container_name : mi-api-bcv-redis
networks :
- app-network
networks :
app-network :
driver : bridge
volumes :
dbdata :
Deploy Application
Clone Repository
cd /var/www
sudo git clone https://github.com/yourusername/mi-api-bcv.git
cd mi-api-bcv
Install Dependencies
composer install --no-dev --optimize-autoloader
The --no-dev flag skips development dependencies, and --optimize-autoloader improves performance.
Configure Environment
cp .env.example .env
nano .env
Production .env settings: APP_NAME="Mi API BCV"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://api.yourdomain.com
LOG_CHANNEL=daily
LOG_LEVEL=error
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mi_api_bcv
DB_USERNAME=api_user
DB_PASSWORD=your_secure_password
CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
Generate application key:
Set File Permissions
sudo chown -R www-data:www-data /var/www/mi-api-bcv
sudo chmod -R 755 /var/www/mi-api-bcv
sudo chmod -R 775 /var/www/mi-api-bcv/storage
sudo chmod -R 775 /var/www/mi-api-bcv/bootstrap/cache
Run Database Migrations
php artisan migrate --force
The --force flag is required in production.
Optimize for Production
# Cache configuration
php artisan config:cache
# Cache routes
php artisan route:cache
# Cache views
php artisan view:cache
# Optimize autoloader
composer dump-autoload --optimize
After caching, changes to config files won’t take effect until you clear the cache.
Web Server Configuration
Nginx Configuration
Create /etc/nginx/sites-available/mi-api-bcv:
server {
listen 80 ;
listen [::]:80;
server_name api.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$ server_name $ request_uri ;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.yourdomain.com;
root /var/www/mi-api-bcv/public;
index index.php;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on ;
# 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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Logging
access_log /var/log/nginx/mi-api-bcv-access.log;
error_log /var/log/nginx/mi-api-bcv-error.log;
# Rate Limiting (optional)
limit_req_zone $ binary_remote_addr zone=api:10m rate=60r/m;
limit_req zone=api burst=10 nodelay;
location / {
try_files $ uri $ uri / /index.php?$ query_string ;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-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 ;
}
# Cache static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable" ;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/mi-api-bcv /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Apache Configuration
Create /etc/apache2/sites-available/mi-api-bcv.conf:
< VirtualHost *:80 >
ServerName api.yourdomain.com
Redirect permanent / https://api.yourdomain.com/
</ VirtualHost >
< VirtualHost *:443 >
ServerName api.yourdomain.com
DocumentRoot /var/www/mi-api-bcv/public
< Directory /var/www/mi-api-bcv/public >
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</ Directory >
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/api.yourdomain.com/privkey.pem
# Security Headers
Header always set X-Frame- Options "SAMEORIGIN"
Header always set X-Content-Type- Options "nosniff"
Header always set X-XSS-Protection " 1 ; mode=block"
Header always set Strict-Transport-Security "max-age= 31536000 ; includeSubDomains"
# Logging
ErrorLog ${APACHE_LOG_DIR}/mi-api-bcv-error.log
CustomLog ${APACHE_LOG_DIR}/mi-api-bcv-access.log combined
</ VirtualHost >
Enable modules and site:
sudo a2enmod rewrite ssl headers
sudo a2ensite mi-api-bcv
sudo systemctl reload apache2
SSL Certificate (Let’s Encrypt)
Install Certbot:
sudo apt install -y certbot python3-certbot-nginx
Obtain certificate:
sudo certbot --nginx -d api.yourdomain.com
Auto-renewal is configured automatically. Test renewal:
sudo certbot renew --dry-run
Set Up Cron Jobs
The scheduler must run every minute to trigger scheduled tasks:
Add:
* * * * * cd /var/www/mi-api-bcv && php artisan schedule:run >> /dev/null 2>&1
Verify the scheduler configuration in routes/console.php:
$schedules = [
'00:00' , '00:30' , '02:00' , '03:00' , '03:30' , '04:00' ,
'05:00' , '05:30' , '06:30' , '07:00' , '07:30'
];
foreach ( $schedules as $time ) {
Schedule :: command ( 'rates:update' ) -> dailyAt ( $time );
}
This runs the rates:update command 11 times daily.
Monitoring & Logging
Log Rotation
Create /etc/logrotate.d/mi-api-bcv:
/var/www/mi-api-bcv/storage/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0644 www-data www-data
sharedscripts
}
Monitor Logs
# Follow Laravel logs
tail -f /var/www/mi-api-bcv/storage/logs/laravel.log
# Follow Nginx access logs
tail -f /var/log/nginx/mi-api-bcv-access.log
# Follow Nginx error logs
tail -f /var/log/nginx/mi-api-bcv-error.log
Health Checks
Laravel 12 includes a health check endpoint:
curl https://api.yourdomain.com/up
Backup Strategy
Database Backup
Create backup script /usr/local/bin/backup-mi-api-bcv.sh:
#!/bin/bash
BACKUP_DIR = "/var/backups/mi-api-bcv"
DATE = $( date +%Y%m%d_%H%M%S )
DB_NAME = "mi_api_bcv"
DB_USER = "api_user"
DB_PASS = "your_password"
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup database
mysqldump -u $DB_USER -p $DB_PASS $DB_NAME | gzip > $BACKUP_DIR /db_ $DATE .sql.gz
# Remove backups older than 30 days
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +30 -delete
echo "Backup completed: db_ $DATE .sql.gz"
Make executable and schedule:
chmod +x /usr/local/bin/backup-mi-api-bcv.sh
# Add to crontab
crontab -e
# Daily backup at 2 AM
0 2 * * * /usr/local/bin/backup-mi-api-bcv.sh
Application Backup
# Backup entire application
tar -czf /var/backups/mi-api-bcv_ $( date +%Y%m%d ) .tar.gz /var/www/mi-api-bcv
Enable OPcache
Edit /etc/php/8.2/fpm/conf.d/10-opcache.ini:
opcache.enable =1
opcache.memory_consumption =256
opcache.interned_strings_buffer =16
opcache.max_accelerated_files =10000
opcache.validate_timestamps =0
opcache.save_comments =1
opcache.fast_shutdown =1
Restart PHP-FPM:
sudo systemctl restart php8.2-fpm
Edit /etc/redis/redis.conf:
maxmemory 256mb
maxmemory-policy allkeys-lru
Restart Redis:
sudo systemctl restart redis
Database Indexing
Add indexes to improve query performance:
USE mi_api_bcv;
-- Add indexes to reference_records table
CREATE INDEX idx_date ON reference_records( date );
CREATE INDEX idx_source ON reference_records(source);
CREATE INDEX idx_date_source ON reference_records( date , source);
Security Hardening
Firewall Configuration
# Allow SSH
sudo ufw allow 22/tcp
# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Enable firewall
sudo ufw enable
Secure .env File
chmod 600 /var/www/mi-api-bcv/.env
chown www-data:www-data /var/www/mi-api-bcv/.env
Disable Directory Listing
Already handled in Nginx/Apache configs with -Indexes.
Rate Limiting
Nginx rate limiting is configured in the server block above:
limit_req_zone $ binary_remote_addr zone=api:10m rate=60r/m;
limit_req zone=api burst=10 nodelay;
This allows 60 requests per minute per IP with a burst of 10.
Zero-Downtime Deployment
For updates without downtime:
Enable Maintenance Mode (Optional)
php artisan down --retry=60 --secret= "bypass-token"
Access site with: https://api.yourdomain.com?bypass-token
Update Dependencies
composer install --no-dev --optimize-autoloader
Run Migrations
php artisan migrate --force
Clear and Rebuild Caches
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
Restart Services
sudo systemctl reload php8.2-fpm
sudo systemctl reload nginx
Troubleshooting Production Issues
500 Internal Server Error
Causes :
Incorrect file permissions
Missing .env file
Uncached configuration errors
Solutions :# Check logs
tail -f storage/logs/laravel.log
tail -f /var/log/nginx/mi-api-bcv-error.log
# Fix permissions
sudo chown -R www-data:www-data /var/www/mi-api-bcv
sudo chmod -R 775 storage bootstrap/cache
# Clear caches
php artisan config:clear
php artisan cache:clear
Check :# Verify cron is running
sudo systemctl status cron
# Check crontab
crontab -l
# Test scheduler manually
php artisan schedule:run
Debug :# Add logging to cron
* * * * * cd /var/www/mi-api-bcv && php artisan schedule:run >> /var/log/scheduler.log 2>&1
Database Connection Issues
Check :# Test database connection
php artisan tinker
DB::connection () ->getPdo ();
# Verify MySQL is running
sudo systemctl status mysql
# Check credentials
mysql -u api_user -p mi_api_bcv
Solutions :# Increase PHP memory limit
# Edit /etc/php/8.2/fpm/php.ini
memory_limit = 512M
# Restart PHP-FPM
sudo systemctl restart php8.2-fpm
# Clear old logs
find storage/logs -name "*.log" -mtime +7 -delete
Laravel Telescope (Development/Staging)
composer require laravel/telescope --dev
php artisan telescope:install
php artisan migrate
Only use Telescope in development/staging, not production. It adds significant overhead.
External Monitoring
Consider using:
New Relic - Application performance monitoring
Datadog - Infrastructure and application monitoring
Sentry - Error tracking and monitoring
UptimeRobot - Uptime monitoring
Deployment Checklist
Before going live:
Summary
Your Mi API BCV deployment should now be:
Secure : HTTPS, proper permissions, hardened
Fast : Caching, OPcache, optimized autoloader
Reliable : Automated updates, backups, monitoring
Scalable : Redis cache, optimized database
For updates, follow the zero-downtime deployment process to keep your API running smoothly.