OpenCTI Docker vs manual deployment

Docker Compose or swarm gets OpenCTI running fastest, while a manual install gives you control over every dependency. Filigran's production guidance favors containers, so the choice depends on your orchestration skills.

On this page

Should you deploy OpenCTI with Docker or install it manually?

For most teams, the answer is Docker: use the official Docker Compose file for a single node, or the Docker stack feature on Swarm when you need to scale out. Install manually from release packages only when your security or operations standards require you to control each host, each dependency and each patch cycle yourself. Filigran's production guidance recommends running every component in containers, including the dependencies, on cloud services or an orchestrator such as Kubernetes. The Kubernetes Helm charts and the Terraform scripts for AWS, Azure and GCP are community contributions, not official Filigran deployments, so treat them as starting points that your team must review and own.

The dependency list is the same on both routes, and it is where the effort sits. OpenCTI needs Elasticsearch 8.0 or later or OpenSearch 2.9 or later, Redis 7.1 or later, RabbitMQ 3.11 or later and S3-compatible storage. The installation docs name Silo, a community-maintained fork of MinIO, as an option and recommend a RabbitMQ max_message_size of 536870912. Docker hides much of this setup, but you still need to size each service, back up the search index and object store, and plan upgrades for every container image. A manual install requires Node.js 22 or later with corepack, Python for workers and connectors, and a Node.js memory limit that defaults to 8 GB. Confirm each of these versions against the current docs before you build an image or a host.

Choose Docker if your team runs containers already, wants a reproducible single-node or Swarm environment and accepts the upstream images and compose files as the baseline. Choose a manual install if you must build each host from an approved image, your policy prohibits container runtimes for this workload, or you need to apply OS-level hardening that the container route cannot meet. Before you decide, ask your platform team to confirm how it will handle image provenance, dependency patching and backup of Elasticsearch or OpenSearch, and check the OpenCTI installation guide for the current supported paths.

Which route fits which team

For a pilot or proof of concept, the default docker-compose.yml route is the shortest path. The OpenCTI installation docs list it for a single node or a Docker swarm, so the team brings up the platform and its dependencies from one file set and can test connectors and the STIX data model quickly. This route assumes working knowledge of Docker and Compose, and it suits a small group that wants to learn the product before committing to a design.

  • Skills assumed: Docker, Compose files, basic Linux administration and editing environment values.
  • Main trade-off: Convenience comes at the cost of production hardening. A pilot stack is not the layout Filigran recommends for production.
  • Resource planning: The sizing guidance calls for at least 2 cores and 8 GB RAM for the platform, and 2 cores, 8 GB RAM and 16 GB SSD for Elasticsearch or OpenSearch. Confirm these against your host before you start.
  • Memory defaults: The platform's Node.js memory limit defaults to 8 GB, so size the host with headroom for the search and queue services.
  • Exit path: Keep the compose files under version control so the pilot can be rebuilt as a production design without re-learning the stack.

Before you rely on a pilot, confirm the currently documented release and LTS line with the OpenCTI installation guide.

Docker Compose, swarm and manual install compared

This table compares the official Docker routes with a manual install from release packages on hosts you prepare. Read each row as a decision point: the entry point, what you operate yourself, how scaling and upgrades work, and where air-gapped or hardened hosts change the answer. Items marked as questions are not documented in the supplied sources and should be confirmed with Filigran before you commit.

FactorDocker Compose or swarmManual install from release packages
Packaging and entry pointDefault docker-compose.yml for a single node or Docker swarm, per the installation docsLaunches the platform and dependencies from GitHub release packages on hosts you prepare
Dependencies you runElasticsearch or OpenSearch, RabbitMQ, Redis and S3-compatible storage run as containers defined in the stackThe same four dependency types, installed and maintained by you on your own hosts
Production recommendationFiligran recommends containers for all components, with the Docker stack feature for easier swarm scalingFiligran's production guidance favors containerized components on cloud services or orchestrators such as Kubernetes
Scaling approachDocker stack feature on swarm; the docs recommend at least one platform node for every 3 workersYou lay out platform and worker processes across hosts yourself; confirm the supported layout with Filigran
Memory defaultsPlatform Node.js memory limit defaults to 8 GB; documented sizing starts at 2 cores and 8 GB RAM for the platformSame 8 GB Node.js default applies; you must size host memory for it and for Redis streams of up to 2 million entries (around 8 GB)
Upgrade pathMove to a newer image or stack definition; LTS builds require a specific license keyReplace release packages and dependency versions yourself; confirm rollback steps and dependency compatibility with Filigran
Air-gapped or hardened hostsRequires pulling images into a private registry; confirm the image list and offline procedure with FiligranFits hosts that cannot pull containers, but you own every package, patch and runtime (Node.js 22 or later, Python)
Community Kubernetes and TerraformHelm charts and Terraform scripts for AWS, Azure and GCP are community contributions, not official Filigran deploymentsNot applicable; confirm any official support position with Filigran before relying on community code

What each route makes your team run

Whichever route you choose, OpenCTI is a set of cooperating parts, not one process. The platform serves the UI and GraphQL API, workers and connectors do the asynchronous work, and four dependencies hold the data, queues and files. Docker hides some of this wiring, but the same components still need to be sized, patched and backed up.

The stateless platform

The platform serves the web application and the GraphQL API, and it is stateless, so state lives in the dependencies rather than on the platform node. The installation docs size it at 2 cores and at least 8 GB RAM. Check whether your Docker or manual route lets you set the Node.js memory limit, which defaults to 8 GB, and plan for more than one platform node if you expect heavy concurrent analyst use.

Python workers on RabbitMQ

Workers consume RabbitMQ messages and perform the asynchronous writes to the data store, so a queue backlog shows up as delayed ingestion rather than as an error in the UI. The docs recommend at least one platform node for every 3 workers. In a manual install you size and supervise worker processes yourself, while in Docker you scale worker containers, so ask who owns that scaling decision.

Connectors for import and enrichment

Connectors handle import, enrichment, file extraction, export and stream consumption, and each one calls an external source or service. MISP, MITRE and CVE connectors are common starting points. Each connector needs its own configuration, credentials and outbound network path, and in a Docker stack each one is another container to pin, monitor and upgrade. Inventory the connectors you need before choosing a route.

Search, cache and queue dependencies

OpenCTI needs Elasticsearch 8.0 or later, or OpenSearch 2.9 or later, plus Redis 7.1 or later and RabbitMQ 3.11 or later. The installation docs recommend setting RabbitMQ max_message_size to 536870912, which is easy to miss in a manual install. The search cluster is sized at 2 cores, 8 GB RAM and 16 GB SSD in the documented baseline, and Redis streams capped at 2 million entries can use around 8 GB.

S3-compatible file storage

Uploaded files and exports need S3-compatible object storage. The installation docs name Silo, a community-maintained fork of MinIO, as the option to use. Decide early whether object storage is self-run or provided by your cloud or data center, and confirm that your backup tooling captures the bucket as well as the search index, since restoring one without the other leaves files and records out of step.

Runtime and version alignment

A manual install needs Node.js 22 or later with corepack, plus Python for workers and connectors. Docker moves these into images, but you still must track which image tag each component runs. Keep the platform, workers and connectors on compatible releases, and confirm with Filigran which dependency versions each release supports before upgrading any single component.

What Filigran recommends for production

The OpenCTI installation documentation gives a clear production direction: deploy every component in containers, dependencies included, on cloud services or an orchestrator such as Kubernetes. For Docker swarm, the documentation recommends the Docker stack feature because it makes scaling easier. That means the platform, its Python workers and connectors, Elasticsearch or OpenSearch, RabbitMQ, Redis and S3-compatible storage would all run as managed container services rather than as packages you install by hand on prepared hosts. The official Docker Compose file is documented as a single-node or swarm starting point, so the production question is less about which file to run and more about where the containers will be scheduled, restarted, scaled and backed up.

If your team cannot run an orchestrator, the documented production path still points toward containers, but you will carry more of the operating model yourself. Confirm with Filigran which swarm and stack configuration they consider supported for your node count, how upgrades between docker-compose.yml revisions are expected to behave, and where the state for each dependency lives. Plan for the sizing in the deployment overview, which calls for at least one platform node for every 3 workers, and check that your swarm nodes can meet it before you commit to a topology.

The Terraform scripts for AWS, Azure and GCP and the Kubernetes Helm charts are community contributions, not official Filigran deployments. Filigran does not stand behind them in the way it stands behind the documented Docker path, so whoever adopts them owns their correctness, version compatibility, security hardening and upgrade testing. Before using either, ask Filigran what support covers, review the chart or module against the release you plan to run, and decide who on your team or your implementation partner will maintain it when OpenCTI releases change the dependency requirements. Treat that maintenance as a recurring cost in your plan, not a one-time setup task.

How a deployment moves from pilot to production

This sequence takes a team from a pilot on a single node to a production OpenCTI instance that it can restore, upgrade and operate. Each step ends with a check you can confirm before moving on.

  1. Confirm the release line before anything else

    Decide whether you will run a regular release, such as 7.261016.0, or an LTS line, such as 7.260309.0-lts.8. LTS builds require a specific LTS license key and, after a one-month stabilization, receive only critical bug and security fixes, so they suit teams that want fewer upgrades. Your security or platform lead owns this decision, and it is done when the version, license model and upgrade expectations are written into the project record. Confirm the key terms with Filigran before you commit.

  2. Prepare dependencies and storage

    Provision Elasticsearch 8.0 or later or OpenSearch 2.9 or later, Redis 7.1 or later, RabbitMQ 3.11 or later and S3-compatible storage. The installation docs name Silo, a community-maintained fork of MinIO, as an option and recommend a RabbitMQ max_message_size of 536870912. Size each component against the documented minimums, then record where each one runs. The step is complete when every service is reachable from the platform host and the RabbitMQ setting is applied and verified.

  3. Choose the Docker or manual route

    Use the default docker-compose.yml for a single node or Docker swarm, or install manually from GitHub release packages on hosts you prepare. Filigran recommends deploying all components in containers for production, including dependencies, and suggests the Docker stack feature on swarm for easier scaling. A manual install also needs Node.js 22 or later with corepack and Python for workers and connectors. The decision is done when your team has written down which route it chose and why.

  4. Configure authentication and access

    Set up how users sign in before you load data. Local accounts are the simplest path for a pilot, while SSO through OpenID, LDAP or SAML is an Enterprise Edition capability, so confirm that your license covers it before you plan around it. Map roles to your analysts and administrators and decide who can change platform settings. The step is complete when a test user from each group can log in and the denied actions are confirmed.

  5. Size workers and connectors for the expected load

    Start from the documented sizing: at least 2 cores and 8 GB RAM for the platform, 2 cores, 8 GB RAM and 16 GB SSD for Elasticsearch or OpenSearch, and at least one platform node for every 3 workers. Set the Node.js memory limit deliberately, because the default is 8 GB, and watch Redis stream growth, since streams capped at 2 million entries use around 8 GB. Enable only the connectors your feeds need, such as MISP, MITRE or CVE. The step is done when a sample import runs through the workers without queue backlog.

  6. Run a restore test

    Take a backup of the search index, object storage and configuration, then restore it to a separate environment. Compare entity counts, a sample of relationships and file attachments against the source. Ask your team to confirm the restore steps in writing, since the vendor documentation does not replace your own runbook. The step is complete when the restored instance matches the source for the checks you chose and the time the restore took is recorded.

  7. Rehearse an upgrade

    Apply the next planned release in the test environment, starting from a copy of production data. Review the release notes and the LTS lifecycle to understand what changes, then confirm that connectors, workers and dependencies still work after the update. For regular releases, the upgrade cadence will be frequent, so the rehearsal should be routine. The step is done when the upgrade completes, the smoke tests pass and a rollback path has been tried and documented.

  8. Approve the production cutover

    Move the tested configuration into production, with the restore and upgrade runbooks attached to the change record. Confirm that monitoring covers the platform, dependencies and queues, and that backups run on a schedule that you have tested. Sign-off from the platform owner and the security lead closes the step. If your team wants outside help with planning, hardening or ongoing upgrades, DeployOpen can scope that work in writing before any project starts.

Upgrades, backups, monitoring and skills for each route

This table compares what you operate after go-live under the Docker route and the manual route, from upgrades and backups to monitoring and staff skills. Read each row as a question to answer for your own team before you pick a route, since the operating work is where the two routes differ most.

