Deployment guide

AppFlowy

Overview

AppFlowy is the open source alternative to Notion for notes, documents, wikis, tasks and lightweight project boards. This image runs AppFlowy on Ubuntu 24.04 LTS and ships the fully self-hosted AppFlowy-Cloud backend together with the AppFlowy web application.

Your whole workspace, including every page, database and uploaded file, lives inside your own Azure subscription rather than a hosted service.

AppFlowy self-hosts as a small set of services, orchestrated by Docker Compose and managed by systemd:

  • appflowy_web: the Notion-like web application (served at /)
  • appflowy_cloud: the Rust API and realtime collaboration server (/api, /ws)
  • appflowy_worker: a background worker for imports and housekeeping
  • gotrue: the authentication service (email/password sign-up and sign-in, at /gotrue)
  • admin_frontend: an administration console for managing users (at /console)
  • postgres (PostgreSQL 16 with pgvector): the workspace, document and user catalogue
  • redis: collaboration state and cache
  • minio: an S3-compatible object store for uploaded files and attachments

nginx on port 80 fronts everything on a single origin. It serves the web app at / and proxies the API at /api, the auth service at /gotrue, the admin console at /console and the object store at /minio-api. It also answers an unauthenticated /healthz for load-balancer probes.

Because every service is reached through nginx on the one public address, there is only one port (80) to open.

What you get:

  • The full AppFlowy-Cloud self-host stack (web, cloud, worker, gotrue, admin console, PostgreSQL, Redis, MinIO) run under Docker Compose via an appflowy.service systemd unit, from images pinned by digest
  • The web app, API, auth service, admin console and object store all on port 80 behind nginx, same-origin, with no CORS and no extra ports
  • Every secret generated fresh per VM on first boot: the PostgreSQL password, the GoTrue JWT signing secret, the admin console password, and the MinIO access and secret keys. No upstream default (hello456, password, minioadmin) survives into the image.
  • The workspace, document and file store on a dedicated Azure data disk at /var/lib/appflowy, captured into the image
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • Unattended security upgrades enabled on the base OS

Free self-hosted tier: seat limit

The self-hosted AppFlowy free tier allows one Member/Owner user plus up to three guests per server.This is an AppFlowy licensing characteristic, not a SecureAnyCloud limitation. The first account you create becomes the workspace owner, and additional full members require an AppFlowy subscription or licence.

Prerequisites

  • An Azure subscription and the Azure CLI (az) signed in, or access to the Azure Portal
  • An SSH key pair for the admin (azureuser) account
  • A Network Security Group that allows inbound TCP 22 (SSH, your admin IP only) and TCP 80 (the web app)
  • The recommended VM size is Standard_D2s_v3 (2 vCPU / 8 GB). The stack runs comfortably there, and smaller sizes are not recommended for the full multi-service stack.

Step 1 - Launch the VM

Option A - Azure Portal

  • From the SecureAnyCloud AppFlowy on Ubuntu 24.04 LTS offer, choose Create.
  • Pick your resource group and region, and set the VM size to Standard_D2s_v3.
  • Set the admin username to azureuser and upload your SSH public key.
  • Under Networking, allow inbound SSH (22) from your admin IP and HTTP (80) from the clients that need the web app.
  • Review and create the VM.

Option B - Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:appflowy-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-resource-group> \
  --name appflowy \
  --image sac1647283583153:appflowy-ubuntu-24-04:default:latest \
  --size Standard_D2s_v3 \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Open port 80 only to the networks that need the web app. SSH is opened for your admin IP separately.

az network nsg rule create \
  --resource-group <your-resource-group> \
  --nsg-name <your-nsg> \
  --name allow-http --priority 1001 \
  --source-address-prefixes <your-CIDR> \
  --destination-port-ranges 80 --access Allow --protocol Tcp

Never use 0.0.0.0/0, * or Internet as the source. A fresh deploy accepts new sign-ups (Step 5) and serves plain HTTP, so anyone who can reach port 80 could create an account until you close sign-up.

Step 2 - First boot and the per-VM credentials

On the first boot, appflowy-firstboot.service generates a fresh set of secrets unique to this VM, sets the public address and brings the stack up. It writes the secrets to a root-only file. Allow a minute or two for the first boot, then connect over SSH:

ssh azureuser@<vm-ip>

Read your per-VM credentials. The secret values are unique to your VM and are masked below:

sudo cat /root/appflowy-credentials.txt

The file records the URLs, the admin console login (admin@appflowy.local plus a per-VM password) and the MinIO object-store keys. Store them somewhere safe.

Step 3 - Verify the stack

Confirm all nine services are running:

