Frappe Builder
Overview
Frappe Builder is an open-source visual website builder built on the Frappe framework. It gives you a drag-and-drop canvas for laying out pages, direct control over styling, spacing and typography, reusable components you can share across pages, a scripting and data-binding layer for dynamic content, previews across device breakpoints, and one-click publishing of finished pages to public routes on the same host.
This SecureAnyCloud image installs Builder v1.31.0 on Frappe framework v15.116.0 as a full production deployment. The stack comprises MariaDB, Redis, a Python gunicorn web tier plus a node realtime process, background workers and a scheduler managed by supervisor, and nginx on port 80. The entire headless install runs at build time, so there is no command-line bootstrap on first use. On the first boot of every VM, the image rotates the Frappe Administrator password, the site database password and the Frappe encryption key. The image is backed by 24/7 SecureAnyCloud support.
What you get:
- Frappe Builder v1.31.0 on Frappe framework v15.116.0, served on port 80 by nginx in front of a gunicorn web worker
- MariaDB on loopback (Barracuda / utf8mb4 / large packets per Frappe), tuned for a small VM
- Redis for cache, queue and socketio, and supervisor managing the Frappe web, worker, schedule and socketio processes
- The node realtime process on a unix socket rather than a network port, so nothing extra is exposed
- A unique Administrator password, site database password and Frappe encryption key generated on first boot, with no default login and anonymous self-registration disabled
nginx.service,supervisor.service,mariadb.serviceandredis-server.serviceas systemd units, enabled and active- 24/7 SecureAnyCloud support
Frappe Builder and the Frappe framework are both MIT licensed, so there is no per-seat, per-page or per-site fee.
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet and subnet in the target region.
Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended size, because the interactive canvas and any re-run of the front-end asset build are the memory peak. Standard_B2s (2 vCPU / 4 GiB) is the supported minimum for light use.
In the NSG, allow inbound 22/tcp from your management network, and 80/tcp for the Builder studio and for the pages you publish. Front the site with TLS for public exposure (see Enabling HTTPS).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Frappe Builder by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80). Then select Review + create and Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:frappe-builder-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name frappe-builder \
--image sac1647283583153:frappe-builder-ubuntu-24-04:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name frappe-builder --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the Builder stack is running
On first boot, the image rotates the Frappe encryption key, the site database password and the Administrator password, points the site at this VM's public IP, and starts the production stack. Confirm that all four systemd services are active:
systemctl is-active mariadb redis-server supervisor nginxAll four report active:
active active active activeSupervisor runs the Frappe web, socketio, worker and schedule processes:
supervisorctl statusfrappe-bench-web:frappe-bench-frappe-web RUNNING pid 8714, uptime 0:03:25 frappe-bench-web:frappe-bench-node-socketio RUNNING pid 8715, uptime 0:03:25 frappe-bench-workers:frappe-bench-frappe-long-worker-0 RUNNING pid 8718, uptime 0:03:25 frappe-bench-workers:frappe-bench-frappe-schedule RUNNING pid 8716, uptime 0:03:25 frappe-bench-workers:frappe-bench-frappe-short-worker-0 RUNNING pid 8717, uptime 0:03:25Confirm that the Frappe web tier answers its health endpoint:
curl -s http://127.0.0.1/api/method/pingFrappe returns {"message":"pong"}. To see the exact installed apps and versions (Frappe framework 15.116.0 and Builder 1.31.0), run:
sudo -u frappe -H bash -lc 'cd /opt/frappe/frappe-bench && bench --site builder.localhost list-apps'frappe 15.116.0 HEAD builder 1.31.0 HEADOnly ports 22 and 80 are reachable from the network. MariaDB, Redis and the gunicorn web worker are bound to loopback, and the node realtime process listens on a unix socket rather than a TCP port:
ss -lntuH | awk '{print $1, $5}' | sort -utcp 0.0.0.0:22 tcp 0.0.0.0:80 tcp 127.0.0.1:3306 tcp 127.0.0.1:6379 tcp 127.0.0.1:8000 tcp 127.0.0.53%lo:53 tcp 127.0.0.54:53 tcp [::1]:6379 tcp [::]:22 tcp [::]:80 udp 10.0.0.14%eth0:68 udp 127.0.0.1:323 udp 127.0.0.53%lo:53 udp 127.0.0.54:53 udp [::1]:323Step 5 - Retrieve the Administrator password
The per-VM Administrator password is generated on first boot and written to a root-only credentials file, along with the studio URL and login name. Read it with:
sudo cat /root/frappe-builder-credentials.txtThe file is mode 0600 and owned by root. Confirm this with:
sudo stat -c '%a %U:%G %n' /root/frappe-builder-credentials.txt600 root:root /root/frappe-builder-credentials.txtBecause these secrets are generated on first boot, no two deployments share the same password, the published vendor defaults are rejected, anonymous visitors cannot read or write Builder content, and self-registration is refused.
You can reproduce the core of that check yourself. Sign in through the API with the password from your credentials file, and fetch the studio with that session:
curl -s -c /tmp/builder-cookies -o /dev/null -w 'login: %{http_code}\n' \
http://127.0.0.1/api/method/login \
--data-urlencode 'usr=Administrator' --data-urlencode 'pwd=<BUILDER_ADMIN_PASSWORD>'
curl -s -b /tmp/builder-cookies -o /dev/null -w 'builder: %{http_code}\n' http://127.0.0.1/builder rm -f /tmp/builder-cookiesBoth requests return 200.
The boundary that protects your work is at the API layer, not at the front door. Requesting /builder without a session also returns 200, because Frappe serves the studio's static application shell to anyone. That shell contains none of your content. The studio's router sends an unauthenticated visitor straight to /login, the Frappe desk at /app is gated behind sign-in, and every Builder content API refuses an anonymous caller. Reading the page list and attempting a write both return 403:
curl -s -o /dev/null -w 'anon page list: %{http_code}\n' \
'http://127.0.0.1/api/method/frappe.client.get_list?doctype=Builder%20Page&limit_page_length=5'
curl -s -o /dev/null -w 'anon write: %{http_code}\n' -X POST \
-H 'Content-Type: application/json' -d '{"page_title":"anon"}' \
'http://127.0.0.1/api/resource/Builder%20Page'anon page list: 403 anon write: 403This is deliberate. Publishing pages to public routes is what the product is for, so the image does not put a blanket gate in front of nginx. It enforces the boundary on the data instead.
Step 6 - Sign in to Frappe Builder
Browse to http://<vm-public-ip>/builder and sign in as Administrator with the password from Step 5. After your first sign-in, change this password from the Frappe desk at /app.
There is no sign-up link on this page, because anonymous self-registration is disabled in this image. You add further users yourself from the desk.
Step 7 - Work with pages
After you sign in, you land on All Pages, which lists every page in this workspace as a card with its title and when it was last edited. Filter by title or route, change the sort order, switch between grid, list and tree views, group pages into folders from the sidebar, and use New to start a page from a blank canvas or from a template.
A fresh instance starts empty, because the image ships with no sample pages.
Step 8 - Design a page on the canvas
Opening a page puts you in the visual editor. The canvas in the middle renders the page as it will look. The left rail carries the block tree, the component library, the asset browser and the script editor. The right rail shows the properties of whatever block you select: link, layout (stack or grid, direction, placement, distribution, gap, wrap), typography (family, weight, size) and style (opacity, background, borders).
Select an element on the canvas and edit it directly, and drag blocks to reorder them. Use the device selector above the canvas to check the layout at each breakpoint.
You can save blocks you expect to reuse as components and drop them into any other page, so a header, footer or call to action is maintained in one place. Use the script editor to attach client scripts and data bindings to a page when you need content that comes from the database rather than from the canvas.
Step 9 - Publish the page
Give the page a route, then use Publish Changes in the top right. Frappe Builder renders the page and serves it at that route on this same host, so http://<vm-public-ip>/<your-route> is live immediately to anonymous visitors, which is what a website builder is for. To serve the page on your own domain, point a DNS record at the VM and add TLS (below).
Published pages are intentionally public. Everything else is not: the studio's router sends an unauthenticated visitor to the sign-in page, the Frappe desk requires a session, and the Builder content APIs refuse anonymous reads and writes (see Step 5). Only the pages you explicitly publish are reachable without signing in.
Enabling HTTPS
For public exposure, front the site with TLS. Point a DNS A record at the VM's public IP, then issue a certificate with Certbot and the nginx plugin. Run the commands interactively:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comCertbot edits the Frappe nginx site in place and sets up automatic renewal. Allow 443/tcp in your NSG. Then tell Frappe its public address, so that generated links and redirects use it:
sudo -u frappe -H bash -lc "cd /opt/frappe/frappe-bench && bench --site builder.localhost set-config host_name 'https://your-domain.example.com'"
sudo systemctl restart supervisorMaintenance
The OS keeps receiving security updates through unattended-upgrades.
You can update Frappe Builder and the framework with bench as the frappe user (sudo -u frappe -H bash -lc 'cd /opt/frappe/frappe-bench && bench update'). Review the Builder release notes before you apply a major version upgrade, and take a snapshot of the OS disk before any upgrade.
The full dependency licence inventory for this image is at /usr/share/frappe-builder/dependency-licences.txt.
Support
This image is published and supported by SecureAnyCloud. Frappe and Frappe Builder are trademarks of Frappe Technologies Pvt. Ltd.; SecureAnyCloud is not affiliated with or endorsed by the Frappe project. For help, contact SecureAnyCloud support.
Deploy on Azure
Launch Frappe Builder on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com