Comprehensive Guide to Setting Up Your Multi-Database Docker-Compose Environment Link to heading

In this blog post, we will delve into setting up a comprehensive multi-database environment using Docker Compose. The setup will include Redis, SurrealDB, ClickHouse, ScyllaDB, Kafka, and Zookeeper. This guide aims to provide an in-depth understanding of each service, its configuration, and the role it plays within the Docker Compose setup.

Table of Contents Link to heading

  1. Introduction
  2. Prerequisites
  3. Overview of Services
  4. Docker-Compose Configuration
  5. Networks and Volumes
  6. Running the Setup
  7. Managing and Monitoring Services
  8. Connecting to Databases with JetBrains DataGrip
  9. Conclusion
  10. Helpful Links and Further Reading

Introduction Link to heading

Docker Compose is a powerful tool that simplifies the management of multi-container Docker applications. In this guide, we will set up a multi-database environment using a single docker-compose.yml file. This setup includes popular databases and tools such as Redis, SurrealDB, ClickHouse, ScyllaDB, Kafka, and Zookeeper. Each of these services plays a crucial role in modern data processing and storage solutions.

Prerequisites Link to heading

Docker Docker Compose

Before we begin, ensure you have the following installed on your system:

  1. Docker
  2. Docker Compose

You can verify your installations by running the following commands:

docker --version
docker-compose --version

Overview of Services Link to heading

Redis Link to heading

Redis

Redis is an in-memory data structure store used as a database, cache, and message broker. It is known for its speed and versatility, supporting various data structures such as strings, hashes, lists, sets, sorted sets, bitmaps, hyperloglogs, and geospatial indexes. In this setup, we use the Bitnami Redis image with authentication enabled.

The Bitnami Redis image is a trusted and well-maintained image that comes with additional security and operational enhancements. By using this image, we ensure that our Redis instance is secure, stable, and up-to-date with the latest Redis features and security patches.

Authentication is a crucial feature for Redis, especially when it is exposed to a network. Without authentication, anyone with access to the Redis port can execute commands and potentially manipulate data. In our configuration, we enable authentication by setting the REDIS_PASSWORD environment variable. This password is required to connect to the Redis server, adding a layer of security to prevent unauthorized access.

Redis is often used in scenarios requiring high-speed read and write operations, such as caching frequently accessed data, managing sessions in web applications, or implementing real-time analytics. Its in-memory nature allows for extremely fast data operations, making it an excellent choice for performance-critical applications.

In addition to its role as a database and cache, Redis also functions as a message broker. It supports publish/subscribe messaging, where messages published to a channel are delivered to all subscribers of that channel. This feature is commonly used for implementing real-time notifications, live streaming, and other applications requiring instant message distribution.

The Redis service in our Docker Compose setup includes persistent storage using Docker volumes. This ensures that data stored in Redis remains available even after container restarts. The volume is mounted at /db within the container, preserving data across container lifecycles.

Overall, Redis’s combination of speed, versatility, and ease of use makes it an indispensable component of modern application architectures. By incorporating Redis into our Docker Compose setup, we leverage its powerful capabilities to enhance the performance and reliability of our services.

SurrealDB Link to heading

SurrealDB

SurrealDB is a scalable, distributed, document-graph database. It combines the power of document and graph databases, providing a versatile data storage solution. This unique combination allows SurrealDB to handle a wide range of data models and query patterns, making it suitable for a variety of applications.

SurrealDB’s document capabilities enable it to store structured data in a flexible, schema-less format. This is particularly useful for applications that require the storage of complex, nested data structures without the rigid constraints of traditional relational databases. Documents in SurrealDB can be easily modified and extended, allowing for rapid development and iteration of data models.

On the other hand, SurrealDB’s graph capabilities allow it to represent and query complex relationships between entities. Graph databases excel at handling interconnected data, making them ideal for use cases such as social networks, recommendation engines, and fraud detection. By integrating graph features, SurrealDB enables developers to perform sophisticated queries on relationships, such as traversals and shortest path calculations, directly within the database.

In this setup, we use the latest SurrealDB image with Docker Compose, ensuring that our database instance is always up-to-date with the latest features and improvements. The configuration includes environment variables for specifying the host, port, user credentials, and other database settings, making it easy to manage and customize the database according to our needs.

