Deployment guide

Colanode

Overview

Colanode is an open-source, local-first collaboration workspace. It combines real-time chat channels, collaborative pages and documents, flexible databases and file sharing in one place, as a self-hosted alternative to tools like Slack and Notion.

Colanode is local-first: the desktop and web clients keep a full local copy of your workspaces. The app stays fast and keeps working offline, then syncs your changes back to the server when you reconnect.

This SecureAnyCloud image runs the free, open-source, Apache-2.0 licensed Colanode server and web client as the upstream containers, the officially supported way. PostgreSQL with the pgvector extension and Valkey, a Redis-compatible cache, run alongside them. Everything is captured into the VM, so your instance starts in seconds.

The upstream project ships with open registration, so this image ships with no known secret. Each VM generates its own secrets on first boot, before the app is reachable, and public signup is closed by default. A fresh instance is never world-joinable.

Colanode is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by Colanode. It ships the free, open-source, Apache-2.0 licensed self-hosted software, unmodified.

What you get:

  • Colanode server v0.4.7 (the Apache-2.0 licensed Node server and sync engine), pinned by image digest
  • Colanode web client v0.4.7 (the Apache-2.0 licensed browser workspace), pinned by image digest
  • PostgreSQL 17 with the pgvector extension, and Valkey 8.1, both bound to the internal container network only and never exposed to any host port
  • Built-in file storage for uploads on a persistent volume, so no external object store is required
  • Docker Engine with the server and web client published to the loopback interface only, fronted by nginx on port 443 (with 80 redirecting to 443)
  • colanode.service, colanode-firstboot.service, colanode-postboot.service and nginx.service as systemd units, enabled and active on boot
  • Unique PostgreSQL and Valkey passwords, a per-instance self-signed TLS certificate and a per-instance administrator account with a random password, all generated per VM on first boot and never baked into the image
  • Public signup closed by default (verificationType=manual), no default login and empty datastores on first boot
  • Ubuntu 24.04 LTS base with the latest security patches applied at build time
  • Azure Linux Agent for cloud integration and SSH key injection
  • 24/7 SecureAnyCloud support with a guaranteed 24-hour response SLA

Prerequisites

  • An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
  • A subscription to the Colanode listing on Azure Marketplace

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is a sensible starting size for a small team. For larger teams or heavier use, choose Standard_D2s_v5 or larger.

In the NSG, allow 22/tcp from your management network. Allow 443/tcp for the web client from the networks that use it, and 80/tcp for the automatic redirect to HTTPS.

The web client is a browser application that requires a secure context, so it is served over HTTPS. The image generates a per-instance self-signed certificate, and your browser warns about it on first visit. Click through once, or attach your own domain and a trusted certificate as shown in Step 15.

1

Deploy from the Azure Portal

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Colanode 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 HTTPS (443).

Select Review + create, then Create.

2

Deploy from the Azure CLI

Run the commands below to create the network, the NSG rules and the VM. Replace <your-mgmt-cidr> with your management network range.

RG="colanode-prod"; LOCATION="eastus"; VM_NAME="colanode-01" IMAGE_URN="sac1647283583153:colanode-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name cola-vnet --address-prefix 10.100.0.0/16 --subnet-name cola-subnet --subnet-prefix 10.100.1.0/24 az network nsg create -g "$RG" --name cola-nsg az network nsg rule create -g "$RG" --nsg-name cola-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name cola-nsg --name allow-https --priority 110 \
  --destination-port-ranges 443 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name cola-nsg --name allow-http-redirect --priority 120 \
  --destination-port-ranges 80 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:colanode-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name cola-vnet --subnet cola-subnet --nsg cola-nsg --public-ip-sku Standard
3

Connect to your VM

ssh azureuser@<vm-ip>

On first boot, the VM generates the per-instance secrets, brings up the stack and seeds your administrator account. This usually completes within a minute or two of the VM first reaching the running state.

4

Confirm the services are running

Run the commands below to check three things. All five systemd units should be active, and the four containers should be up. Only 80 and 443 should be public: the server and web client bind to loopback, and PostgreSQL and Valkey are on no host port at all.

systemctl is-active docker colanode-firstboot colanode colanode-postboot nginx
sudo docker ps --format '{{.Names}}\t{{.Status}}'
sudo ss -tlnp | grep -E ':443 |:80 |:3000 |:4000 |:5432 |:6379 '

Expected output:

active active active active active colanode-web-1 Up (healthy) colanode-server-1 Up colanode-postgres-1 Up (healthy) colanode-valkey-1 Up (healthy) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 511 0.0.0.0:443 0.0.0.0:* LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:* LISTEN 0 4096 127.0.0.1:4000 0.0.0.0:*

Note that there are no listeners on 5432 or 6379. PostgreSQL and Valkey are reachable only on the private container network, never from the host or the internet.

5

Read the per-instance credentials

On first boot, the VM writes your administrator account and its random password to a root-only file. Read it with sudo:

sudo cat /root/colanode-credentials.txt

Expected output (the password value is unique to your VM):

WEB_URL=https://<vm-ip>/ SERVER_URL=https://<vm-ip> ADMIN_EMAIL=admin@colanode.local ADMIN_PASSWORD=<set-at-first-boot> WORKSPACE=General
6

Verify the security model

Public signup is closed by default (verificationType=manual), so a fresh instance is not world-joinable. The API rejects an unauthenticated request to create a workspace. The seeded per-instance account authenticates end to end.

Run the checks below:

grep verificationType /etc/colanode/config.json curl -ks -o /dev/null -w 'unauthenticated POST -> HTTP %{http_code}\n' \
  -X POST -H 'Content-Type: application/json' -d '{"name":"x"}' \
  https://127.0.0.1/client/v1/workspaces
sudo /usr/local/sbin/colanode-roundtrip.sh

Expected output:

"account": { "verificationType": "manual", "otpTimeout": 600 }, unauthenticated POST -> HTTP 401 OK round-trip: web=https://<vm-ip>/ server=https://<vm-ip> admin=admin@colanode.local (per-VM account gates the API; unauth/wrong-token create rejected 401/403; workspace create+readback 200; web UI + server /config live)
7

Open the web client and add your server

In a desktop browser, open your instance:

https://<vm-ip>/

The certificate is self-signed, so your browser shows a one-time warning. Choose Advanced, then Proceed. Alternatively, attach your own domain and certificate (Step 15).

Colanode opens on the Add a server screen. Click Add a new server and enter your server's config URL exactly:

https://<vm-ip>/config

Then click Create.

8

Sign in

Select the server you just added. Sign in with the seeded administrator account from Step 5: admin@colanode.local and the random ADMIN_PASSWORD.

New self-registrations are held inactive by default, so use this seeded account first. Step 11 shows how to open signup or activate additional users.

9

Write pages and documents

In your workspace, the left rail lists your spaces. Each space holds pages, channels and databases.

Open the Welcome page to see the block editor. Click anywhere and start typing, or press / to insert headings, to-dos, blockquotes, subpages and databases.

Everything you write syncs to your server and to any other device signed in to the same account.

10

Chat in a channel

Open the Discussions channel to chat with your team in real time. Type a message in the composer at the bottom and press Enter.

Messages appear instantly and sync to every member of the workspace.

11

Manage signup and users

By default, account.verificationType is manual. Anyone can submit the registration form, but new accounts stay inactive until you approve them. You have three options.

Open self-signup so that anyone can register and use the server immediately. Edit the server config and restart:

sudo sed -i 's/"verificationType": "manual"/"verificationType": "automatic"/' /etc/colanode/config.json
sudo systemctl restart colanode

Activate a specific user who has registered, and keep signup otherwise closed:

sudo docker compose --env-file /etc/colanode/colanode.env -f /etc/colanode/compose.yaml \
  exec -T postgres psql -U colanode_user -d colanode_db \
  -c "UPDATE accounts SET status = 1 WHERE email = '<their-email>';"

Require email verification instead. Set verificationType to email and configure SMTP under the email block of /etc/colanode/config.json, with email.enabled set to true. Then restart the service.

12

Explore the server API

The server exposes a public configuration endpoint and a client API under /client/v1. Run the commands below to confirm the server, its version and its file storage:

curl -ks https://127.0.0.1/config | jq -c '{name,version,sha}' grep -o '"provider": {[^}]*}' /etc/colanode/config.json

Expected output:

{"name":"Colanode","version":"0.4.7","sha":"d649523637f0f059c936418488165d4a689da27c"} "provider": { "type": "file", "path": "/var/lib/colanode/storage", "directory": "/var/lib/colanode/storage" }
13

Server components

  • Colanode server (ghcr.io/colanode/server): the Node API and sync engine, published to 127.0.0.1:3000 and reached through nginx at /config and /client/
  • Colanode web client (ghcr.io/colanode/web): the static browser workspace, published to 127.0.0.1:4000 and served at /
  • PostgreSQL 17 with pgvector (pgvector/pgvector:pg17): the primary datastore, on the internal container network only
  • Valkey 8.1 (valkey/valkey:8.1): the Redis-compatible cache and sync channel, on the internal container network only
  • nginx: the host reverse proxy, terminating TLS on 443 and redirecting 80 to 443
  • Configuration and storage: configuration lives in /etc/colanode/config.json and per-VM secrets in /etc/colanode/colanode.env. Uploads persist in the server_storage volume.
14

Managing the service

Use these commands to restart the service, check container status and read the server logs:

sudo systemctl restart colanode
sudo docker compose --env-file /etc/colanode/colanode.env -f /etc/colanode/compose.yaml ps
sudo docker compose --env-file /etc/colanode/colanode.env -f /etc/colanode/compose.yaml logs --tail 50 server
15

Use your own domain and HTTPS (production)

The image ships a per-instance self-signed certificate so the browser client works out of the box. For a certificate without browser warnings, point a DNS name at the VM, then replace the certificate. The simplest method is Certbot with the nginx plugin:

sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
sudo certbot --nginx -d <your-domain> -m <your-email> --agree-tos --redirect

After Certbot issues the certificate, edit /etc/colanode/config.json. Set web.domain to your domain and cors.origin to https://<your-domain>. Then run sudo systemctl restart colanode.

When you add the server in the web client, enter https://<your-domain>/config.

16

Security recommendations

  • Restrict 22/tcp to your management network in the NSG, and expose 443/tcp only to the networks that need the workspace
  • Keep public signup closed (verificationType=manual) unless you intend to run an open server, and activate users deliberately
  • Replace the self-signed certificate with a trusted one for production (Step 15)
  • Keep the per-instance credentials file (/root/colanode-credentials.txt) private, and rotate the administrator password after your first sign-in
  • Apply operating system updates regularly with sudo apt update && sudo apt upgrade
17

Support and Licensing

Colanode is free, open-source software distributed under the Apache-2.0 license. This image bundles the unmodified upstream server and web client with PostgreSQL, pgvector and Valkey, configured securely for Azure.

SecureAnyCloud provides 24/7 support with a guaranteed 24-hour response SLA for image and deployment issues. For questions about Colanode features, consult the upstream project documentation.

Colanode is a trademark of its respective owner. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by Colanode.

Deploy on Azure

Search the Azure Marketplace for Colanode on Ubuntu 24.04 LTS by SecureAnyCloud to deploy this image.

Deploy on Azure

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