This repository demonstrates how to set up and run multiple interconnected Fluree v3 servers that can communicate with each other across different business domains. This example showcases a distributed ledger architecture where different organizational functions (Sales, Manufacturing, Accounts) maintain their own data while being able to reference and query data from other domains.
The setup consists of three separate Fluree servers, each managing a specific business domain:
- Sales Server (port 8090) - Manages customer relationships, orders, and sales representatives
- Manufacturing Server (port 8091) - Handles product manufacturing, production batches, and suppliers
- Accounts Server (port 8092) - Manages customer billing, invoices, and payments
Each server operates independently but can communicate with the others through configured remote system connections, enabling cross-domain data relationships and queries.
The example uses a unified data model based on the ACME organization (http://acme.org/ namespace) with three interconnected domains:
Classes:
acme:Customer- Customer information with loyalty tiers and purchase historyacme:Order- Sales orders with status tracking and product relationshipsacme:SalesRepresentative- Sales team members with territory assignmentsacme:ProductReview- Customer product reviews and ratings
Key Properties:
- Cross-references to Manufacturing products via
acme:purchasedProducts - Customer loyalty tracking with
acme:loyaltyTierandacme:lastPurchaseDate - Territory-based sales management
Classes:
acme:Product- Product catalog with manufacturing details and costsacme:ProductionBatch- Production batches with quality control statusacme:Factory- Manufacturing facilities and their capabilitiesacme:Supplier- Material suppliers and their relationships to factories
Key Properties:
- Cross-references to Sales orders via
acme:productOrders - Production tracking with batch numbers and quality control
- Supply chain management with supplier relationships
Classes:
acme:Customer- Customer account and billing informationacme:Invoice- Customer invoices with payment trackingacme:Payment- Payment records with method and date trackingacme:AccountRepresentative- Account management staff assignments
Key Properties:
- Cross-references to Sales orders via
acme:invoiceOrders - Credit management with limits and account status
- Payment processing and accounts receivable tracking
The power of this architecture lies in the relationships between domains:
- Sales ↔ Manufacturing: Orders reference products across domains
- Sales ↔ Accounts: Customer data spans both domains with different focuses
- Manufacturing ↔ Accounts: Product costs inform pricing and billing
- Docker and Docker Compose
- Make (for using the provided utilities)
- curl and jq (optional, for manual API interaction)
- Fluree v3 server image (included in docker-compose.yml)
The easiest way to get started is using the provided Makefile:
-
Clone this repository:
git clone <repository-url> cd v3-remote-multi-server-example
-
Complete setup with one command:
make setup
This command will:
- Start all three Fluree servers
- Wait for them to initialize
- Create and seed all databases with sample data
- Display the server URLs
-
Try the example queries:
# Run all example queries make queries # Or run individual queries make query-sales make query-manufacturing make query-cross-domain
If you prefer to run commands manually:
# Start servers
docker-compose up -d
# Create and seed databases (after servers are running)
curl -X POST http://localhost:8090/fluree/create \
-H "Content-Type: application/json" \
-d @resources/seed_data/sales-db.jsonld
curl -X POST http://localhost:8091/fluree/create \
-H "Content-Type: application/json" \
-d @resources/seed_data/manufacturing-db.jsonld
curl -X POST http://localhost:8092/fluree/create \
-H "Content-Type: application/json" \
-d @resources/seed_data/accounts-db.jsonldEach server has its own configuration file in the resources/ directory:
sales-config.jsonld- Configures the Sales server with remote connections to Manufacturing and Accountsmanufacturing-config.jsonld- Configures the Manufacturing server with remote connection to Salesaccounts-config.jsonld- Configures the Accounts server with remote connection to Sales
The servers are configured to communicate using Docker's internal networking:
- Sales server is available at
http://host.docker.internal:8090 - Manufacturing server is available at
http://host.docker.internal:8091 - Accounts server is available at
http://host.docker.internal:8092
Each server maintains its own persistent data in the data/ directory:
data/sales/- Sales server datadata/manufacturing/- Manufacturing server datadata/accounts/- Accounts server data
Once the servers are running and seeded, you can perform cross-domain queries:
# Get all customers and their orders
curl -X POST http://localhost:8090/fluree/query \
-H "Content-Type: application/json" \
-d '{
"from": ["acme/sales"],
"@context": {
"acme": "http://acme.org/"
},
"where": {
"@id": "?s",
"@type": "acme:Order"
},
"select": { "?s": ["*"] },
"depth": 3
}'# Get all products with their production details
curl -X POST http://localhost:8091/fluree/query \
-H "Content-Type: application/json" \
-d '{
"from": ["acme/manufacturing"],
"@context": {
"acme": "http://acme.org/"
},
"where": {
"@id": "?s",
"@type": "acme:Factory"
},
"select": { "?s": ["*"] },
"depth": 1
}'# Query sales data that references manufacturing products and relies on traversing a graph virtualized across multiple servers
curl -X POST http://localhost:8090/fluree/query \
-H "Content-Type: application/json" \
-d '{
"from": ["acme/accounts", "acme/manufacturing", "acme/sales"],
"@context": {
"acme": "http://acme.org/",
"f": "https://ns.flur.ee/ledger#"
},
"where": {
"@id": "?s",
"@type": "acme:AccountRepresentative"
},
"select": { "?s": ["*"] },
"depth": 8
}'# Start only the sales server
docker-compose up
# Stop all servers
docker-compose downEach server exposes a full Fluree API on its respective port:
- Sales API: http://localhost:8090
- Manufacturing API: http://localhost:8091
- Accounts API: http://localhost:8092
This multi-server approach provides several advantages:
- Domain Separation: Each business unit manages its own data and access controls
- Scalability: Servers can be scaled independently based on domain-specific loads
- Security: Fine-grained access control per domain with optional closed mode
- Data Sovereignty: Each domain maintains control over its data while enabling collaboration
- Cross-Domain Queries: Unified queries across multiple business domains
This example is provided as-is for demonstration purposes of Fluree v3 remote multi-server capabilities.