Deployment guide

Self-Host Komodo on a VPS: Multi-Server Docker and GitOps

Deploy on a VPS Cloud →

Tutorial

Self-Host Komodo on a VPS: Multi-Server Docker and GitOps

Deployment9 min read13 steps

Managing Docker on one server is simple. On ten servers, it quickly becomes chaos: ten SSH sessions, ten compose files, no centralised history. Komodo (GPL-3.0, over 12,000 GitHub stars, v2.x) solves this with a Core/Periphery architecture: one dashboard to orchestrate all your servers, trigger deployments from Git and trace every action in an audit log. Written in Rust, the Core idles under 256 MB RAM — it runs comfortably on the smallest ServOrbit VPS.

Contents· Why Komodo instead of Portainer or Dockge?1/9
  1. 01Why Komodo instead of Portainer or Dockge?
  2. 02What Komodo adds beyond container management
  3. 03Core/Periphery architecture in practice
  4. 04Deploy Komodo on your ServOrbit VPS
  5. 05GitOps with webhooks: deploy on every push
  6. 06Creating a Komodo Procedure: pull, migrate, restart
  7. 07Komodo vs Portainer vs Dockge
  8. 08Troubleshooting: common errors and solutions
  9. 09Komodo + Dockge: the two complementary tools

Why Komodo instead of Portainer or Dockge?

Portainer and Dockge are single-server UIs: they read the local Docker socket and show you what is running on that machine. As soon as you have two or more servers, you need two tabs, you have to remember which service runs where, and replicate every change manually. Komodo breaks this ceiling with its Core/Periphery architecture: the Core is a central server that drives lightweight Periphery agents on each machine. You deploy, restart or update any stack from one interface, with a full history of who did what and when.

What Komodo adds beyond container management

  • Native GitOps — link a Git repository, define a Deploy Procedure, and trigger it automatically on every git push via HMAC webhook.
  • Reusable Procedures — chain image pull, database migration, stack restart and Slack notification into a single versionable workflow.
  • Docker Swarm — manage Swarm services, replicas and rolling updates from the same interface as your Compose stacks.
  • Native Slack/Discord alerts — configure alert channels for deployment failures, stopped containers and critical resources.
  • Multi-user RBAC — grant granular access by role (viewer, builder, deployer) without sharing the admin account.
  • Full REST API — automate deployments from your CI/CD pipeline (GitHub Actions, Woodpecker, Forgejo) without the web interface.

Core/Periphery architecture in practice

The Core is the brain: it stores configuration in FerretDB (a MongoDB-compatible layer), exposes the web UI on port 9120 and receives webhooks. Periphery agents are the arms: each one runs on a target server, proxies the machine's Docker socket to the Core over an encrypted channel and executes the commands the Core sends. The asymmetric keypair generated at init ensures that only your Core can command your agents — no extra secrets to manage. On a ServOrbit VPS, the local Periphery agent is deployed in the same Docker Compose stack as the Core, so the hosting server itself is managed from the first boot.

Deploy Komodo on your ServOrbit VPS

  1. Order the VPS

    A 1 vCPU / 1 GB RAM VPS on Ubuntu 24.04 LTS is sufficient for the Komodo control plane (Core + FerretDB). The Rust Core idles under 256 MB. If you plan to run other services on the same VPS, 2 GB RAM is recommended.

  2. Deploy from the ServOrbit marketplace

    In your ServOrbit client area, go to Marketplace → Application Deployment & DevOps → Komodo and click Deploy. Provide a domain name or subdomain — required for KOMODO_HOST. The playbook auto-generates JWT secrets, the Core/Periphery keypair and the admin password, then starts the services. The Komodo dashboard is available on port 9120 over HTTPS.

  3. Log in and verify the local agent

    Open https://your-domain.com:9120 and log in with admin and the password shown in your ServOrbit client area. In the Servers menu you should see a server named 'Local' already registered — this is the Periphery agent on the hosting VPS that auto-connected at startup. Change your password from the account settings during this first session.

  4. Connect a remote server via Periphery

    On each additional VPS to manage, install the Periphery agent: docker run -d --restart=unless-stopped --network host -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/moghtech/komodo-periphery:latest. Then in Komodo, go to Servers → Add Server, enter the agent IP and port 8120. The Core validates the connection using the Periphery public key generated at init. Your server fleet appears immediately in the dashboard.

  5. Create your first stack from the marketplace

    In Komodo, go to Stacks → New Stack. Choose the target server from the dropdown (Local or any added agent), paste your Docker Compose YAML or point to a Git repository path, and click Deploy. Komodo writes the file to the remote server, runs docker compose up -d and streams the logs in real time.

  6. Configure Slack or e-mail alerts

    In Komodo, go to Alerters → New Alerter. Choose the type (Slack, Discord, e-mail) and paste the webhook URL or destination address. Then associate the alerter with your resources (Stacks, Builds, Servers) via the Alerts section of each resource. You receive an immediate notification on deployment failure or stopped container.

  7. Set up a GitOps pipeline

    In your GitHub repository, add a webhook pointing to https://your-domain.com/api/webhook/komodo with the HMAC secret defined in Komodo. Create a Procedure named 'Deploy App': pull image, restart stack, notification. Link the webhook to the Procedure. Every git push now triggers the pipeline — the HMAC signature is verified by Komodo before execution.

  8. Integrate your CI/CD via the REST API

    Komodo exposes a full REST API at /api. From GitHub Actions, trigger a deployment with a POST /api/execute/procedure/<name> call and the API token of your service account. This integration lets you chain tests, image build and deployment in a single CI workflow without direct machine access.

GitOps with webhooks: deploy on every push

The Komodo GitOps cycle rests on three components: a Git repository, an HTTP webhook, and a Procedure. On the GitHub side, create a webhook in Settings → Webhooks, point it to https://your-domain.com/api/webhook/komodo, set the content type to application/json and define a secret. On the Komodo side, in the Webhooks section of a Stack or Procedure, paste that same secret — Komodo computes the HMAC SHA-256 of each incoming payload and rejects requests whose signature does not match.

A typical deployment Procedure chains three actions: PullImage (fetches the latest image from your registry), DeployStack (launches or recreates the containers), then SendAlert (notifies your Slack channel). If any step fails, Komodo stops the Procedure and sends the full error to your alerter — you never end up with a deployment silently half-applied.

One subtlety to know: Komodo validates the push branch against the branch configured in the Stack before triggering. A push to a feature branch will not trigger a production deployment, even if the webhook points to the same URL. Configure one Stack per environment (staging on dev, production on main) and you get a fully automated promotion pipeline.

Creating a Komodo Procedure: pull, migrate, restart

  1. Create the Procedure

    In Komodo, go to Procedures → New Procedure. Give it a name (deploy-app) and select the target server. A Procedure is an ordered list of steps — each step has a type (PullImage, DeployStack, RunCommand, SendAlert) and parameters.

  2. Add the PullImage step

    Click Add Step → PullImage. Enter the image name (e.g. ghcr.io/myorg/myapp:latest) and the server to pull it on. If your image is in a private registry, add the credentials in Settings → Registries before this step — Komodo injects them automatically during the pull.

  3. Add a migration command

    Click Add Step → RunCommand. In the Command field, enter the migration command to run in the container (e.g. docker exec app php artisan migrate --force). Enable the 'Stop on error' option: if the migration fails, the Procedure stops before restarting the service, preventing you from leaving an application with an inconsistent schema.

  4. Add the stack restart

    Click Add Step → DeployStack and select the target Stack. Komodo runs docker compose up -d --pull never (the image was already pulled in the previous step) and recreates modified containers. Environment variables defined in the Stack are passed automatically.

  5. Add a completion notification

    Click Add Step → SendAlert and select your Slack or Discord Alerter. You can include context variables in the message ({{ procedure.name }}, {{ server.name }}) to identify at a glance which Procedure on which server just ran.

Komodo vs Portainer vs Dockge

Scroll the table

FeatureKomodoPortainer CEDockge
Native multi-server✅ Multi-node Core/Periphery⚠️ Edge agents (paid)❌ Single host only
GitOps / webhooks✅ Native, HMAC validated❌ Not native❌ Not native
Procedures / automation✅ Built-in engine⚠️ Limited CE❌ No
REST API✅ Full✅ Full❌ No
Native alerts✅ Slack, Discord, e-mail⚠️ Partial CE❌ No
Audit log✅ All actions⚠️ Partial CE❌ No
Licence / priceGPL-3.0, freeZlib (CE free) / Business paidMIT, free

Troubleshooting: common errors and solutions

Periphery agent unreachable. The most common error when adding a new server. First check that the remote server's firewall allows incoming connections on port 8120 from your Core's IP. Then verify that the KOMODO_HOST variable of the Periphery agent matches the IP or domain the Core uses to reach it — a wrong value lets the agent start without error but makes it unreachable.

Failed to pull image. Komodo returns this error when the private registry is not accessible or credentials are missing. Add your credentials in Settings → Registries (Docker Hub, GHCR, private registry) before triggering a pull. If the image is public and the error persists, verify that the target server has internet access on port 443.

Webhook not triggered. Two main causes: the HMAC secret configured in Komodo does not match the one entered in GitHub, or your Core's URL is not accessible from GitHub's servers (behind a firewall or VPN). Check the 'Recent Deliveries' tab in GitHub to see the HTTP code returned — a 401 indicates an incorrect secret, a timeout indicates a network issue. Also verify that the push branch matches the branch configured in your Stack or Procedure.

Slow first start (FerretDB). FerretDB performs an internal database initialisation on first launch, which can take 30 to 60 seconds before the Komodo interface responds. If you see a connection error immediately after deployment, wait one minute and reload the page before diagnosing an installation problem.

Komodo + Dockge: the two complementary tools

Komodo and Dockge are not mutually exclusive. Dockge is great for interactive editing of Compose files on a single machine (YAML interface with syntax highlighting). Komodo handles multi-server coordination, Git deployments and workflows. Deploy Dockge via Komodo on your development machines, and use Komodo to orchestrate production deployments.

Your servers under GitOps control

Deploy Komodo on a ServOrbit VPS and manage your entire Docker fleet from a unified dashboard — GitOps, webhooks, audit log.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab