Skip to main content

Overview

Bench is a command-line utility that orchestrates multiple components to create a complete Frappe application environment. Understanding its architecture helps you troubleshoot issues, extend functionality, and optimize your development workflow.

Bench Directory Structure

A typical bench instance has the following directory layout:
frappe-bench/
├── apps/              # Application source code
│   ├── frappe/       # Frappe framework (required)
│   └── erpnext/      # Additional apps
├── sites/            # Site-specific data and configuration
│   ├── assets/       # Compiled static assets
│   ├── [site-name]/  # Individual site directories
│   ├── apps.txt      # List of installed apps
│   ├── common_site_config.json
│   └── currentsite.txt
├── config/           # Bench configuration files
│   ├── pids/         # Process ID files
│   ├── redis_cache.conf
│   ├── redis_queue.conf
│   └── supervisor.conf (production)
├── env/              # Python virtual environment
│   ├── bin/
│   ├── lib/
│   └── ...
├── logs/             # Application and service logs
├── node_modules/     # Node.js dependencies
├── patches.txt       # Applied patches tracking
├── Procfile          # Process definitions for development
└── archived/         # Archived sites and apps

Key Directories

Contains the source code for all installed applications. Each app is a separate directory containing:
  • Python modules
  • Frontend assets (JS, CSS)
  • Configuration files
  • Hooks definitions
The frappe app is always required as it provides the core framework.
Stores site-specific data and configuration:
  • Site directories: Each site has its own directory with:
    • site_config.json - Site-specific configuration
    • private/ - Private files and backups
    • public/ - Public files accessible via web
    • locks/ - Site-level locks
  • apps.txt: List of apps installed across all sites
  • common_site_config.json: Configuration shared across all sites
Houses generated configuration files:
  • Redis configuration files for cache, queue, and socketio
  • Process manager configuration (Supervisor or systemd)
  • PID files for running processes
Python virtual environment containing:
  • Python interpreter
  • Installed Python packages
  • Application dependencies
Isolated from system Python to prevent conflicts.

Core Components

Bench integrates several components to create a complete application stack:

1. Python Virtual Environment

  • Purpose: Isolates Python dependencies
  • Location: env/ directory
  • Default Python: Python 3.10+
  • Package Manager: pip (or uv for faster installs)

2. Frappe Framework

  • Purpose: Core framework providing ORM, API, UI components
  • Location: apps/frappe/
  • Role: Required base for all Frappe applications
  • Features:
    • Database abstraction layer
    • REST API framework
    • Background job processing
    • User authentication and permissions

3. Database Layer

MariaDB/MySQL:
  • Stores application data
  • Default configuration: localhost:3306
  • Configurable via common_site_config.json:
    {
      "db_host": "localhost",
      "db_port": 3306
    }
    

4. Redis

Bench uses multiple Redis instances for different purposes:
InstanceDefault PortPurpose
redis_cache13000Caching layer for application data
redis_queue11000Background job queue management
redis_socketio13000Real-time websocket connections
Configuration in common_site_config.json:
{
  "redis_cache": "redis://127.0.0.1:13000",
  "redis_queue": "redis://127.0.0.1:11000",
  "redis_socketio": "redis://127.0.0.1:13000"
}

5. Node.js & Frontend Build

  • Purpose: Frontend asset compilation and development
  • Tools:
    • Node.js runtime
    • npm/yarn for package management
    • Webpack/Rollup for bundling
  • Output: Compiled assets in sites/assets/

6. Process Management

Development (via Procfile):
web: bench serve --port 8000
worker_short: bench worker --queue short
worker_long: bench worker --queue long
worker_default: bench worker --queue default
schedule: bench schedule
redis_cache: redis-server config/redis_cache.conf
redis_queue: redis-server config/redis_queue.conf
Production (via Supervisor or systemd):
  • Multiple gunicorn web workers
  • Background workers for job processing
  • Scheduler for periodic tasks
  • Redis instances

Command Routing and Execution

How Bench Commands Work

1

Command Invocation

User runs a bench command:
bench new-site mysite.local
2

CLI Entry Point

The bench command is registered via Python setuptools and points to bench.cli:cliLocation: bench/cli.py:65
3

Command Discovery

Bench uses Click’s MultiCommandGroup to discover commands from:
  • Built-in commands in bench/commands/
  • Frappe framework commands
  • Custom app commands
Location: bench/commands/__init__.py:1
4

Command Execution

The appropriate command function is called with parsed arguments and options
5

Frappe Integration

For Frappe-specific commands, bench:
  1. Sets up the Python environment
  2. Calls Frappe with the command
  3. Returns the result

Command Categories

Bench organizes commands into logical groups: Initialization & Setup (bench/commands/make.py:5):
  • init - Initialize a new bench
  • new-app - Create new application
  • get-app - Clone and install app
Updates (bench/commands/update.py:9):
  • update - Update bench and apps
  • switch-to-branch - Switch branches
Configuration (bench/commands/config.py:8):
  • config - Manage bench configuration
  • set-* commands for various settings
Setup (bench/commands/setup.py:13):
  • setup production - Production environment
  • setup nginx - NGINX configuration
  • setup supervisor - Supervisor configuration
Utilities (bench/commands/utils.py:8):
  • start - Start development server
  • restart - Restart processes
  • backup-all-sites - Backup operations

Data Flow

Request Lifecycle

  1. HTTP Request arrives at NGINX (production) or Werkzeug (development)
  2. Web Server forwards request to Frappe application
  3. Frappe processes request:
    • Checks Redis cache
    • Queries MariaDB if needed
    • Enqueues background jobs if needed
  4. Response is returned to client
  5. Background Workers process queued jobs asynchronously

Configuration Hierarchy

Bench uses a layered configuration approach:
┌─────────────────────────────────┐
│ Environment Variables           │  (Highest priority)
├─────────────────────────────────┤
│ site_config.json (per site)     │
├─────────────────────────────────┤
│ common_site_config.json (bench) │
├─────────────────────────────────┤
│ Default values                  │  (Lowest priority)
└─────────────────────────────────┘
Site-specific settings override bench-wide settings, which override defaults.

Development vs Production

Development Mode

  • Process Manager: Honcho/Procfile
  • Web Server: Werkzeug (Flask development server)
  • Port: 8000 (default)
  • Auto-reload: Enabled
  • Debug Mode: Enabled
  • Started via: bench start

Production Mode

  • Process Manager: Supervisor or systemd
  • Web Server: Gunicorn + NGINX
  • Port: 80/443 (standard HTTP/HTTPS)
  • Auto-reload: Disabled
  • Debug Mode: Disabled
  • Setup via: bench setup production

Key Python Modules

bench.bench.Bench

Main Bench class representing a bench instanceLocation: bench/bench.py:61

bench.app.App

Represents a Frappe applicationHandles app installation, updates, and dependencies

bench.utils.system

System-level utilitiesInitialization, process management, system setup

bench.config.*

Configuration generatorsNGINX, Supervisor, systemd, Redis configs

Build docs developers (and LLMs) love