Deploying Bigcapital
Bigcapital is a comprehensive, open-source accounting and financial management platform designed for small to medium-sized businesses. Built with modern web technologies, Bigcapital provides a complete solution for managing invoices, expenses, customers, vendors, and financial reporting without the complexity or cost of traditional accounting software. With an intuitive interface and powerful features, Bigcapital enables business owners and accountants to take full control of their financial data while maintaining complete privacy and data ownership.
Why Bigcapital?
Bigcapital stands out in the accounting software landscape with its open-source approach and comprehensive feature set:
- Complete Accounting: Double-entry bookkeeping system with full GL, AR, and AP management
- Invoicing: Professional invoice generation with customizable templates and automatic numbering
- Expense Tracking: Record and categorize business expenses with receipt attachments
- Multi-Currency Support: Handle transactions in multiple currencies with automatic conversion
- Financial Reports: Generate profit & loss, balance sheets, cash flow, and aging reports
- Customer Management: Maintain detailed customer information with invoice history
- Vendor Management: Track vendor relationships and payment obligations
- Tax Compliance: Track tax liabilities and generate tax reports
- User Roles: Granular permission system for multi-user access
- Customizable Chart of Accounts: Design your accounting structure to match business needs
- API Integration: REST API for integrating with other business applications
- Data Privacy: All data stays on your server—complete control and security
- No Licensing Costs: Open-source platform with no per-user fees
- Mobile Access: Responsive design for managing finances on the go
- Audit Trail: Complete logging of all accounting transactions and changes
Bigcapital is ideal for freelancers, small business owners, accounting firms, nonprofits, and any organization that needs reliable financial management without vendor lock-in. With persistent storage on Klutch.sh, your financial records are always safe, secure, and accessible.
Prerequisites
Before deploying Bigcapital, ensure you have:
- A Klutch.sh account
- A GitHub repository with your Bigcapital deployment configuration
- Basic familiarity with Docker, Git, and accounting principles
- Node.js knowledge (helpful but not required for deployment)
- A domain name (recommended for professional appearance)
- MySQL or PostgreSQL database access (local or external)
Important Considerations
Deploying Bigcapital
Create a New Project
Log in to your Klutch.sh dashboard and create a new project for your Bigcapital deployment.
Prepare Your Repository
Create a GitHub repository with the following structure for your Bigcapital deployment:
bigcapital-deploy/├─ Dockerfile├─ .env.example├─ docker-entrypoint.sh├─ .gitignore└─ README.mdHere’s a Dockerfile for Bigcapital:
FROM node:18-alpine# Install required dependenciesRUN apk add --no-cache \python3 \make \g++ \curl \supervisor \nginx# Set working directoryWORKDIR /app# Clone Bigcapital repositoryRUN git clone https://github.com/bigcapitalio/bigcapital.git . && \git checkout main# Install dependenciesRUN npm ci --legacy-peer-deps && \npm run build# Create necessary directoriesRUN mkdir -p /app/logs /app/storage /app/uploads && \chown -R node:node /app# Copy entrypoint scriptCOPY docker-entrypoint.sh /RUN chmod +x /docker-entrypoint.sh# Switch to node user for securityUSER node# Expose portEXPOSE 3000# Health checkHEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \CMD curl -f http://localhost:3000/api/health || exit 1# Run entrypointENTRYPOINT ["/docker-entrypoint.sh"]CMD ["start"]Create a
docker-entrypoint.shfile for managing startup processes:#!/bin/sh# Function to wait for databasewait_for_db() {echo "Waiting for database connection..."MAX_ATTEMPTS=30ATTEMPTS=0while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; doif npm run db:test 2>/dev/null; thenecho "Database is ready!"return 0fiATTEMPTS=$((ATTEMPTS + 1))sleep 1doneecho "Database connection failed after $MAX_ATTEMPTS attempts"return 1}# Wait for database if configuredif [ -n "$DB_HOST" ]; thenwait_for_db || exit 1fi# Run database migrations on first startupif [ ! -f /app/storage/initialized ]; thenecho "Running database migrations..."npm run db:migratetouch /app/storage/initializedfiif [ "$1" = "start" ]; then# Start the applicationnpm run startelseexec "$@"fiCreate a
.env.examplefile:Terminal window # Application ConfigurationAPP_URL=https://yourdomain.comAPP_PORT=3000APP_ENV=productionNODE_ENV=productionAPP_DEBUG=false# Database ConfigurationDB_HOST=localhostDB_PORT=3306DB_NAME=bigcapitalDB_USER=bigcapital_userDB_PASSWORD=secure_password_hereDB_DIALECT=mysql# AuthenticationJWT_SECRET=your-secure-jwt-secret-keyAPI_KEY=your-secure-api-keySESSION_SECRET=your-secure-session-secret# Email Configuration (for invoices, reports)MAIL_DRIVER=smtpMAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_USERNAME=your-email@gmail.comMAIL_PASSWORD=your-app-passwordMAIL_FROM=noreply@yourbusiness.comMAIL_FROM_NAME="Your Business Name"# File UploadsMAX_UPLOAD_SIZE=52428800ALLOWED_FILE_TYPES=pdf,doc,docx,xls,xlsx,jpg,jpeg,png,gif# FeaturesENABLE_INVOICING=trueENABLE_EXPENSES=trueENABLE_REPORTS=trueENABLE_MULTI_CURRENCY=true# PerformanceCACHE_DRIVER=memoryQUEUE_DRIVER=syncCommit and push to your GitHub repository:
Terminal window git initgit add .git commit -m "Initial Bigcapital deployment"git remote add origin https://github.com/yourusername/bigcapital-deploy.gitgit push -u origin mainCreate a New App
In the Klutch.sh dashboard:
- Click “Create New App”
- Select your GitHub repository containing the Dockerfile
- Choose the branch (typically
mainormaster) - Klutch.sh will automatically detect the Dockerfile in the root directory
Configure Environment Variables
Set up these essential environment variables in your Klutch.sh dashboard:
Variable Description Example APP_URLYour application domain https://accounting.example.comAPP_PORTApplication port 3000APP_ENVEnvironment (production or development) productionNODE_ENVNode environment productionDB_HOSTDatabase host database.example.comDB_PORTDatabase port 3306DB_NAMEDatabase name bigcapitalDB_USERDatabase username bigcapital_userDB_PASSWORDDatabase password (use strong password) secure_password_hereDB_DIALECTDatabase type (mysql or postgres) mysqlJWT_SECRETJWT signing secret (generate random string) random-secret-keyAPI_KEYAPI authentication key api-key-stringSESSION_SECRETSession encryption secret session-secret-keyMAIL_DRIVERMail service driver smtpMAIL_HOSTSMTP server hostname smtp.gmail.comMAIL_PORTSMTP port 587MAIL_USERNAMESMTP username your-email@gmail.comMAIL_PASSWORDSMTP password or app password app_passwordMAIL_FROMFrom email address noreply@example.comConfigure Persistent Storage
Bigcapital requires persistent storage for uploaded documents, receipts, and logs. Add persistent volumes:
Mount Path Description Recommended Size /app/storageApplication data and initialization files 20GB /app/uploadsUploaded documents and receipts 100GB+ /app/logsApplication logs 20GB In the Klutch.sh dashboard:
- Navigate to your app settings
- Go to the “Volumes” section
- Click “Add Volume” for each mount path
- Set mount paths and sizes as specified above
Set Network Configuration
Configure your app’s network settings:
- Select traffic type: HTTP (Bigcapital uses standard web ports)
- Recommended internal port: 3000 (as specified in Dockerfile)
- Klutch.sh will automatically handle HTTPS termination via reverse proxy
- Ensure ports 80 and 443 are accessible from your domain
Configure Custom Domain
BigCapital works best with a custom domain:
- Navigate to your app’s “Domains” section in Klutch.sh
- Click “Add Custom Domain”
- Enter your domain (e.g.,
accounting.yourdomain.com) - Configure DNS with a CNAME record to point to your Klutch.sh app
- Update
APP_URLenvironment variable to match your domain - Klutch.sh will automatically provision SSL certificates
Deploy Your App
- Review all settings and environment variables
- Click “Deploy”
- Klutch.sh will build the Docker image and start your Bigcapital instance
- Wait for the deployment to complete (typically 10-15 minutes for initial build)
- Access your Bigcapital instance at your configured domain
- Complete the initial setup and create your first organization
Initial Setup and Configuration
After deployment completes, access your Bigcapital instance to complete setup.
Accessing Bigcapital
Navigate to your app’s domain: https://yourdomain.com
You’ll be greeted with the Bigcapital setup wizard where you can:
- Create an administrator account
- Set up your organization details
- Configure basic accounting preferences
- Create your chart of accounts
Creating Your First Organization
- Click “Create Organization” on the dashboard
- Enter organization details:
- Organization name
- Business type
- Currency
- Fiscal year start date
- Configure initial settings:
- Chart of accounts template (select based on business type)
- Accounting method (accrual or cash)
- Tax settings
- Create admin user account
- Start managing your finances
Setting Up Chart of Accounts
Bigcapital comes with pre-built chart templates:
- Select appropriate template for your business
- Review and customize accounts if needed
- Add additional accounts for specific needs
- Organize accounts into logical groups
- Set account numbering scheme
Creating Your First Invoice
- Navigate to “Invoicing” section
- Click “New Invoice”
- Configure invoice details:
- Customer information
- Invoice date and due date
- Line items with descriptions and amounts
- Tax settings
- Add payment terms if needed
- Customize invoice template if desired
- Send to customer or export as PDF
Environment Variable Examples
Basic Production Configuration
APP_URL=https://accounting.yourdomain.comAPP_PORT=3000APP_ENV=productionNODE_ENV=productionDB_HOST=database.example.comDB_NAME=bigcapitalDB_USER=bigcapital_userDB_PASSWORD=your-secure-passwordJWT_SECRET=your-secure-jwt-secretSESSION_SECRET=your-session-secretMAIL_DRIVER=smtpMAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_USERNAME=your-email@gmail.comMAIL_PASSWORD=your-app-passwordComplete Advanced Configuration
# ApplicationAPP_URL=https://accounting.yourdomain.comAPP_PORT=3000APP_ENV=productionNODE_ENV=productionAPP_DEBUG=falseAPP_TIMEZONE=UTC
# DatabaseDB_HOST=database.example.comDB_PORT=3306DB_NAME=bigcapitalDB_USER=bigcapital_userDB_PASSWORD=your-secure-passwordDB_DIALECT=mysqlDB_POOL_MIN=2DB_POOL_MAX=10
# AuthenticationJWT_SECRET=your-secure-jwt-secret-keyJWT_EXPIRATION=7dAPI_KEY=your-secure-api-keySESSION_SECRET=your-secure-session-secret
# EmailMAIL_DRIVER=smtpMAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_USERNAME=your-email@gmail.comMAIL_PASSWORD=your-app-passwordMAIL_FROM=noreply@yourbusiness.comMAIL_FROM_NAME="Your Business Name"MAIL_ENCRYPTION=tls
# File UploadsMAX_UPLOAD_SIZE=52428800ALLOWED_FILE_TYPES=pdf,doc,docx,xls,xlsx,jpg,jpeg,pngUPLOAD_PATH=/app/uploadsSTORAGE_PATH=/app/storage
# FeaturesENABLE_INVOICING=trueENABLE_EXPENSES=trueENABLE_ESTIMATES=trueENABLE_REPORTS=trueENABLE_MULTI_CURRENCY=trueENABLE_TAX_TRACKING=true
# PerformanceCACHE_DRIVER=memoryQUEUE_DRIVER=syncLOG_LEVEL=info
# SecurityREQUIRE_HTTPS=trueCORS_ORIGINS=https://yourdomain.comALLOW_REGISTRATION=falseSample Code and Getting Started
Node.js - Creating Invoices Programmatically
const axios = require('axios');
const API_BASE_URL = 'https://accounting.yourdomain.com/api';const API_KEY = 'your-api-key';const ORGANIZATION_ID = 'your-org-id';
const apiClient = axios.create({ baseURL: API_BASE_URL, headers: { 'Authorization': `Bearer ${API_KEY}`, 'X-Organization-ID': ORGANIZATION_ID }});
// Create a new invoiceasync function createInvoice(invoiceData) { try { const response = await apiClient.post('/invoices', { customer_id: invoiceData.customerId, invoice_date: new Date().toISOString().split('T')[0], due_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], items: invoiceData.items.map(item => ({ description: item.description, quantity: item.quantity, unit_price: item.unitPrice, account_id: item.accountId })), notes: invoiceData.notes || '' });
console.log('Invoice created:', response.data); return response.data; } catch (error) { console.error('Error creating invoice:', error.response.data); throw error; }}
// Retrieve all invoicesasync function getInvoices(filters = {}) { try { const response = await apiClient.get('/invoices', { params: filters }); console.log('Invoices:', response.data); return response.data; } catch (error) { console.error('Error retrieving invoices:', error.response.data); throw error; }}
// Get invoice detailsasync function getInvoice(invoiceId) { try { const response = await apiClient.get(`/invoices/${invoiceId}`); console.log('Invoice details:', response.data); return response.data; } catch (error) { console.error('Error retrieving invoice:', error.response.data); throw error; }}
// Send invoice to customerasync function sendInvoice(invoiceId, email) { try { const response = await apiClient.post(`/invoices/${invoiceId}/send`, { to: email });
console.log('Invoice sent successfully'); return response.data; } catch (error) { console.error('Error sending invoice:', error.response.data); throw error; }}
// Usage examples(async () => { try { // Create invoice const newInvoice = await createInvoice({ customerId: 'customer-123', items: [ { description: 'Professional Services', quantity: 10, unitPrice: 150, accountId: 'account-4000' } ], notes: 'Thank you for your business!' });
// Get all invoices const invoices = await getInvoices({ status: 'draft' });
// Send invoice await sendInvoice(newInvoice.id, 'customer@example.com'); } catch (error) { console.error('Error:', error.message); }})();JavaScript - Managing Expenses
const axios = require('axios');
const API_BASE_URL = 'https://accounting.yourdomain.com/api';const API_KEY = 'your-api-key';
const apiClient = axios.create({ baseURL: API_BASE_URL, headers: { 'Authorization': `Bearer ${API_KEY}` }});
// Record an expenseasync function recordExpense(expenseData) { try { const formData = new FormData(); formData.append('vendor_id', expenseData.vendorId); formData.append('expense_date', expenseData.date); formData.append('amount', expenseData.amount); formData.append('category_id', expenseData.categoryId); formData.append('description', expenseData.description); formData.append('reference_number', expenseData.referenceNumber);
// Attach receipt if provided if (expenseData.receipt) { formData.append('receipt', expenseData.receipt); }
const response = await apiClient.post('/expenses', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
console.log('Expense recorded:', response.data); return response.data; } catch (error) { console.error('Error recording expense:', error.response.data); throw error; }}
// Get expense reportasync function getExpenseReport(startDate, endDate) { try { const response = await apiClient.get('/reports/expenses', { params: { start_date: startDate, end_date: endDate } });
console.log('Expense Report:', response.data); return response.data; } catch (error) { console.error('Error generating report:', error.response.data); throw error; }}
// Get expense categoriesasync function getExpenseCategories() { try { const response = await apiClient.get('/expense-categories'); console.log('Categories:', response.data); return response.data; } catch (error) { console.error('Error retrieving categories:', error.response.data); throw error; }}
// Usage(async () => { try { // Get categories first const categories = await getExpenseCategories(); const officeSuppliesCategory = categories.find(c => c.name === 'Office Supplies');
// Record expense const expense = await recordExpense({ vendorId: 'vendor-456', date: new Date().toISOString().split('T')[0], amount: 125.50, categoryId: officeSuppliesCategory.id, description: 'Office supplies and printer paper', referenceNumber: 'INV-2024-001' });
// Generate report const startDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; const endDate = new Date().toISOString().split('T')[0]; const report = await getExpenseReport(startDate, endDate); } catch (error) { console.error('Error:', error.message); }})();Python - Financial Reporting
import requestsimport jsonfrom datetime import datetime, timedelta
class BigcapitalClient: def __init__(self, base_url, api_key, organization_id): self.base_url = base_url self.api_key = api_key self.organization_id = organization_id self.headers = { 'Authorization': f'Bearer {api_key}', 'X-Organization-ID': organization_id, 'Content-Type': 'application/json' }
def get_profit_loss_statement(self, start_date, end_date): """Generate profit and loss statement""" try: response = requests.get( f'{self.base_url}/api/reports/profit-and-loss', headers=self.headers, params={ 'start_date': start_date, 'end_date': end_date } ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error generating P&L: {e}") return None
def get_balance_sheet(self, as_of_date): """Get balance sheet""" try: response = requests.get( f'{self.base_url}/api/reports/balance-sheet', headers=self.headers, params={'as_of_date': as_of_date} ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error retrieving balance sheet: {e}") return None
def get_cash_flow_statement(self, start_date, end_date): """Generate cash flow statement""" try: response = requests.get( f'{self.base_url}/api/reports/cash-flow', headers=self.headers, params={ 'start_date': start_date, 'end_date': end_date } ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error generating cash flow: {e}") return None
def get_accounts_receivable_aging(self): """Get aging report for receivables""" try: response = requests.get( f'{self.base_url}/api/reports/ar-aging', headers=self.headers ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error retrieving AR aging: {e}") return None
def get_accounts_payable_aging(self): """Get aging report for payables""" try: response = requests.get( f'{self.base_url}/api/reports/ap-aging', headers=self.headers ) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error retrieving AP aging: {e}") return None
def export_report_as_pdf(self, report_type, params): """Export financial report as PDF""" try: response = requests.post( f'{self.base_url}/api/reports/{report_type}/export', headers={**self.headers, 'Accept': 'application/pdf'}, json=params ) response.raise_for_status() return response.content except requests.exceptions.RequestException as e: print(f"Error exporting report: {e}") return None
# Usageclient = BigcapitalClient( 'https://accounting.yourdomain.com', 'your-api-key', 'organization-id')
# Generate monthly reportstoday = datetime.now()start_of_month = datetime(today.year, today.month, 1)end_of_month = datetime(today.year, today.month + 1, 1) - timedelta(days=1)
start_date = start_of_month.strftime('%Y-%m-%d')end_date = end_of_month.strftime('%Y-%m-%d')
# Get P&Lpl_statement = client.get_profit_loss_statement(start_date, end_date)print("Profit & Loss Statement:")print(json.dumps(pl_statement, indent=2))
# Get Balance Sheetbalance_sheet = client.get_balance_sheet(end_date)print("\nBalance Sheet:")print(json.dumps(balance_sheet, indent=2))
# Get Cash Flowcash_flow = client.get_cash_flow_statement(start_date, end_date)print("\nCash Flow Statement:")print(json.dumps(cash_flow, indent=2))
# Get A/R Agingar_aging = client.get_accounts_receivable_aging()print("\nAccounts Receivable Aging:")print(json.dumps(ar_aging, indent=2))
# Get A/P Agingap_aging = client.get_accounts_payable_aging()print("\nAccounts Payable Aging:")print(json.dumps(ap_aging, indent=2))
# Export P&L as PDFpdf_data = client.export_report_as_pdf('profit-and-loss', { 'start_date': start_date, 'end_date': end_date})if pdf_data: with open(f'P&L_{end_date}.pdf', 'wb') as f: f.write(pdf_data) print(f"Report exported to P&L_{end_date}.pdf")cURL - API Integration Examples
# Get all customerscurl -X GET https://accounting.yourdomain.com/api/customers \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "X-Organization-ID: YOUR_ORG_ID"
# Create a new customercurl -X POST https://accounting.yourdomain.com/api/customers \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "X-Organization-ID: YOUR_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "555-1234", "billing_address": "123 Main St, City, State 12345" }'
# Record a paymentcurl -X POST https://accounting.yourdomain.com/api/invoices/123/payments \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "X-Organization-ID: YOUR_ORG_ID" \ -H "Content-Type: application/json" \ -d '{ "amount": 1500.00, "payment_date": "2024-01-15", "payment_method": "bank_transfer", "reference": "CHECK-001" }'
# Get financial summarycurl -X GET "https://accounting.yourdomain.com/api/reports/summary" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "X-Organization-ID: YOUR_ORG_ID"Docker Compose for Local Development
For local testing before deploying to Klutch.sh:
version: '3.8'
services: bigcapital: build: . container_name: bigcapital-app environment: APP_URL: http://localhost:3000 APP_PORT: 3000 APP_ENV: development NODE_ENV: development APP_DEBUG: "true" DB_HOST: mysql DB_PORT: 3306 DB_NAME: bigcapital DB_USER: bigcapital_user DB_PASSWORD: dev_password DB_DIALECT: mysql JWT_SECRET: dev-secret-key SESSION_SECRET: dev-session-secret MAIL_DRIVER: log ports: - "3000:3000" volumes: - ./:/app - /app/node_modules depends_on: - mysql restart: unless-stopped
mysql: image: mysql:8.0 container_name: bigcapital-mysql environment: MYSQL_ROOT_PASSWORD: root_password MYSQL_DATABASE: bigcapital MYSQL_USER: bigcapital_user MYSQL_PASSWORD: dev_password ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql restart: unless-stopped
volumes: mysql_data:To run locally:
docker-compose up -dAccess Bigcapital at http://localhost:3000
Financial Management Features
Multi-Currency Support
Bigcapital supports multiple currencies for:
- Customer transactions
- Vendor payments
- Currency conversion tracking
- Multi-currency reporting
Tax Configuration
Set up tax tracking:
- Navigate to “Settings” → “Tax”
- Configure tax rates and categories
- Set default tax accounts
- Enable tax reporting
- Track tax obligations by period
Bank Reconciliation
Reconcile bank accounts with transactions:
- Go to “Banking” → “Reconciliation”
- Select account to reconcile
- Match transactions with bank statements
- Identify discrepancies
- Complete reconciliation
Customer and Vendor Management
Customer Management
- Maintain detailed customer profiles
- Track credit limits and payment terms
- View invoice history
- Monitor outstanding amounts
- Generate statements
Vendor Management
- Maintain vendor information
- Set payment terms and methods
- Track bills and payables
- Manage vendor communications
- Process payments
User Management and Roles
User Roles
Available roles in Bigcapital:
- Owner/Administrator: Full access to all features
- Accountant: Access to all accounting functions
- Manager: Limited financial management
- Employee: View-only or specific transaction access
- Custom Roles: Create custom roles with specific permissions
Setting Up Team Members
- Go to “Settings” → “Users”
- Click “Invite User”
- Enter email address
- Assign role and permissions
- Send invitation
- User creates account and joins organization
Backup and Recovery
Automated Backups
Bigcapital should be backed up regularly:
# Backup script (can be run via cron)#!/bin/bash
BACKUP_DIR="/backups"TIMESTAMP=$(date +%Y%m%d_%H%M%S)DB_HOST=${DB_HOST:-localhost}DB_NAME=${DB_NAME:-bigcapital}DB_USER=${DB_USER}DB_PASSWORD=${DB_PASSWORD}
# Backup databasemysqldump -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME > \ $BACKUP_DIR/bigcapital_db_$TIMESTAMP.sql
# Backup uploads and storagetar -czf $BACKUP_DIR/bigcapital_files_$TIMESTAMP.tar.gz \ /app/uploads /app/storage
# Keep only last 30 days of backupsfind $BACKUP_DIR -name "bigcapital_*" -mtime +30 -delete
echo "Backup completed: $TIMESTAMP"Recovery Procedures
To restore from backups:
- Stop the Bigcapital container
- Restore database:
Terminal window mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME < backup.sql - Restore files:
Terminal window tar -xzf backup.tar.gz -C / - Restart the container
Performance Optimization
Database Optimization
-- Create indexes for common queriesCREATE INDEX idx_customer_id ON invoices(customer_id);CREATE INDEX idx_vendor_id ON bills(vendor_id);CREATE INDEX idx_invoice_date ON invoices(invoice_date);CREATE INDEX idx_transaction_date ON transactions(transaction_date);
-- Optimize tablesOPTIMIZE TABLE invoices;OPTIMIZE TABLE bills;OPTIMIZE TABLE transactions;OPTIMIZE TABLE customers;Caching Configuration
CACHE_DRIVER=memoryCACHE_TTL=3600QUEUE_DRIVER=syncFor production with higher load:
CACHE_DRIVER=redisREDIS_HOST=redis-serverREDIS_PORT=6379QUEUE_DRIVER=bullSecurity Best Practices
Authentication and Access Control
- Enforce strong password policies
- Use two-factor authentication when available
- Limit admin access to trusted IPs
- Create individual accounts for each user
- Regular audit of user permissions
Data Security
- Enable HTTPS (automatic via Klutch.sh)
- Encrypt sensitive data in transit
- Store database credentials securely
- Implement regular backups
- Test restore procedures regularly
- Maintain audit logs of financial transactions
Financial Data Protection
- Restrict access to sensitive financial data
- Use role-based permissions
- Log all changes to financial records
- Require approval for large transactions
- Monitor for suspicious activity
- Maintain data privacy compliance (GDPR, etc.)
API Security
# Rotate API keys regularlyAPI_KEY=rotate-regularly
# Restrict API access by IP if possibleAPI_ALLOWED_IPS=203.0.113.0
# Use strong JWT secretsJWT_SECRET=use-cryptographically-secure-random-stringJWT_EXPIRATION=7dTroubleshooting
Common Issues and Solutions
Issue: Database connection fails on startup
Solutions:
- Verify
DB_HOST,DB_NAME,DB_USER,DB_PASSWORDare correct - Ensure database server is running and accessible
- Check database user has proper permissions
- Verify no firewall blocks database connection
- Check database connection logs
Issue: Invoices not generating
Troubleshooting:
- Verify invoice templates are configured
- Check that line items are added properly
- Ensure customer information is complete
- Check currency settings
- Review application logs for errors
Issue: Email notifications not sending
Solutions:
- Verify SMTP credentials are correct
- Check SMTP server connectivity
- Ensure firewall allows SMTP connections
- Verify sender email is configured
- Check mail logs
Issue: Slow report generation
Solutions:
- Optimize database indexes
- Limit date ranges for reports
- Enable caching
- Archive old transactions if applicable
- Consider upgrading instance resources
Issue: File uploads failing
Troubleshooting:
- Verify
/app/uploadspersistent volume is attached - Check directory permissions
- Verify
MAX_UPLOAD_SIZEis appropriate - Check available disk space
- Review upload error logs
Upgrading Bigcapital
To update Bigcapital to a newer version:
-
Update your Dockerfile to latest version:
RUN git clone https://github.com/bigcapitalio/bigcapital.git . && \git checkout latest-version-tag -
Commit and push to GitHub
-
Klutch.sh will automatically rebuild with the latest version
-
Always backup database before upgrading
-
Test in a development environment first
-
Review release notes for breaking changes
Multi-Organization Support
Bigcapital supports managing multiple organizations:
- Create separate organization for each business entity
- Manage independent accounting records
- Switch between organizations in the UI
- Generate consolidated reports if needed
- Maintain separate user permissions per organization
Advanced Reporting
Custom Reports
Generate custom financial reports:
- Navigate to “Reports” section
- Click “Custom Report”
- Select report type (P&L, Balance Sheet, etc.)
- Configure filters and date ranges
- Select columns and sorting
- Export to PDF or Excel
Financial Dashboards
Monitor key metrics:
- Revenue and expenses overview
- Cash flow summary
- Accounts receivable aging
- Accounts payable aging
- Net profit trends
- Customer and vendor summaries
Additional Resources
- Bigcapital Official Website - Project information and features
- Bigcapital Documentation - Complete guides and reference
- Bigcapital GitHub Repository - Source code
- Bigcapital Blog - Tutorials and tips
- Bigcapital Community - Forum and support
- Klutch.sh Getting Started Guide
- Klutch.sh Volumes Documentation
- Klutch.sh Custom Domains Guide
Conclusion
Deploying Bigcapital on Klutch.sh provides you with a complete, open-source accounting and financial management platform that respects your data privacy while offering powerful financial tools. With persistent storage for all financial records, comprehensive reporting capabilities, and full control over your financial data, Bigcapital enables small businesses and organizations to manage their finances with confidence. Klutch.sh’s managed infrastructure ensures your accounting system is always available, secure, and performant, allowing you to focus on growing your business.
Start managing your business finances with complete control and transparency by deploying Bigcapital on Klutch.sh today.