Skip to main content

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

1

Prepare Environment

  • Server meets PHP 8.2+ requirements
  • Database is configured and secured
  • SSL certificate is installed
  • Domain DNS points to server
  • Firewall rules are configured
2

Configure Application

  • .env file set to production settings
  • APP_DEBUG=false
  • APP_ENV=production
  • Strong APP_KEY generated
  • Database credentials secured
3

Optimize Performance

  • Configuration cached
  • Routes cached
  • Views cached
  • Autoloader optimized
  • Redis configured (optional but recommended)
4

Set Up Automation

  • Cron job for scheduler configured
  • Log rotation enabled
  • Backup strategy implemented
5

Security Hardening

  • File permissions set correctly
  • .env file secured
  • HTTPS enforced
  • Rate limiting configured

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

Configure PHP-FPM

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

1

Clone Repository

cd /var/www
sudo git clone https://github.com/yourusername/mi-api-bcv.git
cd mi-api-bcv
2

Install Dependencies

composer install --no-dev --optimize-autoloader
The --no-dev flag skips development dependencies, and --optimize-autoloader improves performance.
3

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:
php artisan key:generate
4

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
5

Run Database Migrations

php artisan migrate --force
The --force flag is required in production.
6

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.
7

Fetch Initial Data

php artisan rates:update

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:
crontab -e
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

Performance Optimization

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

Configure Redis for Performance

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:
1

Enable Maintenance Mode (Optional)

php artisan down --retry=60 --secret="bypass-token"
Access site with: https://api.yourdomain.com?bypass-token
2

Pull Latest Changes

git pull origin main
3

Update Dependencies

composer install --no-dev --optimize-autoloader
4

Run Migrations

php artisan migrate --force
5

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
6

Restart Services

sudo systemctl reload php8.2-fpm
sudo systemctl reload nginx
7

Disable Maintenance Mode

php artisan up

Troubleshooting Production Issues

Causes:
  1. Incorrect file permissions
  2. Missing .env file
  3. 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
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

Production Monitoring Tools

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:
  • APP_DEBUG=false
  • APP_ENV=production
  • HTTPS enabled and working
  • Cron job configured for scheduler
  • Database backups automated
  • Logs rotating properly
  • File permissions set correctly
  • Configuration cached
  • Redis configured and running
  • Firewall rules configured
  • SSL certificate auto-renewal enabled
  • Monitoring and alerting set up
  • Initial exchange rates fetched
  • API endpoints tested

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.