One of the key advantages of SurrealDB is its scalability. It is designed to handle large volumes of data and high query throughput, making it suitable for applications with demanding performance requirements. SurrealDB achieves this by distributing data across multiple nodes and using advanced indexing techniques to optimize query performance.

Additionally, SurrealDB supports a wide range of query languages and APIs, making it accessible to developers with different preferences and expertise. Whether you prefer SQL, graph query languages, or custom APIs, SurrealDB provides the flexibility to work with your preferred tools and frameworks.

The SurrealDB service in our Docker Compose setup also includes persistent storage using Docker volumes. This ensures that data stored in SurrealDB is retained across container restarts, providing durability and reliability for our applications.

By leveraging the strengths of both document and graph databases, SurrealDB offers a powerful and versatile data storage solution that can adapt to a wide range of use cases. Integrating SurrealDB into our Docker Compose setup allows us to take advantage of its unique features and capabilities, enhancing the functionality and performance of our applications.

ClickHouse Link to heading

ClickHouse

ClickHouse is a fast open-source column-oriented database management system that allows generating analytical data reports in real-time. It is known for its high performance and efficiency, particularly in scenarios involving large-scale data analytics and reporting.

As a column-oriented database, ClickHouse stores data by columns rather than rows. This design significantly reduces the amount of data read from disk during query execution, especially for queries that access only a subset of columns. This leads to faster query performance and more efficient use of storage, making ClickHouse an excellent choice for OLAP ( Online Analytical Processing) workloads.

ClickHouse’s high performance is achieved through a combination of advanced data processing techniques, including vectorized query execution, data compression, and parallel processing. These techniques allow ClickHouse to handle billions of rows and produce results with minimal latency. This makes it ideal for applications that require real-time analytics, such as monitoring systems, business intelligence tools, and data warehousing solutions.

In our Docker Compose setup, we use the latest ClickHouse image, ensuring we benefit from the newest features and performance improvements. The configuration includes environment variables for the database host, user credentials, and other settings, allowing for easy customization and management. Ports 8123, 9000, and 9009 are exposed to facilitate various types of connections and interactions with the ClickHouse server.

ClickHouse also supports a rich set of SQL features, enabling complex queries, joins, aggregations, and window functions. Its SQL compatibility makes it accessible to developers and data analysts who are familiar with traditional relational databases, easing the transition to a column-oriented paradigm.

Another significant advantage of ClickHouse is its support for high availability and fault tolerance. It can be deployed in a distributed setup, replicating data across multiple nodes to ensure data durability and availability even in the case of hardware failures. This makes ClickHouse a robust solution for mission-critical applications.

In our Docker Compose setup, we ensure persistent storage for ClickHouse by using Docker volumes. This guarantees that our analytical data is preserved across container restarts, maintaining the integrity and continuity of our data analysis processes.

ClickHouse’s ability to handle large datasets with exceptional speed and efficiency makes it a valuable addition to our multi-database environment. By integrating ClickHouse, we gain the capability to perform real-time data analysis and reporting, enhancing our overall data processing capabilities and providing deeper insights into our data.

ScyllaDB Link to heading

ScyllaDB

ScyllaDB is a high-performance, low-latency NoSQL database compatible with Apache Cassandra. It is designed for large-scale data workloads, offering superior performance and scalability compared to traditional NoSQL databases.

One of the key features of ScyllaDB is its compatibility with Apache Cassandra. This means that applications built for Cassandra can easily migrate to or operate alongside ScyllaDB without significant changes. ScyllaDB uses the same CQL ( Cassandra Query Language) and supports the same data model and architecture, making the transition seamless.

ScyllaDB achieves its high performance through several innovative techniques. It is built using the Seastar framework, which allows for highly efficient, asynchronous programming. This enables ScyllaDB to fully utilize modern multi-core processors, providing low-latency access and high throughput. Additionally, ScyllaDB is designed to minimize disk I/O operations, further enhancing its speed and efficiency.

In this Docker Compose setup, we use the latest ScyllaDB image, ensuring that we benefit from the most recent updates and optimizations. The configuration includes environment variables for the database hosts, keyspace, user credentials, and other settings, allowing for easy customization and management. Ports 9042 and 9160 are exposed to facilitate various types of connections and interactions with the ScyllaDB server.