Operating areaDocker Compose or stack filesManual install from release packages
Upgrade pathMove between published images and compose or stack file versions. Filigran's installation docs describe the Docker route as the default single-node or swarm option, so confirm the exact upgrade steps for your version in the docs.Replace release packages and re-run your own dependency and service steps on each host. Each upgrade touches Node.js, Python and the platform itself, so the change surface is larger.
Release cadence to plan forNon-LTS releases ship from daily to weekly, so plan a standing review cycle. LTS releases come every 6 months, each supported for 1 year, with a 6-month overlap. LTS builds need a specific LTS license key and receive only critical bug and security fixes after a one-month stabilization.Same release cadence and LTS rules apply, because the platform is the same. Your team carries the full install and test cycle for each package, so schedule time for it against that cadence.
Backup scopeBack up the Elasticsearch or OpenSearch indices, the S3-compatible object store, and the Redis and RabbitMQ state you decide to keep. Container volumes need a defined backup owner and a tested restore procedure.Same data stores, but the host filesystems, service configuration and OS-level snapshots are yours to define and test. Confirm which RabbitMQ and Redis state you must keep against what OpenCTI can rebuild.
Monitoring of queues and memoryWatch RabbitMQ queue depth, Redis stream length (the docs cite a 2 million entry cap that uses around 8 GB), and container memory against the platform's 8 GB Node.js default. Container runtime metrics are the first signals to wire up.Watch the same queues and memory, but on host-level process metrics for Node.js, Python workers and each dependency. Confirm the Node.js memory limit set in your service configuration matches your host sizing.
Platform sizing signalScale by adding service replicas as the docs suggest for one platform node per three workers, using the swarm or orchestrator scaling you configure. Confirm the replica model with the docs for your version.Scale by provisioning more hosts or processes yourself. The one-platform-node-per-three-workers guidance still applies, and each new host needs its own build of the runtime.
Skills your team needsDocker, Compose or swarm, plus Linux administration for hosts and storage. Kubernetes skills matter if you move to the containerized production pattern the docs recommend.Linux administration, Node.js and Python operations, and service management for every dependency, including Elasticsearch or OpenSearch, RabbitMQ, Redis and S3-compatible storage.
Community Kubernetes and TerraformCommunity Helm charts and Terraform scripts are not official Filigran deployments, so you own their upkeep and testing if you adopt them.Not applicable to this route. Your own configuration management replaces these community artifacts.
Who should own day-two workA platform or DevOps team comfortable with containers and an on-call rotation for dependencies.A systems team with strong Linux and runtime skills, and enough capacity to track each release by hand.

Questions buyers ask before choosing a route

How much more effort is a manual OpenCTI install than a Docker Compose deployment?

A Compose deployment packages the platform, workers, connectors and most dependencies into a predefined file, so the main work is configuring the environment, storage and secrets. A manual install means your team deploys Elasticsearch or OpenSearch, Redis, RabbitMQ and S3-compatible storage itself, then installs Node.js 22 or later with corepack and Python for workers and connectors. The gap is mostly in dependency setup, tuning and day-two maintenance, not in first launch. Ask the vendor or your own platform team to confirm which dependency versions your environment will run, since the documented minimums are Elasticsearch 8.0 or OpenSearch 2.9, Redis 7.1, and RabbitMQ 3.11.

Can we run OpenCTI in production without Kubernetes or another orchestrator?

Yes, but the documentation's production guidance points toward containers on cloud services or orchestrators such as Kubernetes, and toward Docker stack on swarm for easier scaling. A single-host Compose setup is suitable for evaluation and small deployments, while production teams usually need a plan for restarts, scaling workers, backups and patching. Confirm with your own platform team whether a single host meets your availability and recovery requirements before committing. Manual installs on prepared hosts are possible, but they put process supervision, dependency health and upgrades entirely on your staff.

What skills does our team need to run OpenCTI in-house?

You need people who can operate containers or Linux services, manage a search cluster, run a message broker and an in-memory store, and administer S3-compatible object storage. Someone also has to own Node.js and Python runtime versions for the platform, workers and connectors. Sizing matters: the documented baseline is 2 cores and at least 8 GB RAM for the platform, 2 cores, 8 GB RAM and 16 GB SSD for Elasticsearch or OpenSearch, and at least one platform node for every 3 workers. Memory defaults and Redis stream growth also need attention, because the Node.js memory limit defaults to 8 GB and Redis streams capped at 2 million entries use around 8 GB. Check these against your hardware before you size the hosts.

How long does an OpenCTI deployment take?

The duration depends on scope and environment: how many dependencies you host yourselves, whether you use managed cloud services, how many connectors you need, how strict your network and identity requirements are, and how much testing your change process requires. A Compose evaluation on one host is a different project from a multi-node production build with backups and monitoring. Ask for a written timeline that lists each deliverable, the environment assumptions behind it, and the acceptance tests. Treat any duration without those assumptions as a placeholder.

Does Filigran support the community Kubernetes Helm charts and Terraform scripts?

No. The installation documentation describes the Terraform scripts for AWS, Azure and GCP and the Kubernetes Helm charts as community contributions, not official Filigran deployments. That means no vendor support path for their defects, and you should review them against your own standards before use. If you choose them, budget for reviewing the chart and module code, pinning versions, and testing every upgrade. For the official installation guidance, start there and confirm the current position with Filigran in writing.

What does LTS licensing change about our upgrade plan?

LTS releases use a version format with an lts suffix, are supported for one year, and arrive about every six months, with a six-month overlap between consecutive LTS lines. They are distributed as container images, require a specific LTS license key, and after a one-month stabilization period receive only critical bug and security fixes. Non-LTS releases ship from daily to weekly and receive new features. For a self-hosted team, LTS means fewer, planned upgrades, but it also means you must track license entitlement and schedule a move to the next LTS line before support ends. Confirm your entitlement and renewal terms in writing before you pick a release line.

When should we bring in outside help for an OpenCTI deployment?

Bring in outside help when the internal team lacks experience with search clusters, brokers or object storage, when the production deadline is fixed, or when the platform must meet a compliance or hardening baseline that nobody internal has tested. DeployOpen plans, implements, integrates, hardens, backs up, upgrades and documents self-hosted platforms inside your own infrastructure, and most engagements are fixed-scope with agreed deliverables and timelines. Ongoing support and upgrades are available as retainers. Ask for a written scope that names the environment, the dependencies, the connectors, the handover documentation and the acceptance criteria. DeployOpen does not publish a price list, so a quote follows from that scope.

When an outside partner earns its place

An outside partner earns its place when the gap between the manual route and your team's skills is wider than the time you have to close it. The manual route asks you to deploy and tune OpenCTI's dependencies yourself: Elasticsearch 8.0 or later or OpenSearch 2.9 or later, Redis 7.1 or later, RabbitMQ 3.11 or later, S3-compatible storage, plus Node.js 22 or later with corepack and Python for the workers and connectors. If nobody on your team runs Node.js services or orchestrates stateful components with confidence, the platform will be harder to keep healthy than to install. Confirm this before you start, by listing who would own each component after go-live and whether that person has done it before.

Help also matters when the network is hardened or air-gapped. Pulling release packages, container images and connector dependencies from the internet may be blocked, so you need an internal mirror path, a tested offline bundle and a clear record of what was imported. The installation docs at OpenCTI installation describe the components, but your own change process decides how they reach the network. Assessments add a second demand: you need documented configuration, access controls and backup and restore evidence. DeployOpen plans, implements, hardens, backs up, upgrades and documents self-hosted platforms inside your own cloud accounts, data centers or air-gapped networks, and it prepares evidence for compliance assessments without issuing the audit report itself.

A planned move across LTS lines is the clearest case for outside help. LTS releases occur every 6 months and each is supported for 1 year, and LTS builds require a specific LTS license key. Upgrading means checking the dependency versions, the RabbitMQ message size setting and the connector versions against each target release. Ask any partner for a written scope that names the source and target versions, the rollback plan and the test evidence you will receive. Most DeployOpen engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts, so you can compare proposals on the same statement of work. Ask for the quote to break out installation, hardening, backup configuration, documentation and any ongoing support retainer separately.

How DeployOpen scopes, delivers and supports OpenCTI deployments

DeployOpen plans and implements self-hosted open-source platforms inside your own cloud accounts, data centers or air-gapped networks, so the Docker or manual route is chosen against your infrastructure rather than a default. Each engagement starts with a written scope that states which deployment route, dependencies and integrations are in and out.

How we scope

  • Confirm whether the target is a single node, Docker swarm, Kubernetes or a host-based install, and who owns each layer
  • Map OpenCTI dependencies (Elasticsearch or OpenSearch, Redis, RabbitMQ, S3-compatible storage) to your existing services or new hosts
  • Agree in writing on fixed-scope deliverables, timelines and which OpenCTI release line, including any LTS track, the deployment will use

How we build

  • Prepare hosts, container runtime or Node.js 22 and Python environments, then deploy dependencies with memory and storage sized to the documented minimums
  • Configure the RabbitMQ message size setting and worker-to-platform ratio, and test connector imports against a non-production dataset
  • Set up Enterprise Edition features such as SSO only where your agreed scope and license allow them, and test them before go-live

How we hand over

  • Document the chosen route, configuration files, network paths, secrets handling and the upgrade steps specific to your environment
  • Provide runbooks for backups of the database, search index and object storage, and a restore test result recorded in the handover pack
  • Walk your platform and security teams through operations, monitoring and the decisions behind the Docker or manual choice

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, scoped separately from the initial engagement
  • Plan upgrades across non-LTS releases and LTS branches, reviewing release notes and dependency version requirements before each change
  • Confirm with your team which support window, license key and patch cadence apply, since these depend on the release line you run

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.