A script for gracefully stopping all Frappe bench processes.
When you start a Frappe bench with bench start, multiple processes are launched in the background. The standard approach to stop these processes is to use pkill or kill -9 to terminate them. However, this approach has several problems:
- Data loss: Force-killing processes can lead to incomplete operations, data corruption, or interrupted background jobs
- Hardcoded assumptions: Simple scripts often assume default port numbers, which may not match your configuration
- Collateral damage: Killing processes by name pattern can accidentally terminate unrelated processes
This script addresses these issues by reading your actual bench configuration and performing a graceful shutdown.
Frappe bench uses three separate Redis instances on different ports:
- Cache Redis: Typically port 13000 (but configurable)
- Queue Redis: Typically port 11000 (but configurable)
- Socket.io Redis: Typically port 12000 (but configurable)
Additionally, other services like the web server and Socket.io server may use non-default ports depending on your sites/common_site_config.json configuration.
A naive script that simply kills all processes named "redis-server" or "node" would:
- Kill system-wide Redis instances that are not part of the bench
- Terminate unrelated Node.js processes
- Fail to identify the correct processes if your bench uses custom ports
This script solves this problem by:
- Reading port numbers from
config/redis_*.conffiles - Reading configuration from
sites/common_site_config.json - Checking PID files in
config/pids/when available - Using multiple methods to identify the correct processes:
- PID files (most reliable)
- Port numbers via
lsof/ss - Process pattern matching as fallback
- Graceful shutdown: Sends SIGTERM first, waits for processes to terminate cleanly, only uses SIGKILL as last resort
- Configuration-aware: Reads your actual bench configuration instead of assuming defaults
- Multi-method process detection: Uses PID files, port lookup, and pattern matching for reliability
- Colored output: Clear status messages with color coding
- Safe: Validates environment before taking action
# From the bench directory
./stop_bench.sh
# Or from anywhere with full path
/path/to/bench/stop_bench.shThe script stops processes in reverse order of startup (important for clean shutdown):
- Worker - Lets current background jobs finish
- Schedule - Stops the scheduled task runner
- Watch processes - Stops asset rebuild watchers (bench watch, esbuild, yarn)
- Serve - Stops the web server
- Socket.io - Stops the real-time communication server
- Redis instances - Stops cache, queue, and socketio Redis servers
For each process:
- Attempts to find the PID via PID file, port lookup, or pattern matching
- Sends SIGTERM for graceful shutdown
- Waits up to 10 seconds (Python) or 5 seconds (Redis/Node) for termination
- If still running, sends SIGKILL as last resort
- Bash shell
- Standard Unix utilities:
grep,awk,ps,kill - Optional but recommended:
lsof(more reliable port-based process detection) - Must be run from or within a Frappe bench directory
Place the script in your Frappe bench directory and make it executable:
chmod +x stop_bench.sh[INFO] === Stopping Frappe Bench ===
[INFO] Bench directory: /home/user/frappe-bench
[INFO] Bench Worker: Stopping gracefully (PID: 12345)...
.
[INFO] Bench Worker: Stopped successfully
[INFO] Bench Schedule: Stopping gracefully (PID: 12346)...
[INFO] Bench Schedule: Stopped successfully
[INFO] Bench Watch: Stopping gracefully (PID: 12347)...
[INFO] Bench Watch: Stopped successfully
[WARN] Esbuild Watch: Not running
[INFO] Bench Serve: Stopping gracefully (PID: 12348)...
[INFO] Bench Serve: Stopped successfully
[INFO] Socket.io: Stopping gracefully (PID: 12349)...
[INFO] Socket.io: Stopped successfully
[INFO] Redis (cache): Stopping gracefully (PID: 12350)...
[INFO] Redis (cache): Stopped successfully
[INFO] Redis (queue): Stopping gracefully (PID: 12351)...
[INFO] Redis (queue): Stopped successfully
[INFO] Redis (socketio): Stopping gracefully (PID: 12352)...
[INFO] Redis (socketio): Stopped successfully
[INFO] === All bench processes stopped ===
Process not found: Make sure you're running the script from the correct bench directory. The script checks for the presence of Procfile and sites directory to validate the location.
Permission denied: The script needs permission to send signals to the bench processes. If you started the bench as a different user, you may need to run the stop script as the same user or with appropriate permissions.
Process still running after timeout: This is normal behavior. The script will force-kill any process that doesn't respond to SIGTERM within the timeout period.
This script is provided as-is for use with Frappe bench environments.