Skip to main content
Deploying Cashify to production requires careful attention to security, performance, and reliability. This guide covers the essential steps for a production-ready deployment.

Pre-deployment checklist

Before deploying to production, ensure you have:

Environment configured

Production .env file with secure credentials

Database ready

Production database server configured and accessible

Domain setup

Domain name configured with SSL certificate

Backups planned

Database and file backup strategy in place

Environment configuration

Production environment file

Create a production .env file with these critical changes:
.env
APP_NAME=Cashify
APP_ENV=production
APP_KEY=base64:YOUR_GENERATED_KEY_HERE
APP_DEBUG=false
APP_URL=https://your-domain.com

# Use a production-grade database
DB_CONNECTION=mysql
DB_HOST=your-db-host
DB_PORT=3306
DB_DATABASE=cashify_production
DB_USERNAME=cashify_user
DB_PASSWORD=your-secure-password

# Session and cache
SESSION_DRIVER=database
CACHE_STORE=redis
QUEUE_CONNECTION=redis

# Redis for better performance
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=your-redis-password
REDIS_PORT=6379

# Production mail settings
MAIL_MAILER=mailtrap
MAILTRAP_HOST=send.api.mailtrap.io
MAILTRAP_API_KEY=your-production-api-key
MAIL_FROM_ADDRESS=[email protected]
MAIL_FROM_NAME=Cashify

# OAuth credentials
GITHUB_CLIENT_ID=your-production-github-client-id
GITHUB_CLIENT_SECRET=your-production-github-secret
GITHUB_REDIRECT=https://your-domain.com/auth/github/callback

# Turnstile CAPTCHA
TURNSTILE_SITE_KEY=your-production-site-key
TURNSTILE_SECRET_KEY=your-production-secret-key
Never commit your production .env file to version control. Use secure deployment tools to manage environment variables.

Critical environment variables

APP_ENV
string
required
Must be set to production to disable debug mode and enable optimizations
APP_DEBUG
boolean
required
Must be false in production to prevent sensitive information leaks
APP_KEY
string
required
Generate with php artisan key:generate. Used for encryption and security
DB_CONNECTION
string
required
Use mysql or pgsql for production. SQLite is not recommended for production

Deployment steps

1

Clone the repository

Clone your Cashify repository to the production server:
git clone https://github.com/yyordan0v/cashify.git
cd cashify
2

Install dependencies

Install PHP and Node.js dependencies:
composer install --no-dev --optimize-autoloader
npm install --production
The --no-dev flag excludes development dependencies, reducing the deployment size.
3

Configure environment

Create and configure your production .env file:
cp .env.example .env
nano .env  # Edit with your production values
php artisan key:generate
4

Run database migrations

Set up the production database:
php artisan migrate --force
The --force flag is required in production. Always backup your database before running migrations.
5

Build frontend assets

Compile and optimize frontend assets:
npm run build
This creates optimized production builds of your CSS and JavaScript.
6

Optimize application

Run Laravel optimization commands:
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize
These commands cache configuration, routes, and views for better performance.
7

Set file permissions

Configure proper file permissions:
chmod -R 755 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
Adjust www-data to match your web server user.
8

Configure web server

Point your web server to the public directory. See the hosting guide for specific configurations.

Performance optimizations

Enable OPcache

Enable PHP OPcache for significant performance improvements:
php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2

Use Redis for caching

Redis provides better performance than file-based caching:
sudo apt-get install redis-server
sudo systemctl enable redis-server
sudo systemctl start redis-server
Update your .env:
CACHE_STORE=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

Database optimization

For MySQL/MariaDB, optimize your database configuration:
-- Add indexes for common queries
CREATE INDEX idx_transactions_user_created ON transactions(user_id, created_at);
CREATE INDEX idx_categories_user_type ON categories(user_id, type);

Security best practices

Always use HTTPS in production. Obtain a free SSL certificate from Let’s Encrypt:
sudo certbot --nginx -d your-domain.com
If your API is accessed from different domains, configure CORS properly in config/cors.php.
The application includes rate limiting on authentication routes. Monitor and adjust as needed in routes/auth.php.
Use a dedicated database user with minimal permissions:
CREATE USER 'cashify_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON cashify_production.* TO 'cashify_user'@'localhost';
FLUSH PRIVILEGES;
Ensure sensitive files are not publicly accessible:
chmod 600 .env
chmod -R 755 storage
chmod -R 755 bootstrap/cache

Monitoring and logging

Application logs

Configure logging for production in .env:
LOG_CHANNEL=stack
LOG_STACK=daily
LOG_LEVEL=error
Logs are stored in storage/logs/laravel.log.

Laravel Telescope

Cashify includes Laravel Telescope for debugging. In production, restrict access or disable it:
config/telescope.php
'enabled' => env('TELESCOPE_ENABLED', false),
Or protect it with authentication in app/Providers/TelescopeServiceProvider.php.

Health checks

Set up a health check endpoint for monitoring:
routes/web.php
Route::get('/health', function () {
    return response()->json(['status' => 'ok']);
});

Backup strategy

Database backups

Schedule regular database backups:
#!/bin/bash
# backup-db.sh
BACKUP_DIR="/backups/cashify"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR
mysqldump -u cashify_user -p cashify_production > $BACKUP_DIR/backup_$DATE.sql
gzip $BACKUP_DIR/backup_$DATE.sql

# Keep only last 30 days
find $BACKUP_DIR -name "backup_*.sql.gz" -mtime +30 -delete
Add to crontab:
0 2 * * * /path/to/backup-db.sh

File backups

Backup uploaded files and important directories:
tar -czf cashify-files-$(date +%Y%m%d).tar.gz storage/app public/images

Zero-downtime deployment

For zero-downtime deployments, use tools like:
  • Laravel Envoyer - Official Laravel deployment service
  • Deployer - PHP deployment tool
  • GitHub Actions - Automated CI/CD pipeline
Example GitHub Actions workflow:
.github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /var/www/cashify
            git pull origin main
            composer install --no-dev --optimize-autoloader
            npm run build
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache

Troubleshooting

Check Laravel logs in storage/logs/laravel.log and ensure:
  • .env file exists and is readable
  • APP_KEY is set
  • Database connection is configured correctly
  • File permissions are correct on storage and bootstrap/cache
Run npm run build and ensure:
  • Vite manifest exists in public/build
  • Web server serves files from the public directory
  • APP_URL matches your domain
Ensure:
  • SESSION_DRIVER=database in .env
  • Sessions table exists (run migrations)
  • SESSION_DOMAIN is configured correctly for your domain
Verify:
  • Mailtrap API key is correct
  • MAIL_FROM_ADDRESS is valid
  • Check logs for SMTP errors

Next steps

Hosting options

Explore different hosting solutions for Cashify

Configuration

Learn more about environment configuration

Build docs developers (and LLMs) love