Skip to content

Deployment

Saiful Alam Rakib edited this page Apr 22, 2026 · 1 revision

Deployment

How to deploy Bill Organizer to a production server.


Requirements

Requirement Minimum
PHP 8.3+
Database MySQL 8.0+ (or SQLite for small deployments)
Web Server Apache 2.4+ or Nginx
Node.js 18+ (build step only)
Composer Latest

Deploying from a Release ZIP

The easiest way to deploy is from a pre-built ZIP artifact created by the Release Workflow.

Steps

  1. Download the latest ZIP from the GitHub Releases page
  2. Extract to your web server document root (or a subdirectory)
  3. Configure environment:
    cp .env.example .env
    php artisan key:generate
  4. Edit .env with your production values (see Environment Variables below)
  5. Run migrations:
    php artisan migrate --force
  6. Set permissions:
    chmod -R 755 storage bootstrap/cache
    chown -R www-data:www-data storage bootstrap/cache
  7. Point your web server to the public/ directory

Deploying from Source

1. Clone the Repository

git clone https://github.com/4msar/bill-organizer.git
cd bill-organizer

2. Install Dependencies

composer install --no-dev --optimize-autoloader
yarn install --frozen-lockfile

3. Build Frontend Assets

yarn build

4. Configure Environment

cp .env.example .env
php artisan key:generate

5. Run Migrations

php artisan migrate --force

6. Optimize Laravel

php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan optimize

7. Set Permissions

chmod -R 755 storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache

Environment Variables

Key .env settings for production:

# Application
APP_NAME="Bill Organizer"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

# Database
DB_CONNECTION=mysql
DB_HOST=your-database-host
DB_PORT=3306
DB_DATABASE=bill_organizer
DB_USERNAME=dbuser
DB_PASSWORD=dbpassword

# Mail
MAIL_MAILER=smtp
MAIL_HOST=your-smtp-host
MAIL_PORT=587
MAIL_USERNAME=your-email@domain.com
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="noreply@yourdomain.com"
MAIL_FROM_NAME="${APP_NAME}"

# Queue
QUEUE_CONNECTION=database

# Security
SESSION_SECURE_COOKIE=true
FORCE_HTTPS=true

# API
SANCTUM_STATEFUL_DOMAINS=yourdomain.com
CORS_ALLOWED_ORIGINS=https://yourdomain.com
API_RATE_LIMIT=60

Web Server Configuration

Nginx

server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/bill-organizer/public;

    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.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Apache

Create or update .htaccess in the project root (Laravel includes one by default):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

The public/.htaccess file handles routing inside the application.


Queue Workers

Bill Organizer uses database queues for notifications and webhook deliveries. Queue workers must be running in production.

Using Supervisor (recommended)

Create /etc/supervisor/conf.d/bill-organizer-worker.conf:

[program:bill-organizer-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/bill-organizer/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/bill-organizer/storage/logs/worker.log
stopwaitsecs=3600
supervisorctl reread
supervisorctl update
supervisorctl start bill-organizer-worker:*

Manual (development only)

php artisan queue:work

Task Scheduler

The scheduler handles automatic notifications and recurring bill updates. Add this cron entry:

* * * * * cd /var/www/bill-organizer && php artisan schedule:run >> /dev/null 2>&1

Docker Production

# Build image
docker build -t bill-organizer .

# Run with Docker Compose (production config)
docker-compose -f docker-compose.prod.yml up -d

Post-Deployment Checklist

  • APP_ENV=production and APP_DEBUG=false
  • Application key generated (php artisan key:generate)
  • Database migrated (php artisan migrate --force)
  • All caches optimized (php artisan optimize)
  • File permissions set on storage/ and bootstrap/cache/
  • Web server pointing to public/ directory
  • HTTPS / SSL configured
  • Queue workers running (via Supervisor or similar)
  • Cron scheduler configured
  • Mail settings tested
  • CORS and Sanctum domains configured
  • Database backups scheduled

Updating an Existing Installation

# Pull latest code (if deploying from source)
git pull origin main

# Update dependencies
composer install --no-dev --optimize-autoloader
yarn install --frozen-lockfile
yarn build

# Run any new migrations
php artisan migrate --force

# Clear and rebuild caches
php artisan optimize:clear
php artisan optimize

# Restart queue workers
php artisan queue:restart

Live Link: bills.msar.me

API Docs: API

Open API Collection: API Collection

Clone this wiki locally