Colanode 0.4.7 on AWS User Guide
Overview
This guide covers launching and using the Colanode 0.4.7 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg office suites and workspaces listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Colanode is an open source, local first collaboration workspace: real time chat channels, collaborative pages and documents, databases (tables, boards and calendars made of pages) and file sharing in one place, a self hosted alternative to tools like Slack and Notion. The web and desktop clients keep a local copy of your workspaces, so they stay fast and keep working offline, then sync with your server when they reconnect.
What the cloudimg image adds:
- HTTPS from the first boot. nginx serves Colanode on port 443 with a certificate generated on your instance's first boot for its public DNS name. Port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped.
- An administrator unique to your instance, and sign-up closed. First boot creates and verifies one account,
admin@colanode.local, with a random password written to/root/colanode-credentials.txt(root only). nginx answers 403 to every sign-up until you open it, and new accounts need your verification, so a fresh instance is never open for anyone to join. nginx does not start until the administrator exists. - Per instance database secrets. PostgreSQL and Valkey passwords are generated on first boot and handed to the containers as read only files, never as environment variables or command line arguments. PostgreSQL accepts
scram-sha-256only, Valkey requires its password, and neither has a port on the host or the network. - The avatar path traversal fenced. Colanode 0.4.7 and earlier let a signed in user read files outside the avatar folder through
GET /client/v1/avatars/<id>(CVE-2026-110766, no fixed release yet). nginx only lets a plain letters-and-digits avatar id through, judged on the raw request, and refuses any request path that carries an encoded dot, slash or backslash, a..or an empty segment. Every build sends 16 bypass attempts and proves none of them reaches Colanode. - Risky entry points closed. Avatar upload (which decodes images with sharp 0.34.5, whose libvips fixes arrive only in sharp 0.35) and Google sign-in are refused at nginx; accounts show their initials instead of a picture.
- Containers and services blocked from the instance metadata service. A firewall rule drops container traffic to
169.254.169.254and to your VPC's addresses, and nginx, Docker and Colanode's unit carryIPAddressDenyfor the metadata addresses. The AMI requires IMDSv2. - Built from source and pinned. The Colanode server and web app are built from the v0.4.7 source with dependency fixes inside their version ranges, scanned with Trivy at build time, and PostgreSQL (pgvector 0.8.7 on PostgreSQL 17) and Valkey 8.1.11 are pulled by image digest. First boot never pulls an image.
- Workspace data on its own volume. PostgreSQL, Valkey and uploaded files live on a separate 10 GiB EBS volume mounted at
/var/lib/colanode, which you can grow or snapshot on its own. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: Colanode 0.4.7 (server and web app, Apache-2.0), PostgreSQL 17 with pgvector 0.8.7, Valkey 8.1.11, Docker Engine with the Compose plugin from Docker's repository, nginx 1.24, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The build record, Colanode's licence and the Trivy reports are in /usr/share/doc/colanode/.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a public IP or a route from your network.
- A security group that allows TCP 22 (SSH) from your admin network (for example
<your-mgmt-cidr>), and TCP 443 and TCP 80 (the redirect) from the networks your team works from. - A desktop browser. The web app needs a secure (HTTPS) page, which the image provides.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Colanode 0.4.7 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose an instance type, your key pair, your subnet and the security group above.
m5.large (2 vCPUs, 8 GiB) suits a team of a few dozen people. The image has two volumes: a 30 GiB root volume and a 10 GiB data volume (/dev/sdf) for /var/lib/colanode. Make the data volume bigger at launch if your team shares many files.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--block-device-mappings '[{"DeviceName":"/dev/sdf","Ebs":{"VolumeSize":50,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=colanode}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| Colanode 0.4.7 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
The login message shows where your URL and password are and how to add a teammate.
Step 3: Check the services
First boot takes about 20 seconds: it names the instance after its public DNS name and makes the certificate, generates the database passwords, starts the containers, creates the administrator and only then starts nginx. Check that everything is running:
systemctl is-active docker colanode-firstboot colanode nginx \
&& sudo test -f /var/lib/cloudimg/colanode-firstboot.done && echo FIRSTBOOT_DONE
active
active
active
active
FIRSTBOOT_DONE
Three containers run, all healthy: the Colanode server, PostgreSQL and Valkey.
sudo docker ps --format '{{.Names}} {{.Image}} {{.Status}}' | sort | tee /dev/stderr \
| grep -c '(healthy)' | grep -qx 3 && echo "3 containers healthy"
colanode-postgres pgvector/pgvector:0.8.7-pg17 Up 2 minutes (healthy)
colanode-server cloudimg/colanode-server:0.4.7 Up 2 minutes (healthy)
colanode-valkey valkey/valkey:8.1.11 Up 2 minutes (healthy)
3 containers healthy
Only SSH and nginx listen on the network. The Colanode server listens on 127.0.0.1:3000 behind nginx, and PostgreSQL and Valkey have no port on the host at all:
sudo ss -Hlnt | awk '{print $4}' | grep -vE '^(127\.|\[::1\]|\[::ffff:127\.)' \
| sed -E 's/.*:([0-9]+)$/\1/' | sort -un | xargs | tee /dev/stderr | grep -qx '22 80 443' && echo "network listeners: 22 80 443"
22 80 443
network listeners: 22 80 443
Your workspace data is on the data volume:
findmnt -no FSTYPE,TARGET /var/lib/colanode | head -n 1 | tee /dev/stderr | grep -q '^ext4 ' \
&& sudo ls /var/lib/colanode | xargs
ext4 /var/lib/colanode
lost+found postgres storage valkey
| Folder | What it holds |
|---|---|
/var/lib/colanode/postgres |
the PostgreSQL database (accounts, workspaces, pages, messages) |
/var/lib/colanode/storage |
uploaded files |
/var/lib/colanode/valkey |
the Valkey cache and sync channel |
Step 4: Get your URL and password
/root/colanode-credentials.txt (root only) holds everything generated on first boot:
sudo grep -o '^colanode\.[a-z.]*' /root/colanode-credentials.txt | tee /dev/stderr \
| grep -qx colanode.admin.pass && echo "credentials present"
colanode.url
colanode.admin.email
colanode.admin.pass
colanode.db.name
colanode.db.user
colanode.db.pass
credentials present
Show the values (keep them private):
sudo cat /root/colanode-credentials.txt
colanode.url is the address to open, for example https://ec2-203-0-113-10.compute-1.amazonaws.com/. It uses the instance's public DNS name, and the certificate is made for that name. Use this name rather than the IP address: the server only accepts changes from pages loaded from the name it is configured with (Step 9 changes it to your own domain).
Step 5: Open Colanode and add your server
In a desktop browser, open the colanode.url address. The certificate is self signed, so the browser warns once; choose Advanced and continue (or use your own domain and certificate, Step 9).
Colanode opens on Add a server. Choose Add a new server, enter your server's config URL, which is colanode.url followed by config, for example:
https://ec2-203-0-113-10.compute-1.amazonaws.com/config
and choose Create. Your server appears in the list as Colanode:

Step 6: Sign in
Choose your server, then sign in with admin@colanode.local and the colanode.admin.pass value from Step 4.

Colanode allows 10 sign-in attempts per email address in 10 minutes; after that, wait 10 minutes. The image has no outgoing email, so Forgot password? cannot send a reset link: keep the credentials file, and change the password in your account settings once you are in.
Step 7: Pages, chat and databases
Your workspace opens with a Home space holding a Welcome page and a Discussions channel. Click anywhere on a page and type, or press / to add headings, to-do lists, quotes, subpages and databases. Everything syncs to the server and to every device signed in to the workspace.

Open Discussions to chat in real time: type in the composer and press Enter.

Step 8: Add your team
Sign-up is closed:
sudo colanode-signup status | tee /dev/stderr | grep -qx 'sign-up is CLOSED' && echo SIGNUP_CLOSED
sign-up is CLOSED
SIGNUP_CLOSED
nginx refuses any sign-up while it is closed (403), and no account is created:
H="$(sudo sed -n 's/^set \$app_host "\(.*\)";$/\1/p' /etc/nginx/colanode-host.conf)"
curl -sk -o /dev/null -w '%{http_code}\n' --resolve "$H:443:127.0.0.1" -X POST -H "Origin: https://$H" \
-H 'Content-Type: application/json' --data '{"name":"Test","email":"test@example.com","password":"Not-a-real-1234"}' \
"https://$H/client/v1/auth/email/register" | tee /dev/stderr | grep -qx 403 && echo "sign-up refused"
403
sign-up refused
To add a teammate, open sign-up, let them register in the Colanode app (No account yet? Register on the login screen), verify their account, then close sign-up again:
sudo colanode-signup open
# they register in the app; their account waits for your verification
sudo colanode-activate --list
sudo colanode-activate <their-email>
sudo colanode-signup close
New accounts always wait for your verification, even while sign-up is open (account.verificationType is manual). Then invite them to your workspace from the workspace settings.
Step 9: Your own DNS name and certificate
Point a DNS name at the instance (an Elastic IP keeps the address fixed), then:
sudo colanode-set-hostname <your-dns-name>
This makes a new self signed certificate for the name, updates nginx, the cross site check and Colanode's web domain, and restarts the stack. Your config URL becomes https://<your-dns-name>/config; add it in the app as in Step 5.
For a certificate your browsers trust, replace /etc/ssl/colanode/colanode.crt (the full chain) and /etc/ssl/colanode/colanode.key (mode 0600, root) with your own and run sudo systemctl reload nginx. The certificate is only regenerated when you change the name again.
Step 10: Security checks
The server's public configuration and the full credential round trip (the web app, anonymous API calls refused, sign-up closed, a wrong password refused, the administrator signs in and opens a sync socket, the database passwords work):
H="$(sudo sed -n 's/^set \$app_host "\(.*\)";$/\1/p' /etc/nginx/colanode-host.conf)"
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/config" | jq -c '{name,version}' | tee /dev/stderr \
| grep -qx '{"name":"Colanode","version":"0.4.7"}' && sudo colanode-selftest | tail -n 1 | cut -c1-60
{"name":"Colanode","version":"0.4.7"}
round-trip OK https://ec2-203-0-113-10.compute-1.amazonaws.
The CVE-2026-110766 fence: an encoded traversal is refused before it reaches Colanode (400), and so is an avatar upload (403):
H="$(sudo sed -n 's/^set \$app_host "\(.*\)";$/\1/p' /etc/nginx/colanode-host.conf)"
T="$(curl -sk -o /dev/null -w '%{http_code}' --path-as-is --resolve "$H:443:127.0.0.1" "https://$H/client/v1/avatars/..%2f..%2fconfig")"
U="$(curl -sk -o /dev/null -w '%{http_code}' --resolve "$H:443:127.0.0.1" -X POST -H "Origin: https://$H" --data-binary x "https://$H/client/v1/avatars")"
echo "traversal=$T upload=$U" | tee /dev/stderr | grep -qx 'traversal=400 upload=403' && echo "avatar fences hold"
traversal=400 upload=403
avatar fences hold
The containers cannot reach the instance metadata service (and so cannot read the instance role's credentials):
sudo docker exec colanode-server node -e "fetch('http://169.254.169.254/latest/api/token',{method:'PUT',headers:{'X-aws-ec2-metadata-token-ttl-seconds':'60'},signal:AbortSignal.timeout(4000)}).then(r=>console.log('REACHED '+r.status)).catch(()=>console.log('BLOCKED'))" \
| tee /dev/stderr | grep -qx BLOCKED && echo "metadata service blocked for the containers"
BLOCKED
metadata service blocked for the containers
What else the image does:
- PostgreSQL and Valkey sit on an internal Docker network with no route out, and the server runs as an unprivileged user on a read only filesystem with every Linux capability dropped.
- nginx pins the host name and the client address it passes to Colanode (it never forwards
X-Forwarded-FororForwardedvalues a client sends) and refuses cross site state changes and WebSocket upgrades. - SSH accepts keys only, with no root login. No core dumps are written by the services that hold secrets.
- The firmware metadata refresh (
fwupd-refresh) is masked, as there is no firmware it could update on EC2.
Step 11: Managing the service
sudo systemctl restart colanode # restart the three containers
sudo docker logs --tail 50 colanode-server
sudo tail -n 20 /var/log/nginx/colanode-upstream.log # requests that reached Colanode
The stack is defined in /opt/colanode/docker-compose.yml; Colanode's configuration is /etc/colanode/config.json (logging level, workspace file size limit).
Step 12: Backup and maintenance
Everything your team creates is on the data volume. For a consistent backup, stop the stack, snapshot the volume, and start it again:
sudo systemctl stop colanode
aws ec2 create-snapshot --volume-id <data-volume-id> --description "colanode backup"
sudo systemctl start colanode
Keep /root/colanode-credentials.txt and /etc/colanode/ with your backups: the database password in /etc/colanode/pg_password is needed to open a restored database.
Operating system updates install automatically (unattended security upgrades). The Colanode, PostgreSQL and Valkey images are fixed at build time; new Colanode releases arrive as new versions of this listing.
Step 13: Security recommendations
- Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your team works from.
- Use your own DNS name and a trusted certificate (Step 9).
- Change the administrator password after your first sign-in, and keep sign-up closed except while you add people.
- Snapshot the data volume regularly.
Support and licensing
Colanode is open source under the Apache License 2.0; there is no per user licence fee. The AMI price covers cloudimg's hardening, first boot setup and support. The licence, the build notice and the third party list are in /usr/share/doc/colanode/.
Colanode is a trademark of its respective owner. This image is produced by cloudimg and is not affiliated with, endorsed by, or sponsored by the Colanode project.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA