{"id":28383026,"url":"https://github.com/opendronemap/clusterodm","last_synced_at":"2026-04-08T14:31:27.349Z","repository":{"id":35511831,"uuid":"158443119","full_name":"OpenDroneMap/ClusterODM","owner":"OpenDroneMap","description":"A NodeODM API compatible autoscalable load balancer and task tracker for easy horizontal scaling ♆","archived":false,"fork":false,"pushed_at":"2025-05-20T17:48:10.000Z","size":657,"stargazers_count":97,"open_issues_count":11,"forks_count":69,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-06-21T23:25:56.366Z","etag":null,"topics":["nodeodm","odm","proxy","webodm"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenDroneMap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-11-20T19:49:19.000Z","updated_at":"2025-06-20T15:24:27.000Z","dependencies_parsed_at":"2023-02-15T03:00:59.813Z","dependency_job_id":"5441a0f2-b2ee-494f-aed2-f4506f480df5","html_url":"https://github.com/OpenDroneMap/ClusterODM","commit_stats":{"total_commits":233,"total_committers":22,"mean_commits":"10.590909090909092","dds":0.2532188841201717,"last_synced_commit":"9c1b83f12d2209dfb4a12b91b3fd9ce4f3c2e9a2"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/OpenDroneMap/ClusterODM","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDroneMap%2FClusterODM","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDroneMap%2FClusterODM/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDroneMap%2FClusterODM/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDroneMap%2FClusterODM/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenDroneMap","download_url":"https://codeload.github.com/OpenDroneMap/ClusterODM/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDroneMap%2FClusterODM/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261826898,"owners_count":23215664,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nodeodm","odm","proxy","webodm"],"created_at":"2025-05-30T05:11:43.213Z","updated_at":"2026-04-08T14:31:27.340Z","avatar_url":"https://github.com/OpenDroneMap.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ClusterODM\n\nA reverse proxy, load balancer and task tracker with optional cloud autoscaling capabilities for NodeODM API compatible nodes. In a nutshell, it's a program to link together multiple [NodeODM](https://github.com/OpenDroneMap/NodeODM) API compatible nodes under a single network address. The program allows to distribute tasks across multiple nodes while taking in consideration factors such as maximum number of images, queue size and slots availability. It can also automatically spin up/down nodes based on demand using cloud computing providers (currently [DigitalOcean](https://m.do.co/c/2977a7634f44), [Hetzner](https://www.hetzner.com), [Scaleway](https://scaleway.com) or [Amazon Web Services](https://aws.amazon.com/)).\n\n![image](https://user-images.githubusercontent.com/1951843/57490594-b9828180-7287-11e9-9328-740cc0be8f7e.png)\n\nThe program has been battle tested on [WebODM Lightning](https://webodm.net) for quite some time and has proven reliable in processing hundreds of thousands of datasets. However, if you find bugs, please [report them](https://github.com/OpenDroneMap/ClusterODM/issues).\n\n## Installation\n\nThe only requirement is a working installation of [NodeJS](https://nodejs.org) 14 or earlier (ClusterODM has compatibility issues with NodeJS 16 and later).\n\n```bash\ngit clone https://github.com/OpenDroneMap/ClusterODM\ncd ClusterODM\nnpm install\n```\n\nThere's also a docker image available at `opendronemap/clusterodm` and a native [Windows bundle](#windows-bundle).\n\n## Usage\n\nFirst, start the program:\n\n```bash\nnode index.js [parameters]\n```\n\nOr with docker:\n\n```bash\ndocker run --rm -ti -p 3000:3000 -p 8080:8080 opendronemap/clusterodm [parameters]\n```\n\nOr with apptainer, after cd into ClusterODM directory:\n\n```bash\napptainer run docker://opendronemap/clusterodm [parameters]\n```\n\nThen connect to the CLI and connect new [NodeODM](https://github.com/OpenDroneMap/NodeODM) instances:\n\n```bash\ntelnet localhost 8080\n\u003e HELP\n\u003e NODE ADD nodeodm-host 3001\n\u003e NODE LIST\n```\n\nFinally, use a web browser to connect to `http://localhost:3000`. A normal [NodeODM](https://github.com/OpenDroneMap/NodeODM) UI should appear. This means the application is working, as web requests are being properly forwarded to nodes.\n\nYou can also check the status of nodes via a web interface available at `http://localhost:10000`.\n\nSee `node index.js --help` for all parameter options.\n\n## Autoscale Setup\n\nClusterODM can spin up/down nodes based on demand. This allows users to reduce costs associated with always-on instances as well as being able to scale processing based on demand.\n\nTo setup autoscaling you must:\n   * Make sure [docker-machine](https://gitlab.com/gitlab-org/ci-cd/docker-machine) is installed.\n   * Setup a S3-compatible bucket for storing results.\n   * Create a configuration file for [DigitalOcean](./docs/digitalocean.md), [Hetzner](./docs/hetzner.md), [Scaleway](./docs/scaleway.md), or [Amazon Web Services](./docs/aws.md) (click links to see examples)\n\nYou can then launch ClusterODM with:\n\n```bash\nnode index.js --asr configuration.json\n```\n\nYou should see the following messages in the console:\n\n```bash\ninfo: ASR: DigitalOceanAsrProvider\ninfo: Can write to S3\ninfo: Found docker-machine executable\n```\n\nYou should always have at least one static NodeODM node attached to ClusterODM, even if you plan to use the autoscaler for all processing. If you setup auto scaling, you can't have zero nodes and rely 100% on the autoscaler. You need to attach a NodeODM node to act as the \"reference node\" otherwise ClusterODM will not know how to handle certain requests (for the forwarding the UI, for validating options prior to spinning up an instance, etc.). For this purpose, you should add a \"dummy\" NodeODM node and lock it:\n\n```\ntelnet localhost 8080\n\u003e NODE ADD localhost 3001\n\u003e NODE LOCK 1\n\u003e NODE LIST\n1) localhost:3001 [online] [0/2] \u003cversion 1.5.1\u003e [L]\n```\n\nThis way all tasks will be automatically forwarded to the autoscaler.\n\nA docker-compose file is available to automatically setup both ClusterODM and NodeODM on the same machine by issuing:\n\n```\ndocker-compose up\n```\n\n## Windows Bundle\n\nClusterODM can run as a self-contained executable on Windows without the need for additional dependencies. You can download the latest `clusterodm-windows-x64.zip` bundle from the [releases](https://github.com/OpenDroneMap/ClusterODM/releases) page. Extract the contents in a folder and run:\n\n```bash\nclusterodm.exe\n```\n\n## HPC set up with SLURM\n\nYou can write a SLURM script to schedule and set up available nodes with NodeODM for the ClusterODM to be wired to if you are on the HPC. Using SLURM will decrease the amount of time and processes needed to set up nodes for ClusterODM each time. This provides an easier way for user to use ODM on the HPC.\n\nTo setup HPC with SLURM, you must make sure SLURM is installed.\n\nSLURM script will be different from cluster to cluster, depending on which nodes in the cluster that you have. However, the main idea is we want to run NodeODM on each node once, and by default, each NodeODM will be running on port 3000. Apptainer will be taking available ports starting from port 3000, so if your node's port 3000 is open, by default NodeODM will be run on that node. After that, we want to run ClusterODM on the head node and connect the running NodeODMs to the ClusterODM. With that, we will have a functional ClusterODM running on HPC.\n\nHere is an example of SLURM script assigning nodes 48, 50, 51 to run NodeODM. You can freely change and use it depending on your system:\n\n![image](https://user-images.githubusercontent.com/70782465/214411148-cdf43e44-9756-4115-9195-d1f36b3a31b9.png)\n\nYou can check for available nodes using sinfo:\n\n```\nsinfo\n```\n\nRun the following command to schedule using the SLURM script:\n\n```\nsbatch sample.slurm\n```\n\nYou can also check for currently running jobs using squeue:\n\n```\nsqueue -u $USER\n```\n\nUnfortunately, SLURM does not handle assigning jobs to the head node. Hence, if we want to run ClusterODM on the head node, we have to run it locally. After that, you can connect to the CLI and wire the NodeODMs to the ClusterODMs. Here is an example following the sample SLURM script:\n\n```\ntelnet localhost 8080\n\u003e NODE ADD node48 3000\n\u003e NODE ADD node50 3000\n\u003e NODE ADD node51 3000\n\u003e NODE LIST\n```\n\nYou should always check to make sure which ports are being used to run NodeODM if ClusterODM is not wired correctly.\n\nIt is also possible to pre-populate nodes using JSON. If starting ClusterODM from apptainer or docker, the relevant JSON is available at `docker/data/nodes.json`. Contents might look similar to the following:\n\n```javascript\n[\n        {\"hostname\":\"node48\",\"port\":\"3000\",\"token\":\"\"},\n        {\"hostname\":\"node50\",\"port\":\"3000\",\"token\":\"\"},\n        {\"hostname\":\"node51\",\"port\":\"3000\",\"token\":\"\"}\n]\n\n```\n\nAfter finish hosting ClusterODM on the head node and finish wiring it to the NodeODM, you can try tunneling to see if ClusterODM works as expected. Open another shell window in your local machine and tunnel them to the HPC using the following command:\n\n```\nssh -L localhost:10000:localhost:10000 user@hostname\n```\n\nReplace user and hostname with your appropriate username and the hpc address. Basically, this command will tunnel the port of the hpc to your local port. After this, open a browser in your local machine and connect to `http://localhost:10000`. Port 10000 is where ClusterODM's administrative web interface is hosted at. This is what it looks like:\n\n![image](https://user-images.githubusercontent.com/70782465/214938402-707bee90-ea17-4573-82f8-74096d9caf03.png)\n\nHere you can check the NodeODMs status and even add or delete working nodes.\n\nAfter that, do tunneling for port 3000 of the HPC to your local machine:\n\n```\nssh -L localhost:3000:localhost:3000 user@hostname\n```\n\nPort 3000 is ClusterODM's proxy. This is the place we assign tasks to ClusterODM. Once again, connect to `http://localhost:3000` with your browser after tunneling. Here, you can Assign Tasks and observe the tasks' processes.\n\n![image](https://user-images.githubusercontent.com/70782465/214938234-113f99dc-f69e-4e78-a782-deaf94e986b0.png)\n\nAfter adding images in this browser, you can press Start Task and see ClusterODM assigning tasks to the nodes you have wired to. Go for a walk and check the progress.\n\n\n## Roadmap\n\nWe have [plenty of goals](https://github.com/OpenDroneMap/ClusterODM/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement). If you want to help, or need help getting started contributing, get in touch on the [OpenDroneMap community forum](https://community.opendronemap.org).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendronemap%2Fclusterodm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopendronemap%2Fclusterodm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendronemap%2Fclusterodm/lists"}