Pleasanter on Ubuntu 24.04 on Azure User Guide
Overview
Pleasanter (Implem.Pleasanter) is an open-source no-code / low-code business database platform — a self-hosted alternative to tools like Airtable and kintone. You build your own tables (Pleasanter calls them sites), records, views, dashboards and approval workflow entirely through the browser, with no programming, and drive everything from other systems through a full REST API.
This cloudimg image runs Pleasanter as a ready-to-use appliance: the ASP.NET Core application under Kestrel bound to loopback, a local PostgreSQL database, and nginx in front as the single public entry point. Pleasanter's own login page is the authenticated front door.
Read this before you expose the VM. The application is bound to 127.0.0.1:5000 and cannot be reached from the network directly. nginx on port 80 is the only public listener. Neither the application nor nginx starts until the machine's first boot has built the per-VM database and rotated the Administrator password — so there is no window in which Pleasanter is reachable with a default credential, and the upstream default login (Administrator / pleasanter) is rejected on every deployed VM.
What is included:
- Pleasanter 1.5.6.1 (the latest upstream release), unmodified, under the AGPL-3.0 licence — a single, fully-featured edition with no licence key and no paywalled tier
- The ASP.NET Core Runtime 10.0, installed from the Ubuntu 24.04 archive (
main) — never frompackages.microsoft.com - A local PostgreSQL 16 backing store, initialised on first boot with a per-VM schema and per-VM database passwords
- A per-VM Administrator password and a per-VM API key, generated on first boot and recorded in a root-only file
- The application bound to
127.0.0.1:5000only, with a dedicatedpleasanterservice account (NoNewPrivileges,ProtectSystem,ProtectHome) - nginx on port 80 as the only public listener, held closed until first boot completes
- 24/7 cloudimg support
Pleasanter is a trademark of Implem Inc. cloudimg is an independent packager and is not affiliated with, endorsed by, or sponsored by Implem Inc.
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting point — the whole stack (the .NET application, PostgreSQL and nginx) uses well under half of that. NSG inbound: allow 22/tcp from your management network and 80/tcp for the application. The image serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Pleasanter, and select Create. On Basics 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 Review + create -> Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group my-rg \
--name pleasanter \
--image cloudimg:pleasanter:pleasanter:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
# open the required ports, then read back the public IP
az vm open-port --resource-group my-rg --name pleasanter --port 22 --priority 1001
az vm open-port --resource-group my-rg --name pleasanter --port 80 --priority 1002
az vm list-ip-addresses --resource-group my-rg --name pleasanter \
--query "[0].virtualMachine.network.publicIpAddresses[0].ipAddress" -o tsv
Step 3 - Retrieve the per-VM credentials
First boot generates a unique Administrator password, a unique API key and unique database passwords, and writes them to a root-only file. SSH in and read them:
sudo cat /root/pleasanter-credentials.txt
The file is 0600 root:root, and both the application and nginx are gated on a bootstrap-ready marker that first boot only creates after the database is built and the Administrator password has been rotated:

Step 4 - Verify the deployment
Confirm the three services are active and that Kestrel is bound to loopback only while nginx faces the network:
systemctl is-active postgresql pleasanter nginx
ss -ltnp | grep -E ':(80|5000)'
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/
http://127.0.0.1/ returns 302 — Pleasanter redirects an unauthenticated request to its login page. Port 5000 answers only on 127.0.0.1; it is refused on the VM's routable address, so the application is never reachable except through nginx:

Step 5 - Log in to Pleasanter
Open http://<your-vm-ip>/ in a browser. Pleasanter shows its login page. Sign in with the login ID Administrator and the password from /root/pleasanter-credentials.txt:

After signing in you land on the top page, where your tables (sites) appear as tiles alongside the built-in start guide:

Step 6 - Build a table and add records (no code)
This is what Pleasanter is for. From the top page, use the + button to create a new table — choose a Records (Results) table, give it a title such as Team Tasks, and save. You now have a working database table with columns for status, manager, owner and update times, filtering, aggregation and CSV import/export, without writing any code:

Click any row to open the record editor, where you edit the title and body, set a status, owner and manager, attach files, add comments and keep a full change history:

Step 7 - Drive it from the REST API
Every table Pleasanter builds is immediately available over a REST API, authenticated with the per-VM API key from /root/pleasanter-credentials.txt. The example below creates a table, adds a record and reads it straight back. It uses the placeholder <API_KEY> — substitute the real key from the credentials file:
API_KEY='<API_KEY>'
BASE=http://localhost
SITE=$(curl -s -H 'Content-Type: application/json' \
-d "{\"ApiVersion\":1.1,\"ApiKey\":\"$API_KEY\",\"Title\":\"API Demo\",\"ReferenceType\":\"Results\",\"SiteSettings\":{}}" \
"$BASE/api/items/0/createsite")
SITE_ID=$(echo "$SITE" | sed -n 's/.*"Id":\([0-9]*\).*/\1/p' | head -1)
REC=$(curl -s -H 'Content-Type: application/json' \
-d "{\"ApiVersion\":1.1,\"ApiKey\":\"$API_KEY\",\"Title\":\"Ship the release\"}" \
"$BASE/api/items/$SITE_ID/create")
REC_ID=$(echo "$REC" | sed -n 's/.*"Id":\([0-9]*\).*/\1/p' | head -1)
curl -s -H 'Content-Type: application/json' \
-d "{\"ApiVersion\":1.1,\"ApiKey\":\"$API_KEY\"}" \
"$BASE/api/items/$REC_ID/get"
Each call returns a 200 status and the read-back returns the record with its title intact — the write path, the schema and API authentication proven in one loop:

You can create additional API keys per user under each user's API Settings in the Pleasanter UI.
Step 8 - Confirm the security posture
The image ships with no usable credential and no database — everything is minted on first boot:
- The upstream default login
Administrator/pleasanteris rejected; first boot rotates the Administrator password to a per-VM secret before the public listener ever opens. - Passwords are stored by Pleasanter as SHA-512 hashes; the credentials file is
0600 root:root. - PostgreSQL listens on loopback only, with a per-VM
postgrespassword and dedicated per-VM owner and user roles. - Both
pleasanter.serviceandnginx.servicecarryConditionPathExists=/var/lib/cloudimg/pleasanter-bootstrap-ready, so if first boot fails, the public listener never opens (fail closed).
Step 9 - Check the runtime and licensing
dotnet --list-runtimes
cat /opt/cloudimg/pleasanter-versions.txt
The ASP.NET Core Runtime 10.0 comes from the Ubuntu archive (noble-updates/main and noble-security/main), so it receives security updates through the normal apt channel, and Pleasanter itself is pinned to release 1.5.6.1:

Step 10 - Change the Administrator password
Sign in to Pleasanter, open the Administrator account from the user menu, and use Change password. To rotate it from the command line, update the SHA-512 hash directly (Pleasanter hashes passwords as unsalted lowercase-hex SHA-512):
NEWPASS='<new-password>'
HASH=$(printf '%s' "$NEWPASS" | sha512sum | awk '{print $1}')
sudo -u postgres psql -d "Implem.Pleasanter" \
-c "UPDATE \"Implem.Pleasanter\".\"Users\" SET \"Password\"='$HASH' WHERE \"LoginId\"='Administrator';"
Maintenance
Back up the database. All your tables and records live in the local PostgreSQL database Implem.Pleasanter:
sudo -u postgres pg_dump -Fc "Implem.Pleasanter" > pleasanter-backup.dump
Operating system updates are delivered through Ubuntu's unattended-upgrades, which remains enabled on the image. Reboot when a new kernel is installed. Keep the VM behind your own TLS termination and NSG rules before exposing it to untrusted networks.
Support
Every cloudimg image is backed by 24/7 support. If you have any questions about this deployment, contact the cloudimg team through the Azure Marketplace listing.