Aakvatech Limited - Frappe Pilot Admin, Bench URLs & Switch Bench
Frappe Pilot introduces an administration layer above individual Frappe sites. Understanding the difference between Pilot Admin, benches, sites, and sibling-bench management makes multi-bench servers
Understanding Frappe Pilot Admin, Bench URLs, and Switch Bench
When running multiple Frappe benches using Frappe Pilot, one of the first potentially confusing commands is:
pilot ls
For example:
NAME MODE MANAGER SITES ADDRESS
dev-bench production systemd 0 https://dev.example.com
v15 production systemd 1 https://v15.example.com
At first glance, the ADDRESS column can look like the address of a Frappe or ERPNext site.
It is not.
It is the URL for the Pilot Admin interface associated with that bench.
Understanding this distinction is especially important when running multiple benches on the same server.
The three administrative layers
A useful way to think about Pilot is that there are three different administrative scopes.
Linux Server
│
├── Pilot / Host
│ └── pilot ls
│
├── Bench: dev-bench
│ ├── Pilot Admin
│ │ └── https://dev.example.com
│ │
│ └── Frappe Sites
│
└── Bench: v15
├── Pilot Admin
│ └── https://v15.example.com
│
└── Frappe Sites
└── erp.example.com
These layers should not be confused with one another.
1. Pilot CLI / server level
Commands such as:
pilot ls
operate at the Pilot installation level and can discover the benches managed on the server.
For example:
NAME MODE MANAGER SITES ADDRESS
dev-bench production systemd 0 https://dev.example.com
v15 production systemd 1 https://v15.example.com
This tells us that Pilot currently knows about two benches.
2. Pilot Admin / Bench Admin
Each bench has its own Pilot Admin interface.
The Pilot Admin can manage operational aspects of the bench, including areas such as:
- Sites
- Applications
- Processes
- Tasks
- Logs
- Updates
- Domains
- Databases
- Resource limits
- Backups
- Storage
- Bench configuration
The ADDRESS shown by pilot ls is derived from that bench's Admin configuration.
Conceptually:
[admin]
domain = "v15.example.com"
tls = true
results in:
https://v15.example.com
being displayed by pilot ls.
3. Frappe / ERPNext Administrator
A Frappe site inside the bench has its own completely separate Administrator account.
For example:
https://erp.example.com
might use:
Username: Administrator
Password: <site administrator password>
That credential does not authenticate against the Pilot Admin interface.
Therefore:
Pilot Admin password
≠
Frappe Administrator password
They secure different layers of the system.
What exactly does pilot ls ADDRESS mean?
Looking at Pilot's ListCommand, the address is generated from the bench's Admin configuration.
If the Admin has a configured domain, Pilot uses that hostname.
Conceptually:
admin = bench.config.admin
if admin.domain:
return admin.domain
Pilot then determines whether the URL should be HTTP or HTTPS based on the TLS configuration and availability of the Admin certificate.
This explains output such as:
dev-bench production systemd 0 http://admin.example.com
v15 production systemd 1 https://v15.example.com
The two addresses are not two ERPNext sites.
They are two Pilot Admin endpoints, one for each bench.
Changing the Pilot Admin hostname
Pilot provides a dedicated command:
pilot set-admin-domain
Its syntax is:
usage: pilot set-admin-domain [-h] [--tls] domain
For example, if the Admin URL is currently:
http://admin.example.com
and we want:
https://dev.example.com
enter the relevant bench directory:
cd ~/pilot/benches/dev-bench
and run:
pilot set-admin-domain dev.example.com --tls
The DNS record for:
dev.example.com
should point to the Pilot server before certificate issuance is attempted.
Pilot handles the Admin-domain change through its Admin-domain management functionality, including updating configuration and republishing the appropriate nginx routing.
Afterwards:
cd ~/pilot
pilot ls
should show the new address.
For example:
dev-bench production systemd 0 https://dev.example.com
Importantly, changing the Admin domain does not rename the bench.
The bench remains:
dev-bench
Only its Pilot Admin hostname changes.
Setting or resetting the Pilot Admin password
Pilot has a separate command for its Admin password:
pilot set-admin-password
The current implementation describes this command as:
Set the admin panel password
If the password argument is omitted, Pilot prompts for it securely.
Therefore, the preferred approach is:
cd ~/pilot/benches/v15
pilot set-admin-password
rather than placing the password directly on the command line.
Although Pilot supports supplying a password as an argument, interactive entry is generally preferable because command-line arguments can be exposed through shell history or process inspection.
Password storage
Modern Pilot does not need to retain the clear-text Admin password.
The current implementation stores a password verifier/hash using PBKDF2-HMAC-SHA256.
This is another reason not to try to manually edit:
password = "..."
inside bench.toml.
Use:
pilot set-admin-password
instead.
Is there a separate "main Pilot Admin"?
This requires an important distinction.
There is not necessarily a completely separate global URL such as:
https://pilot.example.com
sitting above all bench Admin interfaces.
Instead, Pilot supports sibling-bench management from an existing Pilot Admin interface.
This is where the Switch Bench functionality comes in.
A server may therefore look like:
Pilot Server
│
├── dev-bench
│ └── Pilot Admin
│ └── dev.example.com
│
└── v15
└── Pilot Admin
└── v15.example.com
When sibling-bench management is enabled, an Admin interface can expose functionality such as:
Switch Bench
New Bench
allowing the administrator to navigate or manage benches on the same Pilot host.
So instead of thinking of Pilot as:
Global Pilot Admin
↓
Bench Admin
↓
Sites
a better model is:
Pilot Host
↓
Bench Admin
├── This bench
└── Sibling benches, when permitted
Why "Switch Bench" may be missing
The presence of Switch Bench has nothing to do with whether the bench contains a Frappe site.
A bench with:
SITES = 0
can still show Switch Bench.
The feature is controlled by:
[admin]
allow_bench_management = true
The Pilot frontend checks the value returned by the backend and only adds Switch Bench when this capability is enabled.
Conceptually, the UI does:
if allowBenchManagement:
show "Switch Bench"
The same capability also controls the UI components used for:
Switch Bench
New Bench
This is an important security boundary because an administrator who can manage sibling benches has considerably more authority than an administrator restricted to only the current bench.
Development checkout versus release installation
One particularly useful discovery in Pilot's source is the default behavior for:
allow_bench_management
Pilot explicitly describes sibling-bench management as primarily a development convenience.
The relevant logic effectively behaves as:
def default_allow_bench_management():
return is_dev_build
This means a development checkout can default to:
allow_bench_management = true
while a release/production installation keeps it disabled until an operator explicitly enables it.
This explains a common situation:
pilot ls
shows several benches, but the Pilot Admin UI does not show:
Switch Bench
The benches exist.
The UI simply does not have permission to manage sibling benches.
Enabling Switch Bench
Inspect the bench configuration:
cd ~/pilot/benches/dev-bench
Then:
grep -A10 '^\[admin\]' bench.toml
You may find:
[admin]
domain = "dev.example.com"
tls = true
allow_bench_management = false
To allow sibling-bench management, the relevant configuration is:
[admin]
allow_bench_management = true
Before enabling this on a production host, understand the scope carefully.
This setting does more than display another navigation item.
It enables functionality intended to manage other benches on the same Pilot server.
Therefore:
allow_bench_management = false
means approximately:
This Admin interface manages its own bench.
while:
allow_bench_management = true
means approximately:
This Admin interface may perform host-level operations involving sibling benches.
That distinction should be considered part of the server's security model.
What settings exist under [admin]?
At the time of writing, Pilot's AdminConfig defines the following Admin configuration fields:
port
timeout
enabled
password
jwt_secret
jwks_url
jwks_audience
domain
tls
allow_bench_management
recovery_codes
A simplified configuration might look like:
[admin]
port = 7000
timeout = 180
enabled = true
domain = "v15.example.com"
tls = true
allow_bench_management = true
Several fields should generally be managed through Pilot itself rather than edited manually.
In particular:
password
jwt_secret
recovery_codes
are security-sensitive configuration.
port
Controls the Admin service port.
Pilot currently defaults this to:
7000
with its internal Gunicorn process using the adjacent internal port.
timeout
Controls the Admin timeout value.
The current default is:
180 seconds
enabled
Controls whether the Pilot Admin functionality is enabled.
password
Contains the Pilot Admin password verifier.
It should normally be changed using:
pilot set-admin-password
jwt_secret
Used for local JWT/session-related functionality.
jwks_url
Allows the Admin backend to trust tokens from an external JWKS issuer.
This becomes relevant in centrally managed or federated authentication deployments.
jwks_audience
Restricts externally issued tokens to the expected audience.
domain
Defines the Pilot Admin hostname.
Example:
domain = "v15.example.com"
tls
Controls whether the Admin hostname is served using HTTPS.
tls = true
allow_bench_management
Controls whether this Admin interface can manage sibling benches.
This is the setting behind functionality such as:
Switch Bench
New Bench
recovery_codes
Pilot also supports break-glass recovery codes for authentication recovery.
Because these are security-sensitive credentials, they should not be exposed unnecessarily.
A practical multi-bench Pilot architecture
For a server hosting different Frappe versions, a sensible structure might be:
Ubuntu Server
│
└── Pilot
│
├── Bench: v15
│ ├── Admin:
│ │ https://v15.example.com
│ │
│ ├── ERPNext Site A
│ └── ERPNext Site B
│
├── Bench: v16
│ ├── Admin:
│ │ https://v16.example.com
│ │
│ └── ERPNext Site C
│
└── Bench: development
├── Admin:
│ https://dev.example.com
│
└── Development Sites
An operator could then choose whether one or more of these Admin interfaces should have:
allow_bench_management = true
depending on the required security model.
Useful commands to remember
List all Pilot benches:
pilot ls
Enter a particular bench:
cd ~/pilot/benches/v15
Set its Pilot Admin password:
pilot set-admin-password
Change its Admin hostname:
pilot set-admin-domain v15.example.com --tls
Inspect its Admin configuration:
grep -A15 '^\[admin\]' bench.toml
Check all benches again:
cd ~/pilot
pilot ls
Key lessons
The main operational lessons are:
The
ADDRESSshown bypilot lsis the Pilot Admin URL for a bench, not the Frappe site's URL.Every bench can have its own Pilot Admin hostname.
The Pilot Admin password is independent from the Frappe
Administratorpassword.Use:
pilot set-admin-passwordto manage the Pilot Admin credential.
Use:
pilot set-admin-domain <hostname> --tlsto change the Pilot Admin hostname.
A bench does not need any Frappe sites before its Pilot Admin interface can be used.
The Switch Bench menu is not controlled by site count.
Switch Bench is controlled by:
[admin] allow_bench_management = trueRelease/production-style Pilot installations can deliberately leave sibling-bench management disabled.
Enabling
allow_bench_managementshould be treated as an administrative privilege because it expands the Admin interface's scope beyond the current bench.
Final recommendation
When operating Pilot in production, give every bench an explicit Admin hostname:
v15.example.com
v16.example.com
dev.example.com
Use HTTPS for each Admin endpoint and maintain separate Pilot Admin credentials from your Frappe site Administrator credentials.
For normal production benches, consider leaving:
allow_bench_management = false
unless cross-bench administration is genuinely required.
If one trusted Admin interface is intended to act as the operational entry point for the whole Pilot server, enabling:
allow_bench_management = true
there can provide the Switch Bench experience without requiring a separate global Pilot dashboard.
This produces a much clearer operational model:
Pilot Host
↓
Trusted Bench Admin
↓
Switch Bench
↓
Individual Bench
↓
Frappe Sites
and keeps the distinction between server administration, bench administration, and ERPNext/Frappe site administration explicit.
Reference articles and discussions
- Frappe Pilot GitHub repository: https://github.com/frappe/pilot/
- Pilot bench listing implementation (
pilot/commands/bench/list.py): https://github.com/frappe/pilot/blob/develop/pilot/commands/bench/list.py - Pilot Admin configuration (
pilot/config/admin.py): https://github.com/frappe/pilot/blob/develop/pilot/config/admin.py - Pilot configuration documentation: https://github.com/frappe/pilot/blob/develop/docs/configuration.md
- Pilot Admin API documentation: https://github.com/frappe/pilot/blob/develop/docs/admin-api.md
- Pilot Admin frontend bench-navigation logic (
useAppMenu.ts): https://github.com/frappe/pilot/blob/develop/admin/frontend/dashboard/src/components/navigation/useAppMenu.ts - Pilot Admin session/bootstrap handling (
useSession.ts): https://github.com/frappe/pilot/blob/develop/admin/frontend/dashboard/src/composables/auth/useSession.ts - Pilot Admin layout and Bench Switcher (
MainLayout.vue): https://github.com/frappe/pilot/blob/develop/admin/frontend/dashboard/src/layouts/MainLayout.vue - Pilot Admin password command (
pilot/commands/sites/set_admin_password.py): https://github.com/frappe/pilot/blob/develop/pilot/commands/sites/setadminpassword.py - Technical exploration and operational testing performed during an Aakvatech Pilot multi-bench deployment.
- OpenAI ChatGPT was used to assist repository analysis, technical interpretation, and article drafting.
Aakvatech Limited is a Frappe Gold Partner and ERPNext implementation company headquartered in Dar es Salaam, Tanzania, operating across East Africa and the UAE.
This article was co-created using AI to accelerate drafting, with final insights curated and validated by the author. Any customer, personal, or sensitive data referenced during drafting has been anonymized or masked where applicable. All contributors, reference URLs, tools, and materials used to assist this content curation are credited in the Reference section.
No comments yet. Login to start a new discussion Start a new discussion