sudo docker compose -f /opt/appflowy/docker-compose.yml ps

Step 4 - Health check

Check the web app, the API and the auth service through nginx. The API correctly returns 401 when called without a token, which confirms authentication is enforced:

curl -s -o /dev/null -w "healthz: %{http_code}\n" http://127.0.0.1/healthz
curl -s -o /dev/null -w "gotrue health: %{http_code}\n" http://127.0.0.1/gotrue/health
curl -s -o /dev/null -w "api (no token): %{http_code}\n" http://127.0.0.1/api/workspace

Step 5 - Create your account

Open http://<vm-ip>/ in your browser. On the welcome page, choose Sign up here and create your account with an email and a password.

Sign-ups are auto-confirmed on this appliance because no email server is configured by default, so you can sign in immediately. Remember the free-tier seat limit: the first account becomes the workspace owner.

Sign-up is open on a fresh deploy. Until you disable it, anyone who can reach the VM on port 80 can create an auto-confirmed account. Create your own account first, then close sign-up straight away.

Close sign-up right after your first account is created. Run this over SSH:

sudo sed -i 's/GOTRUE_DISABLE_SIGNUP=false/GOTRUE_DISABLE_SIGNUP=true/' /opt/appflowy/docker-compose.yml cd /opt/appflowy && sudo docker compose up -d gotrue
sudo grep -n 'GOTRUE_DISABLE_SIGNUP' /opt/appflowy/docker-compose.yml

The last command prints GOTRUE_DISABLE_SIGNUP=true. Existing accounts keep working. To add more users later, invite them from the admin console (with email enabled) or set the value back to false briefly.

Put HTTPS in front of the VM. The appliance serves plain HTTP on port 80, so passwords and documents cross the network unencrypted. Before you store real data, put a TLS-terminating proxy or an Azure Application Gateway with a certificate in front of the VM, and keep the NSG source restricted.

Step 6 - Your workspace

After you sign in, you land in your workspace, with the sidebar on the left and a Getting started document already open. From here you can organise pages into spaces, share them and collaborate.

Step 7 - Create and edit a document

Click New page, choose a space, and start writing. AppFlowy's block editor supports rich text, headings, checklists, tables and more. Type / to insert a block.

The admin console

The admin console at http://<vm-ip>/console lets an operator manage the users on the server. Sign in with the APPFLOWY_ADMIN_EMAIL (admin@appflowy.local) and APPFLOWY_ADMIN_PASSWORD from your credentials file.

Optional: enable email (SMTP)

By default no email server is configured, so sign-ups are auto-confirmed and password-reset and invitation emails are not sent. To enable email, add your SMTP settings to /opt/appflowy/.env (GOTRUE_SMTP_HOST, GOTRUE_SMTP_PORT, GOTRUE_SMTP_USER, GOTRUE_SMTP_PASS, GOTRUE_SMTP_ADMIN_EMAIL), set GOTRUE_MAILER_AUTOCONFIRM=false, and recreate the stack:

cd /opt/appflowy && sudo docker compose up -d

Optional: enable AI features

AppFlowy's AI writing and chat features are off by default. To enable them, provide an OpenAI API key and add the ai service. Set AI_OPENAI_API_KEY in /opt/appflowy/.env, follow the upstream AppFlowy-Cloud AI documentation, then recreate the stack.

Data and backups

The PostgreSQL catalogue and the MinIO object store live in Docker volumes on the dedicated data disk at /var/lib/appflowy, which is captured into the image and re-provisioned on every VM. To back up, snapshot the data disk from Azure, or use docker compose to dump the postgres database and mirror the minio bucket.

Assign a static public IP so the object-store and auth URLs remain stable.

Troubleshooting

  • The web app does not load. Confirm port 80 is open in your NSG and that sudo docker compose -f /opt/appflowy/docker-compose.yml ps shows all services up. Check curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1/healthz returns 200.
  • "Seat limit reached" on sign-up. The free self-hosted tier allows one Member/Owner. Sign in as the existing owner and invite guests, or apply an AppFlowy licence for more members.
  • Sign-in issues after changing the address. The public address is baked in at first boot. If you change the VM's public IP, edit FQDN in /opt/appflowy/.env to the new address and run cd /opt/appflowy && sudo docker compose up -d.
  • Inspect logs. cd /opt/appflowy && sudo docker compose logs --tail 100 appflowy_cloud gotrue.

Support

This image is maintained by SecureAnyCloud and backed by 24/7 support. For help with deployment or configuration, contact the SecureAnyCloud team via the Azure Marketplace listing.

Deploy on Azure

Launch AppFlowy 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

Deploy on Azure