Apache Ignite is an open-source, distributed database and computing platform designed for high-performance, real-time data processing. It operates as an in-memory or hybrid storage system, delivering sub-millisecond data access and horizontal scalability across cluster nodes.
While commercial offerings like GridGain add enterprise capabilities on top of Ignite, Apache Ignite gives you full SQL capability, distributed consensus, and fault tolerance — completely free and open-source under the Apache 2.0 license.
In this guide, we will set up a local 3-node Apache Ignite 3 cluster using Docker Compose, walk through cluster initialization, execute SQL statements, and cover a full teardown.
1. Prepare the Cluster Configuration (docker-compose.yml)
Our cluster consists of three independent nodes (node1, node2, and node3) communicating on internal port 3344. Each node exposes two main endpoints to the host:
- HTTP REST API (
10300): Used for cluster administration, topology health, and management tasks. - JDBC Thin Client (
10800): Used for client SQL connections and transactional queries.
Create a file named docker-compose.yml in your working directory:
name: ignite3
x-ignite-def: &ignite-def
image: apacheignite/ignite:3.1.0
environment:
JVM_MAX_MEM: "4g"
JVM_MIN_MEM: "4g"
BOOTSTRAP_NODE_CONFIG: /opt/ignite/etc/ignite-config.conf
configs:
- source: node_config
target: /opt/ignite/etc/ignite-config.conf
mode: 0644
services:
node1:
<<: *ignite-def
command: --node-name node1
ports:
- "10300:10300"
- "10800:10800"
volumes:
- ./data/node1:/opt/ignite/work
node2:
<<: *ignite-def
command: --node-name node2
ports:
- "10301:10300"
- "10801:10800"
volumes:
- ./data/node2:/opt/ignite/work
node3:
<<: *ignite-def
command: --node-name node3
ports:
- "10302:10300"
- "10802:10800"
volumes:
- ./data/node3:/opt/ignite/work
configs:
node_config:
content: |
ignite {
network {
port: 3344
nodeFinder.netClusterNodes = ["node1:3344", "node2:3344", "node3:3344"]
}
"storage": {
"profiles": [
{
name: "rocksDbProfile"
engine: "rocksdb"
}
]
}
}The node_config configuration in the Docker Compose file:
- Adds a storage profile named
rocksDbProfilethat uses the RocksDB engine; - Sets the storage size to 64MB (67108864 bytes) by default;
- Stores persistent data in the
datadirectory where docker was run.
2. Launch the Cluster Containers
Bring up the container stack in detached mode:
docker-compose up -dExpected Output:
[+] Running 5/5
✔ Network ignite3_default Created 0.1s
✔ Config ignite3_node_config Created 0.0s
✔ Container ignite3-node1-1 Started 0.4s
✔ Container ignite3-node2-1 Started 0.4s
✔ Container ignite3-node3-1 Started 0.4sCheck the containers:
docker-compose psExpected Output:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
ignite3-node1-1 apacheignite/ignite:3.1.0 "docker-entrypoint.s…" node1 6 seconds ago Up 5 seconds 0.0.0.0:10300->10300/tcp, [::]:10300->10300/tcp, 0.0.0.0:10800->10800/tcp, [::]:10800->10800/tcp
ignite3-node2-1 apacheignite/ignite:3.1.0 "docker-entrypoint.s…" node2 6 seconds ago Up 5 seconds 0.0.0.0:10301->10300/tcp, [::]:10301->10300/tcp, 0.0.0.0:10801->10800/tcp, [::]:10801->10800/tcp
ignite3-node3-1 apacheignite/ignite:3.1.0 "docker-entrypoint.s…" node3 6 seconds ago Up 5 seconds 0.0.0.0:10302->10300/tcp, [::]:10302->10300/tcp, 0.0.0.0:10802->10800/tcp, [::]:10802->10800/tcp3. Configure the CLI Helper Function
Apache Ignite 3 uses the main container image to execute CLI commands. Java 11+ runtime reflection warnings can clutter command output. We can pass --add-opens flags via JAVA_TOOL_OPTIONS to keep our console output clean.
Run this shell function in your terminal (or append it to your ~/.bashrc / ~/.zshrc):
ignite-cli() {
docker run --rm -it --network=ignite3_default \
-e JAVA_TOOL_OPTIONS="--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED" \
apacheignite/ignite:3.1.0 cli "$@"
}4. Initialize and Verify the Cluster
Initialize the metastorage group across all three nodes using the REST endpoint on node1 (port 10300):
ignite-cli cluster init --url http://node1:10300 --name my-cluster \
--metastorage-group node1,node2,node3Expected Output:
Cluster was initialized successfullyCheck the health and operational status of your newly formed cluster:
ignite-cli cluster status --url http://node1:10300Expected Output:
[name: my-cluster, nodes: 3, status: active, cmgNodes: [node1, node2, node3], msNodes: [node1, node2, node3]]Inspecting Storage Configuration (Optional):
ignite-cli node config show --url http://node1:10300 \
--format JSON ignite.storageExpected Output:
{
"engines" : {
"aimem" : {
"pageSizeBytes" : 16384
},
"aipersist" : {
"checkpoint" : {
"checkpointDelayMillis" : 200,
"checkpointThreads" : 4,
"compactionThreads" : 4,
"intervalDeviationPercent" : 40,
"intervalMillis" : 180000,
"logReadLockThresholdTimeoutMillis" : 0,
"readLockTimeoutMillis" : 10000,
"useAsyncFileIoFactory" : true
},
"pageSizeBytes" : 16384
},
"rocksdb" : {
"flushDelayMillis" : 100
}
},
"profiles" : [ {
"engine" : "rocksdb",
"name" : "rocksDbProfile",
"sizeBytes" : -1,
"writeBufferSizeBytes" : 67108864
}, {
"engine" : "aipersist",
"name" : "default",
"replacementMode" : "CLOCK",
"sizeBytes" : -1
} ]
}5. Execute SQL Queries
SQL execution in Apache Ignite 3 runs over the JDBC thin client protocol (port 10800). Connect using --jdbc-url to create tables and manipulate data:
Create a Distributed Table
ignite-cli sql --jdbc-url jdbc:ignite:thin://node1:10800 \
"CREATE TABLE IF NOT EXISTS my_table (id INT PRIMARY KEY, val VARCHAR)"Expected Output:
Updated 0 rows.Insert Data
ignite-cli sql --jdbc-url jdbc:ignite:thin://node1:10800 \
"INSERT INTO my_table VALUES (1, 'Hello World')"Expected Output:
Updated 1 rows.Query Data
for node in node1 node2 node3; do
echo "=== Querying $node ==="
ignite-cli sql --jdbc-url "jdbc:ignite:thin://${node}:10800" "SELECT * FROM my_table"
doneExpected Output:
=== Querying node1 ===
╔════╤═════════════╗
║ ID │ VAL ║
╠════╪═════════════╣
║ 1 │ Hello World ║
╚════╧═════════════╝
=== Querying node2 ===
╔════╤═════════════╗
║ ID │ VAL ║
╠════╪═════════════╣
║ 1 │ Hello World ║
╚════╧═════════════╝
=== Querying node3 ===
╔════╤═════════════╗
║ ID │ VAL ║
╠════╪═════════════╣
║ 1 │ Hello World ║
╚════╧═════════════╝6. Connecting to a Node
Execute:
ignite-cliExpected Output:
Picked up JAVA_TOOL_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED
# ___ __
### / | ____ ____ _ _____ / /_ ___
# ##### / /| | / __ \ / __ `// ___// __ \ / _ \
### ###### / ___ | / /_/ // /_/ // /__ / / / // ___/
##### ####### /_/ |_|/ .___/ \__,_/ \___//_/ /_/ \___/
####### ###### /_/
######## #### ____ _ __ _____
# ######## ## / _/____ _ ____ (_)/ /_ ___ |__ /
#### ####### # / / / __ `// __ \ / // __// _ \ /_ <
##### ##### _/ / / /_/ // / / // // /_ / ___/ ___/ /
#### ## /___/ \__, //_/ /_//_/ \__/ \___/ /____/
## /____/
Apache Ignite CLI version 3.1.0
You appear to have not connected to any node yet. Do you want to connect to the default node http://localhost:10300? [Y/n]Type "Y" and ENTER.
Then paste the below and press ENTER:
connect http://node1:10300Expected Output:
Connected to http://node1:10300
[node1]>Let's see the nodes/partitions.
For this let's move to sql mode. Type sql and press ENTER.
Finally run:
SELECT * FROM SYSTEM.LOCAL_PARTITION_STATES;Expected Output:

7. Complete Clean Teardown
To stop the cluster, clean up Docker networks, and wipe host-mounted data directories for a fresh start:
# Stop containers and remove internal network/volumes
docker-compose down -v
# Clear host bind-mount data
rm -rf ./data 0.1sSummary
In this guide, we covered the full lifecycle of a multi-node local cluster:
- Configured & Started: Defined a 3-node topology using
docker-compose.ymland launched it in the background. - Configured CLI: Created an
ignite-clialias to silence JVM warnings and streamline command invocation. - Initialized & Verified: Bootstrapped the metastorage group across nodes via HTTP REST (
10300) and confirmed cluster health. - Executed SQL: Created tables and queried data over the thin client protocol (
10800). - Cleaned Up: Removed container resources and purged local data directories with
docker-compose down -vandrm -rf ./data.
By leveraging Apache Ignite 3 and Docker Compose, you can simulate a production-grade multi-node environment on your local machine with full SQL and REST API capabilities in just a few shell commands.
Further Readings
📣 Call to Action
If you are interested in following along with my journey, I invite you to dive into all the details provided below:
Thanks for reading
- 👏 Please clap for the story (50 claps) to help the article to be spread
- 🌐 Share the story on Social Media
- ➕More stories about Programming, Career, AI and more.
- 🔔 Follow me: Medium | LinkedIn | Twitter
- ✉️ Subscribe to the newsletter