ScyllaDB’s architecture is optimized for scalability. It can handle petabytes of data and thousands of requests per second, making it suitable for applications with demanding performance requirements. Whether it’s real-time analytics, IoT data processing, or handling high-velocity transactions, ScyllaDB can manage these workloads with ease.

In our Docker Compose setup, we ensure persistent storage for ScyllaDB by using Docker volumes. This guarantees that our data is preserved across container restarts, maintaining the integrity and continuity of our data operations. The setup also includes a health check to ensure that ScyllaDB is running correctly and can be queried.

Additionally, ScyllaDB provides robust support for high availability and fault tolerance. It replicates data across multiple nodes, ensuring that data remains accessible even if some nodes fail. This makes ScyllaDB a reliable solution for mission-critical applications where uptime and data consistency are paramount.

The scylla-load-keyspace service in our Docker Compose setup is responsible for initializing the ScyllaDB keyspace. This service depends on ScyllaDB being healthy and uses initialization scripts to set up the necessary database schema and data. By automating this process, we ensure that ScyllaDB is ready for use as soon as the environment is up and running.

Integrating ScyllaDB into our multi-database environment provides us with a powerful NoSQL database that can handle large-scale data workloads with high performance and low latency. Its compatibility with Apache Cassandra, combined with its advanced architectural features, makes ScyllaDB an excellent choice for modern, data-intensive applications.

Zookeeper Link to heading

Zookeeper

Apache Zookeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. It is a critical component in many distributed systems, ensuring that various parts of a system can coordinate and work together efficiently.

Zookeeper is often used in conjunction with other distributed systems to manage configuration and state information. It provides a hierarchical namespace, similar to a file system, where data is stored in znodes (ZooKeeper nodes). These znodes can be used to store configuration settings, metadata, and other essential information required by distributed applications.

One of the key features of Zookeeper is its ability to provide distributed synchronization. This is crucial in distributed systems where multiple processes need to coordinate their actions. For example, Zookeeper can be used to implement distributed locks, leader election, and barriers, ensuring that processes do not interfere with each other and that tasks are executed in the correct order.

In this Docker Compose setup, we use the Wurstmeister Zookeeper image, which is well-suited for integration with Apache Kafka. The configuration includes environment variables to specify the client port and tick time, which are essential for Zookeeper’s operation. The client port (2181) is exposed to allow other services to connect to Zookeeper.

Zookeeper also plays a crucial role in managing group services. It can keep track of the members of a distributed system, monitor their health, and facilitate communication between them. This is particularly important in systems where components need to be aware of each other’s presence and state to function correctly.

In our multi-database environment, Zookeeper is primarily used by Kafka to manage brokers, topics, and partition assignments. Kafka relies on Zookeeper to maintain its distributed state and to coordinate actions such as leader election for partitions. Without Zookeeper, Kafka would not be able to function as a distributed, fault-tolerant system.

The Zookeeper service in our Docker Compose setup ensures that it is always available and ready to serve other components in the environment. The configuration ensures persistent storage using Docker volumes, guaranteeing that configuration and state information is retained across container restarts. This reliability is crucial for maintaining the integrity and stability of the distributed system.

By incorporating Zookeeper into our Docker Compose setup, we provide a robust and reliable foundation for managing distributed configurations, synchronization, and coordination. Zookeeper’s ability to centralize and manage essential information ensures that our distributed services can operate smoothly and efficiently, maintaining high levels of performance and availability.

Kafka Link to heading

Kafka

Apache Kafka is a distributed event streaming platform capable of handling trillions of events a day. It is used for building real-time data pipelines and streaming applications. Kafka’s robust architecture and high throughput make it an ideal choice for applications that require the processing and analysis of vast amounts of real-time data.

Kafka’s core architecture consists of producers, consumers, brokers, topics, and partitions. Producers are responsible for sending data to Kafka topics, which are categories or feeds to which records are sent. Consumers subscribe to topics to read and process the data. Brokers are the Kafka servers that store the data and serve the consumers and producers. Topics are further divided into partitions, which allow Kafka to scale horizontally and handle large volumes of data efficiently.

