Komodo
Overview
Komodo is an open-source build and deployment platform for Docker hosts. From one web interface you define stacks and deployments, build images from your own git repositories, run scheduled procedures, and watch the state of everything you have deployed. It replaces keeping compose files on a server and driving them over SSH, and it records what was deployed, when and by whom.
This SecureAnyCloud image delivers Komodo 2.3.3 on Ubuntu 24.04 as a complete, self-contained appliance.
What you get:
- Komodo Core: the API and web interface, reachable only through an encrypted front door
- Komodo Periphery: the agent that creates, starts and destroys containers on this VM, already connected to Core
- FerretDB over a PostgreSQL 17 document engine: the database beneath Komodo, reachable from neither the network nor any other container
- nginx terminating TLS on port 443 with a certificate generated on your own VM, installed from the Ubuntu archive so it keeps receiving security updates
- Docker Engine from the Ubuntu archive, for the same reason
alpine:3.22, already present, so your first deployment works without reaching a registry- On-VM self-tests you can run at any time, each of which is itself tested against a known bad input first
- 24/7 SecureAnyCloud support
This image ships with no shared password. On first boot, your VM generates its own administrator password, database password, session signing key and TLS certificate. It writes them to a file that only root can read, and it refuses to start Komodo until it has done so. Self registration is switched off, so nobody can create an account by visiting the page.
Read this before you connect Komodo to anything you care about. Komodo manages Docker on this VM. The agent that does so has full control of the container engine, which is equivalent to administrative access to the machine. That is inherent to what Komodo is, not a property of this image.
Whoever holds the Komodo administrator credential can run any container here. Give Komodo its own VM, which is exactly what this image is, and treat its password as you would treat root on this machine.
The data layer avoids the Server Side Public License entirely. Komodo speaks the MongoDB wire protocol, and this image serves it with FerretDB (Apache-2.0) over the DocumentDB PostgreSQL extension (MIT). No MongoDB component is installed.
Komodo, Docker, FerretDB and PostgreSQL are trademarks of their respective owners. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. This image packages the unmodified open-source software, which is distributed under the GNU General Public License v3.0.
Prerequisites
You need:
- An Azure subscription
- A VM size with at least 2 vCPUs and 8 GiB of memory.
Standard_B2msis the recommended size, and the image is tuned for it. It runs four containers, one of them a PostgreSQL cluster, and leaves room for the containers you deploy. - Inbound TCP 443 open to the addresses you will administer Komodo from, and 22 for SSH. Nothing else needs to be open.
- An SSH key pair
Deploy from the Azure Marketplace
In the Azure Marketplace, find Komodo on Ubuntu 24.04 LTS and choose Create. Select Standard_B2ms or larger.
On the Networking tab, allow inbound 443 and 22. Leave everything else at its default and create the VM.
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:komodo-ubuntu-24-04:default:latest
az vm create \
--resource-group my-resource-group \
--name my-komodo \
--image sac1647283583153:komodo-ubuntu-24-04:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardOpen port 443 for the web interface. Port 22 is used for SSH:
az vm open-port --resource-group my-resource-group --name my-komodo --port 443 --priority 1001Connect to your VM
Connect over SSH as azureuser:
ssh azureuser@<vm-public-ip>Confirm the appliance is running
Komodo is four containers plus an encrypted front door, and all of it starts automatically at boot. Check the services and containers:
systemctl is-active docker nginx komodo-postgres komodo-ferretdb komodo-core komodo-peripherysudo docker ps --format 'table {{.Names}}\t{{.Status}}'Each of the four images is pinned to exact content rather than to a moving tag. None of them is fetched at runtime.
Find your VM's administrator password
This image does not ship with a password. Your VM generated its own on first boot, before Komodo was allowed to start. Print the credentials file with the password hidden:
sudo sed -E 's/^(KOMODO_ADMIN_PASSWORD=).*/\1REDACTED/' /root/komodo-credentials.txtThe file is 0600 root:root. To read the real password, run:
sudo grep '^KOMODO_ADMIN_PASSWORD=' /root/komodo-credentials.txt | cut -d= -f2-The sign-in address is in the same file:
sudo grep '^KOMODO_URL=' /root/komodo-credentials.txt | cut -d= -f2-Sign in to the web interface
Open https://<KOMODO_ADDRESS>/ in a browser. The certificate was generated on your VM, so your browser warns that it is not signed by a public authority. This is expected for an appliance reached by IP address.
Sign in with the user <KOMODO_ADMIN_USER> and the password from Step 5. The home view lists every resource Komodo knows about. On a new appliance it shows one server: this VM.
To use a real certificate instead, replace /etc/ssl/komodo/komodo.crt and /etc/ssl/komodo/komodo.key and reload nginx. Keep the private key 0600 root:root.
Check what the network can reach
Only two ports on this VM answer from off the machine: SSH and the encrypted Komodo front door. The database, the document engine and the agent are reachable from neither the network nor the containers Komodo deploys. List the listening ports:
sudo ss -Hltn | awk '{print $4}' | sort -uRun the bundled checker. It asserts that set of ports by equality, rather than by looking for a handful of unwanted ports:
sudo /usr/local/sbin/komodo-port-check.shThen confirm that no MongoDB component is present on the VM, in any of the four container images, or in the unit files that start them:
sudo /usr/local/sbin/komodo-no-sspl-assert.shConfirm that self sign-up is closed
By default, Komodo allows self registration, and lets the first visitor to an appliance with no administrator claim it. This image closes both. It also reports this to the browser, so no sign-up button is ever shown. Query the login options:
ADDR="$(sudo grep '^KOMODO_ADDRESS=' /root/komodo-credentials.txt | cut -d= -f2-)" curl -s --cacert /etc/ssl/komodo/komodo.crt --resolve "${ADDR}:443:127.0.0.1" \
-H 'Content-Type: application/json' \
-d '{"type":"GetLoginOptions","params":{}}' \
"https://${ADDR}/auth/login" echoIn the response, registration_disabled is true and every external login provider is false.
Your VM also re-checks this on every boot. If the administrator account is ever missing, it stops the front door rather than leaving an open sign-up on a machine that manages containers.
systemctl is-active komodo-postboot-verify.serviceKomodo limits sign-in attempts to 5 in any 15 second window. This is a Komodo feature, not a limitation of this image, and it applies to the checks that follow. If you run several checks back to back and one reports a refusal, wait twenty seconds and run it again.
Verify the whole security posture
Run the full verification with one command:
sudo /usr/local/sbin/komodo-verify.shOn the running appliance, it asserts that:
- the four images still match the content they were pinned to
- the off-VM listening set is exactly SSH and 443
- no MongoDB component is present
- the database and the agent publish no port
- self registration is closed
- Komodo Core is published only on the loopback interface
- the encrypted front door forwards the live-update websocket
- containers are denied the Azure instance metadata service
- the certificate names this VM rather than the machine the image was built on
- the administrator credential recorded on this VM opens it, while a wrong one is refused
It finishes by feeding each of its own offline checks a deliberately bad input and requiring each to fail on it, because a check that cannot fail proves nothing.
For the heavier version, run sudo /usr/local/sbin/komodo-selftest.sh --customer-vm --full. It also starts a deliberately insecure throwaway Komodo on its own temporary database, to prove that the sign-up check can detect an open sign-up. It takes a few minutes and removes everything it created.
Deploy your first container
In the web interface, choose Deployments, then New Deployment. Give the deployment a name, pick the server called Local (this VM), and set the image to alpine:3.22, which is already present. Then choose Deploy.
You can do the same from the command line. The image ships a check for it. The check signs in through the front door exactly as you did, creates a deployment and runs it. It reads the container's own output back out of Komodo, then removes both the deployment and the container:
sudo /usr/local/sbin/komodo-deploy-probe.shThe check reports the container's own output rather than a status code on purpose. A Komodo that created a deployment and silently ran nothing would return success for every call in that sequence.
Check what your deployed containers can reach
A container that Komodo deploys is code you chose to run. Ordinary networking works normally. The container can resolve names and reach the internet, so images pull and packages install:
sudo docker run --rm alpine:3.22 sh -c 'nslookup ghcr.io >/dev/null 2>&1 && echo "name resolution works" || echo "name resolution is broken"'A deployed container cannot reach the Azure instance metadata service, which is where a virtual machine's own cloud credentials are handed out. Without that boundary, being able to deploy a container here would quietly mean holding this subscription's identity. Verify the block:
sudo docker run --rm alpine:3.22 sh -c 'wget -q -T 5 -O /dev/null http://169.254.169.254/metadata/instance 2>/dev/null && echo "metadata reachable" || echo "metadata unreachable, as intended"'The rules are installed as a systemd unit and reapplied whenever Docker restarts. Check them:
sudo /usr/local/sbin/komodo-egress-filter.sh checkOnly containers are filtered. The VM itself keeps its own access to that service, which is how it learned its public address on first boot.
Know where your data lives, and back it up
Everything Komodo stores lives in two Docker volumes. That includes every resource you define, every user and every update record. List the volumes:
sudo docker volume ls --format '{{.Name}}'The compose files, repositories and build contexts that Komodo manages live on the VM at /etc/komodo:
ls /etc/komodoKomodo writes dated database backups into /etc/komodo/backups, which is mounted into Core. Back up that directory and the two volumes together, and you can rebuild this appliance elsewhere.
Your per-VM secrets live in /etc/komodo-secrets, mode 0700. The directory is deliberately mounted into no container. Check its permissions:
sudo stat -c '%a %U:%G %n' /etc/komodo-secretsRoutine administration
Change the administrator password in the web interface under Settings, or through the API with the UpdatePassword request. Do this before you connect Komodo to anything important, and keep self registration switched off.
To add a second person, sign in as the administrator, then create and enable the account under Settings. With self registration off, only someone who is already signed in can create accounts.
Security updates for Ubuntu, nginx and the container engine install themselves. Confirm that unattended upgrades are enabled:
systemctl is-enabled unattended-upgrades.serviceUpgrade
The four container images are pinned to exact content, so nothing changes underneath you. To move to a newer Komodo, edit the image reference in /etc/systemd/system/komodo-core.service and /etc/systemd/system/komodo-periphery.service. Then run sudo systemctl daemon-reload and restart the two units.
Take a backup first, and read the Komodo release notes, because the database schema can change between minor versions.
For a clean upgrade path with none of that work, deploy the next SecureAnyCloud image release and restore your backup into it.
Troubleshooting
The browser warns about the certificate. This is expected. The certificate was generated on your VM and is not signed by a public authority. If you put a host name in front of the appliance, replace the certificate as described in Step 6.
A sign-in is refused and you are sure the password is right. Komodo limits sign-in attempts to 5 in any 15 second window. Wait twenty seconds and try again.
The web interface loads but nothing updates. The live-update websocket is not getting through. Check that nothing between you and the VM strips the upgrade header, and confirm that the front door still forwards it:
grep -c 'proxy_set_header Upgrade' /etc/nginx/sites-available/komodoThe front door is not answering at all. If this VM's administrator credential ever stops working, the post-boot check stops nginx rather than leaving an unprotected Komodo running. Read the reason, then recover:
sudo journalctl -u komodo-postboot-verify.service -n 20 --no-pagerKomodo will not start after a reboot. Every unit waits for first boot to complete. Confirm that it did:
ls -l /var/lib/sac/data/komodo-firstboot.done /var/lib/sac/data/komodo.bootstrap-readyA deployment will not start. Read what the agent reported:
sudo journalctl -u komodo-periphery.service -n 30 --no-pagerSupport
SecureAnyCloud provides 24/7 support for this image. Support covers deployment, connecting repositories and registries, stack and deployment design, webhooks and alerting, backups, scaling to additional managed hosts, and upgrades. Contact sales@secureanycloud.com.
Deploy on Azure
Launch Komodo 2.3.3 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