ffm — Foxmayn Frappe Manager
How a Single Command Replaced Hours of Manual Frappe Environment Setup
At a Glance
Challenge
Manual Docker Compose YAML editing for each Frappe development bench
Result
Single-command bench creation with auto-routing and image caching
Tech Stack
Status
production
Situation
Setting up a local Frappe/ERPNext development environment is notoriously painful. Developers must manually edit docker-compose YAML files, configure MariaDB and Redis connections, manage port allocations to avoid conflicts between benches, and set up reverse proxies for local domain routing. The official frappe_docker devcontainer approach works but requires significant Docker knowledge and manual configuration for each new bench.
The Challenge
Wrap the entire Frappe bench lifecycle — creation, startup, shell access, app installation, and teardown — into a single CLI tool that handles Docker orchestration, port management, and domain routing automatically.
What Was Built
Built a Go CLI with commands for the full bench lifecycle: create, start, stop, shell, logs, delete — each generating and managing Docker Compose configurations automatically.
Implemented smart port auto-allocation that scans for available ports across all benches, eliminating manual port conflict resolution.
Added a shared Traefik reverse proxy that routes <bench>.localhost domains to the correct bench containers, so developers access each bench via clean URLs.
Built Docker image layer caching: the first bench build downloads and configures the Frappe image, but subsequent benches with the same Frappe branch reuse cached layers — reducing creation time from minutes to seconds.
Pre-configured the bench shell environment with zsh, zinit, starship prompt, syntax highlighting, and Go toolchain — plus automatic foxmayn-frappe-cli (ffc) installation for API-level management.
Added multi-app installation support for both public apps (ERPNext, HRMS) and private repos via SSH/HTTPS, plus reverse proxy config generation for Caddy and Nginx.
Results
Bench setup time
30-60 minutes (manual)
~2 minutes (single command)
Subsequent bench creation
Seconds (cached images)
Port conflicts
Manual resolution
Auto-allocated
Domain routing
Auto via Traefik (<bench>.localhost)
Frappe developers can now spin up isolated development environments in seconds, with automatic port management, domain routing, and a pre-configured shell — eliminating the Docker expertise barrier that previously made local Frappe development inaccessible to many teams.
Key Achievement
Spins up fully configured Frappe benches with smart port allocation, image caching for fast rebuilds, and automatic domain routing at <bench>.localhost via Traefik.