In this Docker Compose setup, we use the latest Kafka image from Wurstmeister, which is known for its ease of integration with Docker environments. The configuration includes environment variables for setting the broker ID, Zookeeper connection, advertised listeners, listeners, and offsets topic replication factor. These settings ensure that Kafka can communicate effectively with Zookeeper and other services, and that it can handle data replication for fault tolerance.

Kafka’s ability to handle trillions of events per day is achieved through its distributed nature. Data is distributed across multiple brokers, allowing for high throughput and scalability. This makes Kafka suitable for applications such as log aggregation, stream processing, event sourcing, and real-time analytics.

In our Docker Compose setup, Kafka is configured to work with Zookeeper, which manages its distributed state and helps with tasks such as leader election for partitions. The configuration exposes port 9092, allowing clients to connect and produce or consume data. The volume mapping to Docker’s host system ensures that Kafka’s data is persisted across container restarts, maintaining data integrity and availability.

Kafka supports a wide range of client libraries for different programming languages, making it accessible to developers with various expertise. Its stream processing capabilities, provided by Kafka Streams and the Kafka Connect API, allow for complex data transformations and integrations with other systems.

The Kafka service in our Docker Compose setup includes a dependency on Zookeeper to ensure that it starts only after Zookeeper is up and running. This dependency is crucial for maintaining the order of service startup and ensuring that Kafka can correctly register and manage its brokers and topics.

By integrating Kafka into our multi-database environment, we gain the ability to build real-time data pipelines and streaming applications that can process and analyze data as it arrives. Kafka’s robustness, scalability, and high performance make it a vital component for any system that requires real-time data processing and event streaming.

Zoonavigator Link to heading

Zoonavigator

Zoonavigator is a web-based UI for Apache Zookeeper, making it easy to manage and visualize your Zookeeper cluster.

Docker-Compose Configuration Link to heading

Below is the docker-compose.yml file used to set up the environment:

version: "3.9"

services:
  redis:
    container_name: redis
    image: bitnami/redis:latest
    ports:
      - "6379:6379"
    volumes:
      - redis:/db
    networks:
      - backend
    command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
    environment:
      REDIS_HOST: ${REDIS_HOST}
      REDIS_PORT_NUMBER: ${REDIS_PORT_NUMBER}
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      REDIS_DATABASE: ${REDIS_DATABASE}
      ALLOW_EMPTY_PASSWORD: ${REDIS_ALLOW_EMPTY_PASSWORD}
    env_file:
      - .env

  surreal-db:
    container_name: surreal_db
    image: surrealdb/surrealdb:latest
    volumes:
      - surreal:/db
    ports:
      - "5800:8000"
    networks:
      - backend
    deploy:
      restart_policy:
        condition: on-failure
    entrypoint:
      - /surreal
      - start
      - --user
      - $SURREALDB_USER
      - --pass
      - $SURREALDB_PASS
    environment:
      SURREALDB_HOST: ${SURREALDB_HOST}
      SURREALDB_PORT: ${SURREALDB_PORT}
      SURREALDB_USER: ${SURREALDB_USER}
      SURREALDB_PASS: ${SURREALDB_PASS}
      SURREALDB_DB: ${SURREALDB_DB}
      SURREALDB_LOG: ${SURREALDB_LOG}
    env_file:
      - .env

  clickhouse-server:
    container_name: clickhouse
    image: clickhouse/clickhouse-server:latest
    restart: always
    volumes:
      - clickhouse:/db
    ports:
      - "8123:8123"
      - "9000:9000"
      - "9009:9009"
    networks:
      - backend
    environment:
      CLICKHOUSE_HOST: ${CLICKHOUSE_HOST}
      CLICKHOUSE_DB: ${CLICKHOUSE_DB}
      CLICKHOUSE_USER: ${CLICKHOUSE_USERNAME}
      CLICKHOUSE_PASSWORD: ${CLICKHOUSE_PASSWORD}
      CLICKHOUSE_PORT: ${CLICKHOUSE_PORT}
      CLICKHOUSE_DEBUG: ${CLICKHOUSE_DEBUG}
    env_file:
      - .env

  scylla:
    container_name: scylla
    image: scylladb/scylla:latest
    restart: always
    ports:
      - "9042:9042"
      - "9160:9160"
    environment:
      SCYLLA_HOSTS: ${SCYLLA_HOSTS}
      SCYLLA_KEYSPACE: ${SCYLLA_KEYSPACE}
      SCYLLA_USERNAME: ${SCYLLA_USERNAME}
      SCYLLA_PASSWORD: ${SCYLLA_PASSWORD}
    volumes:
      - scylla:/db
    networks:
      - backend
    env_file:
      - .env
    healthcheck:
      test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e DESCRIBE KEYSPACES" ]
      interval: 15s
      timeout: 10s
      retries: 10

  scylla-load-keyspace:
    image: scylladb/scylla:latest
    depends_on:
      scylla:
        condition: service_healthy
    networks:
      - backend
    volumes:
      - ./scripts/scylla/init-scylla.cql:/init-scylla.cql
      - ./scripts/scylla/initdb.sh:/initdb.sh
    entrypoint: [ "bash", "/initdb.sh" ]

  zookeeper:
    container_name: zookeeper
    image: wurstmeister/zookeeper:3.4.6
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka:
    container_name: kafka
    image: wurstmeister/kafka:latest
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - zookeeper

  zoonavigator:
    container_name: zoonavigator
    image: elkozmon/zoonavigator:latest
    ports:
      - "8000:8000"
    environment:
      HTTP_PORT: 8000
      NODES: zookeeper:2181
    depends_on:
      - zookeeper
    networks:
      - backend

networks:
  zoonavigator:
  backend:
    driver: bridge

volumes:
  scylla:
  redis:
  clickhouse:
  surreal:
  db-data:

Networks and Volumes Link to heading

Networks Link to heading

In this setup, we define a single network called backend to ensure that all services can communicate with each other. We also define a zoonavigator network for the Zoonavigator service.

Volumes Link to heading

We define persistent storage volumes for each database service. These volumes ensure that data persists even if the containers are restarted or recreated. The volumes defined are:

  • scylla for ScyllaDB
  • redis for Redis
  • clickhouse for ClickHouse
  • surreal for SurrealDB
  • db-data for generic database data

Environment Variables Link to heading

The .env file should contain the environment variables needed by each service. Below is an example of what the .env file might look like:

# Redis
REDIS_HOST=redis
REDIS_PORT_NUMBER=6379
REDIS_PASSWORD=your_redis_password
REDIS_DATABASE=0
ALLOW_EMPTY_PASSWORD=no

# SurrealDB
SURREALDB_HOST=surreal-db
SURREALDB_PORT=8000
SURREALDB_USER=your_surrealdb_user
SURREALDB_PASS=your_surrealdb_password
SURREALDB_DB=your_surrealdb_database
SURREALDB_LOG=info

# ClickHouse
CLICKHOUSE_HOST=clickhouse
CLICKHOUSE_DB=your_clickhouse_db
CLICKHOUSE_USERNAME=your_clickhouse_user
CLICKHOUSE_PASSWORD=your_clickhouse_password
CLICKHOUSE_PORT=9000
CLICKHOUSE_DEBUG=1

# ScyllaDB
SCYLLA_HOSTS=scylla
SCYLLA_KEYSPACE=your_scylla_keyspace
SCYLLA_USERNAME=your_scylla_username
SCYLLA_PASSWORD=your_scylla_password

# Kafka
KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181

Ensure that the .env file is located in the same directory as your docker-compose.yml file.

Running the Setup Link to heading

With your docker-compose.yml file and .env file ready, you can now start your multi-database environment. Run the following command to start the services:

docker-compose up -d

This command will pull the necessary images, create the containers, and start the services in detached mode. You can check the status of the containers using:

docker-compose ps

To view the logs of a specific service, use:

docker-compose logs <service_name>

For example, to view the logs for the Redis service, run:

docker-compose logs redis

Managing and Monitoring Services Link to heading

Redis Link to heading

To interact with the Redis service, you can use the Redis CLI. Run the following command to start a Redis CLI session:

docker exec -it redis redis-cli -a your_redis_password

SurrealDB Link to heading

You can interact with SurrealDB through its REST API. Access it via the URL http://localhost:5800.

ClickHouse Link to heading

To interact with ClickHouse, you can use the ClickHouse client:

docker exec -it clickhouse clickhouse-client

ScyllaDB Link to heading

You can use cqlsh to interact with ScyllaDB:

docker exec -it scylla cqlsh

Kafka and Zookeeper Link to heading

Kafka depends on Zookeeper for managing the cluster. You can use the Kafka CLI tools to manage and monitor Kafka. For example, to list all topics:

docker exec -it kafka kafka-topics.sh --list --zookeeper zookeeper:2181

Zoonavigator Link to heading

Zoonavigator provides a web-based UI for Zookeeper. Access it via the URL http://localhost:8000.

Connecting to Databases with JetBrains DataGrip Link to heading

JetBrains

JetBrains DataGrip is a powerful database management tool that supports a wide range of databases. It provides an intuitive interface for connecting, querying, and managing your databases. In our setup, we can use DataGrip to connect to Redis, SurrealDB, ClickHouse, ScyllaDB, and Kafka, making it easier to interact with and manage our multi-database environment.

JetBrains DataGrip

Setting Up Connections Link to heading

  1. Redis:

    • Open DataGrip and navigate to the Database tool window.
    • Click on the + sign and select Data Source > Redis.
    • Enter the connection details:
      • Host: localhost
      • Port: 6379
      • Password: your_redis_password
    • Click Test Connection to ensure everything is set up correctly, then click OK.
  2. SurrealDB:

    • SurrealDB support in DataGrip may require using the HTTP API or a generic database connection configuration.
    • Select Data Source > HTTP.
    • Enter the base URL: http://localhost:5800.
    • Configure the HTTP headers for authentication if required.
  3. ClickHouse:

    • Click on the + sign and select Data Source > ClickHouse.
    • Enter the connection details:
      • Host: localhost
      • Port: 8123
      • Database: your_clickhouse_db
      • User: your_clickhouse_user
      • Password: your_clickhouse_password
    • Click Test Connection to ensure everything is set up correctly, then click OK.
  4. ScyllaDB:

    • Click on the + sign and select Data Source > Cassandra (as ScyllaDB is Cassandra-compatible).
    • Enter the connection details:
      • Host: localhost
      • Port: 9042
      • Keyspace: your_scylla_keyspace
      • User: your_scylla_username
      • Password: your_scylla_password
    • Click Test Connection to ensure everything is set up correctly, then click OK.
  5. Kafka:

    • DataGrip does not natively support Kafka, but you can use tools like Confluent’s Kafka client or other Kafka management tools to interact with Kafka brokers.
    • For basic monitoring and message production/consumption, use the Kafka CLI tools provided within the Kafka container.

Benefits of Using DataGrip Link to heading

By connecting to your databases through DataGrip, you can leverage its powerful features, such as:

  • Unified Interface: Manage all your databases from a single interface.
  • Intelligent Query Editor: Write and execute queries with syntax highlighting, code completion, and error detection.
  • Database Management: Perform tasks such as creating tables, managing indexes, and running maintenance scripts.
  • Data Visualization: Visualize your data with built-in charts and graphs to gain insights quickly.

Using DataGrip enhances productivity and provides a centralized platform for managing your diverse database ecosystem, ensuring you can efficiently handle your data operations across all services in your Docker Compose setup.

Conclusion Link to heading

Setting up a multi-database environment using Docker Compose is a powerful way to manage and scale your data infrastructure. By following this guide, you now have a robust setup that includes Redis, SurrealDB, ClickHouse, ScyllaDB, Kafka, and Zookeeper. This environment provides a versatile and scalable foundation for your data processing and storage needs.

Remember to monitor your services regularly, back up your data, and ensure that your environment variables are securely managed. Docker Compose simplifies the orchestration of multiple services, making it easier to maintain a complex infrastructure with minimal effort.

Feel free to customize this setup further to meet your specific requirements.

To help you further explore the services we’ve set up in this Docker Compose environment, here are some useful links to their official websites, Docker Hub images, and additional reading materials.

Official Websites Link to heading

Further Reading Link to heading

To deepen your understanding and get more hands-on with these technologies, here are some excellent blog posts and articles:

These resources should help you get the most out of your multi-database environment and give you a deeper understanding of each technology’s capabilities and best practices.