mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-10-06 06:39:07 +00:00
Add Docker support and fix CLI bootstrap flag
- Add comprehensive Docker setup with docker-compose.yml and Dockerfile - Fix critical CLI bootstrap flag bug that prevented local development - Add Docker environment variable support for node configuration - Add Windows Docker setup documentation - Enable local 4-node network development environment Key changes: - cmd/cli/main.go: Fix bootstrap peer override in createClient() - cmd/node/main.go: Add Docker environment variable support - docker-compose.yml: Multi-container orchestration setup - WINDOWS_DOCKER_SETUP.md: Complete user guide
This commit is contained in:
parent
5d951daaf8
commit
a539b6ff2d
39
.dockerignore
Normal file
39
.dockerignore
Normal file
@ -0,0 +1,39 @@
|
||||
# Build artifacts
|
||||
bin/
|
||||
data/
|
||||
logs/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Docker
|
||||
Dockerfile*
|
||||
docker-compose*.yml
|
||||
.dockerignore
|
||||
|
||||
# Documentation
|
||||
*.md
|
||||
docs/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
*~
|
||||
|
||||
# Test files
|
||||
*_test.go
|
||||
e2e/
|
||||
|
||||
# Examples (optional - remove if you want to include them)
|
||||
examples/
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -73,3 +73,6 @@ data/bootstrap/rqlite/
|
||||
.env.*
|
||||
|
||||
configs/
|
||||
|
||||
# PR documentation (temporary files)
|
||||
PR_CHANGES.md
|
||||
|
67
Dockerfile
Normal file
67
Dockerfile
Normal file
@ -0,0 +1,67 @@
|
||||
# Multi-stage build for DeBros Network
|
||||
# Stage 1: Build stage
|
||||
FROM golang:1.23-alpine AS builder
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache git make gcc musl-dev wget tar
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Build RQLite from source for Alpine compatibility
|
||||
RUN RQLITE_VERSION="8.43.0" && \
|
||||
git clone --depth 1 --branch v${RQLITE_VERSION} https://github.com/rqlite/rqlite.git /tmp/rqlite && \
|
||||
cd /tmp/rqlite && \
|
||||
go build -o /usr/local/bin/rqlited ./cmd/rqlited && \
|
||||
go build -o /usr/local/bin/rqlite ./cmd/rqlite && \
|
||||
chmod +x /usr/local/bin/rqlited /usr/local/bin/rqlite && \
|
||||
rm -rf /tmp/rqlite
|
||||
|
||||
# Copy go mod files first for better caching
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build only node and gateway executables (CLI is built separately on host)
|
||||
RUN mkdir -p bin && \
|
||||
go build -ldflags "-X 'main.version=0.50.1-beta' -X 'main.commit=unknown' -X 'main.date=2025-09-23T15:40:00Z'" -o bin/node ./cmd/node && \
|
||||
go build -ldflags "-X 'main.version=0.50.1-beta' -X 'main.commit=unknown' -X 'main.date=2025-09-23T15:40:00Z' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildVersion=0.50.1-beta' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildCommit=unknown' -X 'github.com/DeBrosOfficial/network/pkg/gateway.BuildTime=2025-09-23T15:40:00Z'" -o bin/gateway ./cmd/gateway
|
||||
|
||||
# Stage 2: Runtime stage
|
||||
FROM alpine:latest
|
||||
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache ca-certificates tzdata wget
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S debros && \
|
||||
adduser -u 1001 -S debros -G debros
|
||||
|
||||
# Create necessary directories
|
||||
RUN mkdir -p /app/bin /app/data /app/configs /app/logs && \
|
||||
chown -R debros:debros /app
|
||||
|
||||
# Copy built executables from builder stage
|
||||
COPY --from=builder /app/bin/ /app/bin/
|
||||
|
||||
# Copy RQLite binaries from builder stage
|
||||
COPY --from=builder /usr/local/bin/rqlited /usr/local/bin/rqlited
|
||||
COPY --from=builder /usr/local/bin/rqlite /usr/local/bin/rqlite
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Switch to non-root user
|
||||
USER debros
|
||||
|
||||
# Expose ports
|
||||
# 4001: LibP2P P2P communication
|
||||
# 5001: RQLite HTTP API
|
||||
# 6001: Gateway HTTP/WebSocket
|
||||
# 7001: RQLite Raft consensus
|
||||
EXPOSE 4001 5001 6001 7001
|
||||
|
||||
# Default command (can be overridden in docker-compose)
|
||||
CMD ["./bin/node"]
|
250
WINDOWS_DOCKER_SETUP.md
Normal file
250
WINDOWS_DOCKER_SETUP.md
Normal file
@ -0,0 +1,250 @@
|
||||
# DeBros Network - Windows Docker Setup Guide
|
||||
|
||||
Simple step-by-step guide to run the DeBros Network locally on Windows using Docker.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
✅ **Docker Desktop for Windows** - Must be installed and running
|
||||
✅ **PowerShell** - Comes with Windows
|
||||
✅ **Git** - For cloning the repository
|
||||
|
||||
## Step 1: Clone and Build
|
||||
|
||||
```powershell
|
||||
# Clone the repository
|
||||
git clone https://github.com/DeBrosOfficial/network.git
|
||||
cd network
|
||||
|
||||
# Build the CLI for local testing
|
||||
go build -ldflags "-X 'main.version=0.50.1-beta'" -o bin/network-cli.exe cmd/cli/main.go
|
||||
```
|
||||
|
||||
## Step 2: Start the Docker Network
|
||||
|
||||
```powershell
|
||||
# Start all services (this will take 1-2 minutes)
|
||||
docker-compose up -d
|
||||
|
||||
# Check that all containers are running
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
**Expected output:** 4 containers running:
|
||||
- `debros-bootstrap` (Bootstrap Node)
|
||||
- `debros-node-2` (Node 2)
|
||||
- `debros-node-3` (Node 3)
|
||||
- `debros-gateway` (HTTP Gateway)
|
||||
|
||||
## Step 3: Wait for Network Initialization
|
||||
|
||||
```powershell
|
||||
# Wait for all services to start up
|
||||
Start-Sleep -Seconds 30
|
||||
|
||||
# Verify bootstrap node is running
|
||||
docker logs debros-bootstrap --tail 5
|
||||
```
|
||||
|
||||
**Look for:** `"current_peers": 2` (means node-2 and node-3 connected)
|
||||
|
||||
## Step 4: Setup CLI Environment
|
||||
|
||||
```powershell
|
||||
# Set these environment variables (required for every new terminal)
|
||||
$env:DEBROS_GATEWAY_URL="http://localhost:6001"
|
||||
$BOOTSTRAP_PEER="/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr"
|
||||
```
|
||||
|
||||
## Step 5: Test the Network
|
||||
|
||||
### Basic Health Check
|
||||
```powershell
|
||||
# Check if network is healthy
|
||||
.\bin\network-cli.exe health --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
**Expected:** `Status: 🟢 healthy`
|
||||
|
||||
### View Connected Peers
|
||||
```powershell
|
||||
# List connected peers
|
||||
.\bin\network-cli.exe peers --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
**Expected:** 2 peers (your CLI + bootstrap node) - **This is normal!**
|
||||
|
||||
### Test Messaging (Requires Authentication)
|
||||
```powershell
|
||||
# Send a message (first time will prompt for wallet authentication)
|
||||
.\bin\network-cli.exe pubsub publish test-topic "Hello DeBros Network!" --bootstrap $BOOTSTRAP_PEER
|
||||
|
||||
# Listen for messages (in another terminal)
|
||||
.\bin\network-cli.exe pubsub subscribe test-topic 10s --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
|
||||
### Test Database (Requires Authentication)
|
||||
```powershell
|
||||
# Query the database
|
||||
.\bin\network-cli.exe query "SELECT * FROM namespaces" --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
|
||||
## Network Architecture
|
||||
|
||||
Your local network consists of:
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Bootstrap │◄──►│ Node-2 │◄──►│ Node-3 │
|
||||
│ localhost:4001 │ │ localhost:4002 │ │ localhost:4003 │
|
||||
│ localhost:5001 │ │ localhost:5002 │ │ localhost:5003 │
|
||||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||||
▲
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ CLI Client │ │ Gateway │
|
||||
│ (Your Terminal) │ │ localhost:6001 │
|
||||
└─────────────────┘ └──────────────────┘
|
||||
```
|
||||
|
||||
**Ports Used:**
|
||||
- **4001-4003**: P2P communication between nodes
|
||||
- **5001-5003**: Database HTTP API
|
||||
- **6001**: Gateway HTTP API
|
||||
- **7001-7003**: Database internal communication
|
||||
|
||||
## Daily Usage Commands
|
||||
|
||||
### Start Your Development Session
|
||||
```powershell
|
||||
# Start the network
|
||||
docker-compose up -d
|
||||
|
||||
# Setup environment (run in every new terminal)
|
||||
$env:DEBROS_GATEWAY_URL="http://localhost:6001"
|
||||
$BOOTSTRAP_PEER="/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr"
|
||||
|
||||
# Quick health check
|
||||
.\bin\network-cli.exe health --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
|
||||
### Common CLI Commands
|
||||
```powershell
|
||||
# Network status
|
||||
.\bin\network-cli.exe status --bootstrap $BOOTSTRAP_PEER
|
||||
|
||||
# Send message
|
||||
.\bin\network-cli.exe pubsub publish my-topic "Hello Network!" --bootstrap $BOOTSTRAP_PEER
|
||||
|
||||
# Listen for messages
|
||||
.\bin\network-cli.exe pubsub subscribe my-topic 15s --bootstrap $BOOTSTRAP_PEER
|
||||
|
||||
# Database query
|
||||
.\bin\network-cli.exe query "SELECT datetime('now') as current_time" --bootstrap $BOOTSTRAP_PEER
|
||||
|
||||
# List all database tables
|
||||
.\bin\network-cli.exe query "SELECT name FROM sqlite_master WHERE type='table'" --bootstrap $BOOTSTRAP_PEER
|
||||
```
|
||||
|
||||
### End Your Development Session
|
||||
```powershell
|
||||
# Stop network (keeps all data)
|
||||
docker-compose stop
|
||||
|
||||
# OR stop and remove all data (clean slate)
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Container Status
|
||||
```powershell
|
||||
# View all containers
|
||||
docker-compose ps
|
||||
|
||||
# Check specific container logs
|
||||
docker logs debros-bootstrap --tail 20
|
||||
docker logs debros-gateway --tail 20
|
||||
docker logs debros-node-2 --tail 20
|
||||
```
|
||||
|
||||
### Common Issues and Solutions
|
||||
|
||||
**❌ "Connection refused" error**
|
||||
```powershell
|
||||
# Solution: Check containers are running and wait longer
|
||||
docker-compose ps
|
||||
Start-Sleep -Seconds 60
|
||||
```
|
||||
|
||||
**❌ "Authentication failed"**
|
||||
```powershell
|
||||
# Solution: Check gateway is running
|
||||
docker logs debros-gateway --tail 10
|
||||
```
|
||||
|
||||
**❌ Only seeing 2 peers instead of 4**
|
||||
```
|
||||
✅ This is NORMAL! The CLI only sees itself + bootstrap node.
|
||||
Node-2 and Node-3 are connected to bootstrap but not visible to CLI.
|
||||
Your network is working correctly!
|
||||
```
|
||||
|
||||
### Restart Services
|
||||
```powershell
|
||||
# Restart all services
|
||||
docker-compose restart
|
||||
|
||||
# Restart specific service
|
||||
docker-compose restart bootstrap-node
|
||||
|
||||
# Complete clean restart
|
||||
docker-compose down -v
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### View Real-time Logs
|
||||
```powershell
|
||||
# Follow logs for all services
|
||||
docker-compose logs -f
|
||||
|
||||
# Follow logs for specific service
|
||||
docker-compose logs -f bootstrap-node
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Authentication
|
||||
- First CLI command will prompt you to connect your wallet
|
||||
- You'll receive an API key for future commands
|
||||
- API key is stored locally and reused automatically
|
||||
|
||||
### Network Isolation
|
||||
- **Your Docker Network**: Completely isolated for development
|
||||
- **Production Network**: Live DeBros Network (separate)
|
||||
- **Default CLI**: Connects to production (without `--bootstrap` flag)
|
||||
- **CLI with `--bootstrap`**: Connects to your local Docker network
|
||||
|
||||
### Data Persistence
|
||||
- All data is stored in Docker volumes
|
||||
- Survives container restarts
|
||||
- Use `docker-compose down -v` to reset everything
|
||||
|
||||
## Quick Reference Card
|
||||
|
||||
```powershell
|
||||
# Essential daily commands
|
||||
docker-compose up -d # Start
|
||||
$env:DEBROS_GATEWAY_URL="http://localhost:6001" # Setup
|
||||
$BOOTSTRAP_PEER="/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr"
|
||||
.\bin\network-cli.exe health --bootstrap $BOOTSTRAP_PEER # Test
|
||||
docker-compose down # Stop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🎉 **Your local DeBros Network is ready for development and testing!**
|
||||
|
||||
The network is completely isolated from production and perfect for:
|
||||
- Testing new features
|
||||
- Learning the DeBros Network
|
||||
- Developing applications
|
||||
- Experimenting safely
|
@ -414,6 +414,11 @@ func handlePeerID() {
|
||||
func createClient() (client.NetworkClient, error) {
|
||||
config := client.DefaultClientConfig("network-cli")
|
||||
|
||||
// Override bootstrap peers if specified via flag
|
||||
if bootstrapPeer != "/ip4/127.0.0.1/tcp/4001" {
|
||||
config.BootstrapPeers = []string{bootstrapPeer}
|
||||
}
|
||||
|
||||
// Check for existing credentials using enhanced authentication
|
||||
creds, err := auth.GetValidEnhancedCredentials()
|
||||
if err != nil {
|
||||
|
@ -100,11 +100,15 @@ func parseGatewayConfig(logger *logging.ColoredLogger) *gateway.Config {
|
||||
}
|
||||
cfg.BootstrapPeers = bp
|
||||
}
|
||||
if v := strings.TrimSpace(os.Getenv("RQLITE_DSN")); v != "" {
|
||||
cfg.RQLiteDSN = v
|
||||
}
|
||||
|
||||
// 3) Flags (override env)
|
||||
addr := flag.String("addr", "", "HTTP listen address (e.g., :6001)")
|
||||
ns := flag.String("namespace", "", "Client namespace for scoping resources")
|
||||
peers := flag.String("bootstrap-peers", "", "Comma-separated bootstrap peers for network client")
|
||||
rqliteDSN := flag.String("rqlite-dsn", "", "RQLite database DSN (e.g., http://localhost:5001)")
|
||||
|
||||
// Do not call flag.Parse() elsewhere to avoid double-parsing
|
||||
flag.Parse()
|
||||
@ -126,6 +130,9 @@ func parseGatewayConfig(logger *logging.ColoredLogger) *gateway.Config {
|
||||
}
|
||||
cfg.BootstrapPeers = bp
|
||||
}
|
||||
if r := strings.TrimSpace(*rqliteDSN); r != "" {
|
||||
cfg.RQLiteDSN = r
|
||||
}
|
||||
|
||||
logger.ComponentInfo(logging.ComponentGeneral, "Loaded gateway configuration",
|
||||
zap.String("addr", cfg.ListenAddr),
|
||||
|
124
cmd/node/main.go
124
cmd/node/main.go
@ -31,7 +31,7 @@ func setup_logger(component logging.Component) (logger *logging.ColoredLogger) {
|
||||
}
|
||||
|
||||
// parse_and_return_network_flags it initializes all the network flags coming from the .yaml files
|
||||
func parse_and_return_network_flags() (configPath *string, dataDir, nodeID *string, p2pPort, rqlHTTP, rqlRaft *int, rqlJoinAddr *string, advAddr *string, help *bool) {
|
||||
func parse_and_return_network_flags() (configPath *string, dataDir, nodeID *string, p2pPort, rqlHTTP, rqlRaft *int, rqlJoinAddr *string, advAddr, httpAdvAddr, raftAdvAddr *string, help *bool) {
|
||||
logger := setup_logger(logging.ComponentNode)
|
||||
|
||||
configPath = flag.String("config", "", "Path to config YAML file (overrides defaults)")
|
||||
@ -42,45 +42,15 @@ func parse_and_return_network_flags() (configPath *string, dataDir, nodeID *stri
|
||||
rqlRaft = flag.Int("rqlite-raft-port", 7001, "RQLite Raft port")
|
||||
rqlJoinAddr = flag.String("rqlite-join-address", "", "RQLite address to join (e.g., /ip4/)")
|
||||
advAddr = flag.String("adv-addr", "127.0.0.1", "Default Advertise address for rqlite and rafts")
|
||||
httpAdvAddr = flag.String("http-adv-addr", "", "HTTP advertise address (overrides adv-addr for HTTP)")
|
||||
raftAdvAddr = flag.String("raft-adv-addr", "", "Raft advertise address (overrides adv-addr for Raft)")
|
||||
help = flag.Bool("help", false, "Show help")
|
||||
flag.Parse()
|
||||
|
||||
logger.Info("Successfully parsed all flags and arguments.")
|
||||
|
||||
if *configPath != "" {
|
||||
cfg, err := LoadConfigFromYAML(*configPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to load config from YAML", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.ComponentInfo(logging.ComponentNode, "Configuration loaded from YAML file", zap.String("path", *configPath))
|
||||
|
||||
// Instead of returning flag values, return config values
|
||||
// For ListenAddresses, extract port from multiaddr string if possible, else use default
|
||||
var p2pPortVal int
|
||||
if len(cfg.Node.ListenAddresses) > 0 {
|
||||
// Try to parse port from multiaddr string
|
||||
var port int
|
||||
_, err := fmt.Sscanf(cfg.Node.ListenAddresses[0], "/ip4/0.0.0.0/tcp/%d", &port)
|
||||
if err == nil {
|
||||
p2pPortVal = port
|
||||
} else {
|
||||
p2pPortVal = 4001
|
||||
}
|
||||
} else {
|
||||
p2pPortVal = 4001
|
||||
}
|
||||
return configPath,
|
||||
&cfg.Node.DataDir,
|
||||
&cfg.Node.ID,
|
||||
&p2pPortVal,
|
||||
&cfg.Database.RQLitePort,
|
||||
&cfg.Database.RQLiteRaftPort,
|
||||
&cfg.Database.RQLiteJoinAddress,
|
||||
&cfg.Discovery.HttpAdvAddress,
|
||||
help
|
||||
}
|
||||
|
||||
// Always return the parsed command line flags
|
||||
// Config file loading will be handled separately in main()
|
||||
return
|
||||
}
|
||||
|
||||
@ -180,9 +150,13 @@ func load_args_into_config(cfg *config.Config, p2pPort, rqlHTTP, rqlRaft *int, r
|
||||
logger.ComponentInfo(logging.ComponentNode, "Setting RQLite join address", zap.String("address", *rqlJoinAddr))
|
||||
}
|
||||
|
||||
if *advAddr != "" {
|
||||
// Only override advertise addresses if they're not already set in config and advAddr is not the default
|
||||
if *advAddr != "" && *advAddr != "127.0.0.1" {
|
||||
cfg.Discovery.HttpAdvAddress = fmt.Sprintf("%s:%d", *advAddr, *rqlHTTP)
|
||||
cfg.Discovery.RaftAdvAddress = fmt.Sprintf("%s:%d", *advAddr, *rqlRaft)
|
||||
logger.ComponentInfo(logging.ComponentNode, "Overriding advertise addresses",
|
||||
zap.String("http_adv_addr", cfg.Discovery.HttpAdvAddress),
|
||||
zap.String("raft_adv_addr", cfg.Discovery.RaftAdvAddress))
|
||||
}
|
||||
|
||||
if *dataDir != "" {
|
||||
@ -190,21 +164,89 @@ func load_args_into_config(cfg *config.Config, p2pPort, rqlHTTP, rqlRaft *int, r
|
||||
}
|
||||
}
|
||||
|
||||
// load_args_into_config_from_yaml applies only explicit command line overrides when loading from YAML
|
||||
func load_args_into_config_from_yaml(cfg *config.Config, p2pPort, rqlHTTP, rqlRaft *int, rqlJoinAddr, advAddr, httpAdvAddr, raftAdvAddr, dataDir *string) {
|
||||
logger := setup_logger(logging.ComponentNode)
|
||||
|
||||
// Only override if explicitly set via command line (check if flag was actually provided)
|
||||
if *dataDir != "" {
|
||||
cfg.Node.DataDir = *dataDir
|
||||
logger.ComponentInfo(logging.ComponentNode, "Overriding data directory from command line", zap.String("dataDir", *dataDir))
|
||||
}
|
||||
|
||||
// Check environment variable for RQLite join address (Docker-specific)
|
||||
if rqlJoinEnv := os.Getenv("RQLITE_JOIN_ADDRESS"); rqlJoinEnv != "" {
|
||||
cfg.Database.RQLiteJoinAddress = rqlJoinEnv
|
||||
logger.ComponentInfo(logging.ComponentNode, "Setting RQLite join address from environment", zap.String("address", rqlJoinEnv))
|
||||
}
|
||||
|
||||
// Handle RQLite join address override from command line (takes precedence over env var)
|
||||
if *rqlJoinAddr != "" {
|
||||
cfg.Database.RQLiteJoinAddress = *rqlJoinAddr
|
||||
logger.ComponentInfo(logging.ComponentNode, "Setting RQLite join address from command line", zap.String("address", *rqlJoinAddr))
|
||||
}
|
||||
|
||||
// Check environment variables for advertise addresses (Docker-specific)
|
||||
if httpAdvEnv := os.Getenv("HTTP_ADV_ADDRESS"); httpAdvEnv != "" {
|
||||
cfg.Discovery.HttpAdvAddress = httpAdvEnv
|
||||
logger.ComponentInfo(logging.ComponentNode, "Setting HTTP advertise address from environment", zap.String("http_adv_addr", httpAdvEnv))
|
||||
}
|
||||
if raftAdvEnv := os.Getenv("RAFT_ADV_ADDRESS"); raftAdvEnv != "" {
|
||||
cfg.Discovery.RaftAdvAddress = raftAdvEnv
|
||||
logger.ComponentInfo(logging.ComponentNode, "Setting Raft advertise address from environment", zap.String("raft_adv_addr", raftAdvEnv))
|
||||
}
|
||||
|
||||
// Handle specific advertise address overrides from command line (takes precedence over env vars)
|
||||
if *httpAdvAddr != "" {
|
||||
cfg.Discovery.HttpAdvAddress = *httpAdvAddr
|
||||
logger.ComponentInfo(logging.ComponentNode, "Overriding HTTP advertise address from command line", zap.String("http_adv_addr", *httpAdvAddr))
|
||||
}
|
||||
if *raftAdvAddr != "" {
|
||||
cfg.Discovery.RaftAdvAddress = *raftAdvAddr
|
||||
logger.ComponentInfo(logging.ComponentNode, "Overriding Raft advertise address from command line", zap.String("raft_adv_addr", *raftAdvAddr))
|
||||
}
|
||||
|
||||
// Handle general advertise address (only if specific ones weren't set)
|
||||
if *advAddr != "" && *advAddr != "127.0.0.1" && *httpAdvAddr == "" && *raftAdvAddr == "" && os.Getenv("HTTP_ADV_ADDRESS") == "" && os.Getenv("RAFT_ADV_ADDRESS") == "" {
|
||||
cfg.Discovery.HttpAdvAddress = fmt.Sprintf("%s:%d", *advAddr, *rqlHTTP)
|
||||
cfg.Discovery.RaftAdvAddress = fmt.Sprintf("%s:%d", *advAddr, *rqlRaft)
|
||||
logger.ComponentInfo(logging.ComponentNode, "Overriding advertise addresses from adv-addr flag",
|
||||
zap.String("http_adv_addr", cfg.Discovery.HttpAdvAddress),
|
||||
zap.String("raft_adv_addr", cfg.Discovery.RaftAdvAddress))
|
||||
}
|
||||
|
||||
logger.ComponentInfo(logging.ComponentNode, "YAML configuration loaded with overrides applied")
|
||||
}
|
||||
|
||||
func main() {
|
||||
logger := setup_logger(logging.ComponentNode)
|
||||
|
||||
_, dataDir, nodeID, p2pPort, rqlHTTP, rqlRaft, rqlJoinAddr, advAddr, help := parse_and_return_network_flags()
|
||||
configPath, dataDir, nodeID, p2pPort, rqlHTTP, rqlRaft, rqlJoinAddr, advAddr, httpAdvAddr, raftAdvAddr, help := parse_and_return_network_flags()
|
||||
|
||||
check_if_should_open_help(help)
|
||||
select_data_dir(dataDir, nodeID)
|
||||
|
||||
// Load Node Configuration
|
||||
var cfg *config.Config
|
||||
cfg = config.DefaultConfig()
|
||||
logger.ComponentInfo(logging.ComponentNode, "Default configuration loaded successfully")
|
||||
if *configPath != "" {
|
||||
// Load config from YAML file
|
||||
var err error
|
||||
cfg, err = LoadConfigFromYAML(*configPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to load config from YAML", zap.Error(err))
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.ComponentInfo(logging.ComponentNode, "Configuration loaded from YAML file", zap.String("path", *configPath))
|
||||
|
||||
// Apply command line argument overrides
|
||||
load_args_into_config(cfg, p2pPort, rqlHTTP, rqlRaft, rqlJoinAddr, advAddr, dataDir)
|
||||
// Only apply command line overrides if they were explicitly set (not defaults)
|
||||
load_args_into_config_from_yaml(cfg, p2pPort, rqlHTTP, rqlRaft, rqlJoinAddr, advAddr, httpAdvAddr, raftAdvAddr, dataDir)
|
||||
} else {
|
||||
cfg = config.DefaultConfig()
|
||||
logger.ComponentInfo(logging.ComponentNode, "Default configuration loaded successfully")
|
||||
|
||||
// Apply command line argument overrides
|
||||
load_args_into_config(cfg, p2pPort, rqlHTTP, rqlRaft, rqlJoinAddr, advAddr, dataDir)
|
||||
}
|
||||
logger.ComponentInfo(logging.ComponentNode, "Command line arguments applied to configuration")
|
||||
|
||||
// LibP2P uses configurable port (default 4001); RQLite uses 5001 (HTTP) and 7001 (Raft)
|
||||
|
165
docker-compose.yml
Normal file
165
docker-compose.yml
Normal file
@ -0,0 +1,165 @@
|
||||
# Docker Compose file for DeBros Network
|
||||
|
||||
services:
|
||||
# Bootstrap Node - First node in the network
|
||||
bootstrap-node:
|
||||
build: .
|
||||
container_name: debros-bootstrap
|
||||
hostname: bootstrap-node
|
||||
command: ["./bin/node", "--config", "/app/configs/bootstrap.docker.yaml"]
|
||||
ports:
|
||||
- "4001:4001" # LibP2P P2P
|
||||
- "5001:5001" # RQLite HTTP API
|
||||
- "7001:7001" # RQLite Raft
|
||||
volumes:
|
||||
- bootstrap_data:/app/data
|
||||
- ./configs:/app/configs:ro
|
||||
- bootstrap_logs:/app/logs
|
||||
environment:
|
||||
- NODE_ID=bootstrap
|
||||
- P2P_PORT=4001
|
||||
- RQLITE_PORT=5001
|
||||
- RQLITE_RAFT_PORT=7001
|
||||
- DATA_DIR=/app/data/bootstrap
|
||||
- LOG_LEVEL=info
|
||||
networks:
|
||||
- debros-network
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5001/status", "||", "exit", "1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 45s
|
||||
|
||||
# Second Node - Joins the bootstrap node
|
||||
node-2:
|
||||
build: .
|
||||
container_name: debros-node-2
|
||||
hostname: node-2
|
||||
command: ["./bin/node", "--config", "/app/configs/node.docker.yaml"]
|
||||
ports:
|
||||
- "4002:4001" # LibP2P P2P (mapped to different host port)
|
||||
- "5002:5001" # RQLite HTTP API
|
||||
- "7002:7001" # RQLite Raft
|
||||
volumes:
|
||||
- node2_data:/app/data
|
||||
- ./configs:/app/configs:ro
|
||||
- node2_logs:/app/logs
|
||||
environment:
|
||||
- NODE_ID=node-2
|
||||
- P2P_PORT=4001
|
||||
- RQLITE_PORT=5001
|
||||
- RQLITE_RAFT_PORT=7001
|
||||
- RQLITE_JOIN_ADDRESS=bootstrap-node:7001
|
||||
- BOOTSTRAP_PEERS=/ip4/172.20.0.2/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr
|
||||
- DATA_DIR=/app/data/node2
|
||||
- LOG_LEVEL=info
|
||||
- HTTP_ADV_ADDRESS=node-2:5001
|
||||
- RAFT_ADV_ADDRESS=node-2:7001
|
||||
networks:
|
||||
- debros-network
|
||||
depends_on:
|
||||
bootstrap-node:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5001/status", "||", "exit", "1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 45s
|
||||
|
||||
# Third Node - Additional network participant
|
||||
node-3:
|
||||
build: .
|
||||
container_name: debros-node-3
|
||||
hostname: node-3
|
||||
command: ["./bin/node", "--config", "/app/configs/node.docker.yaml"]
|
||||
ports:
|
||||
- "4003:4001" # LibP2P P2P
|
||||
- "5003:5001" # RQLite HTTP API
|
||||
- "7003:7001" # RQLite Raft
|
||||
volumes:
|
||||
- node3_data:/app/data
|
||||
- ./configs:/app/configs:ro
|
||||
- node3_logs:/app/logs
|
||||
environment:
|
||||
- NODE_ID=node-3
|
||||
- P2P_PORT=4001
|
||||
- RQLITE_PORT=5001
|
||||
- RQLITE_RAFT_PORT=7001
|
||||
- RQLITE_JOIN_ADDRESS=bootstrap-node:7001
|
||||
- BOOTSTRAP_PEERS=/ip4/172.20.0.2/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr
|
||||
- DATA_DIR=/app/data/node3
|
||||
- LOG_LEVEL=info
|
||||
- HTTP_ADV_ADDRESS=node-3:5001
|
||||
- RAFT_ADV_ADDRESS=node-3:7001
|
||||
networks:
|
||||
- debros-network
|
||||
depends_on:
|
||||
bootstrap-node:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5001/status", "||", "exit", "1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 45s
|
||||
|
||||
# HTTP Gateway - Provides REST API and WebSocket interface
|
||||
gateway:
|
||||
build: .
|
||||
container_name: debros-gateway
|
||||
hostname: gateway
|
||||
command: ["./bin/gateway", "--addr", ":6001", "--namespace", "default", "--bootstrap-peers", "/ip4/bootstrap-node/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr"]
|
||||
ports:
|
||||
- "6001:6001" # Gateway HTTP/WebSocket
|
||||
volumes:
|
||||
- ./configs:/app/configs:ro
|
||||
- gateway_logs:/app/logs
|
||||
environment:
|
||||
- GATEWAY_ADDR=:6001
|
||||
- GATEWAY_NAMESPACE=default
|
||||
- GATEWAY_BOOTSTRAP_PEERS=/ip4/bootstrap-node/tcp/4001/p2p/12D3KooWQX6jcPTVSsBuVuxdkbMbau3DAqZT4pc7UgGh2FvDxrKr
|
||||
- RQLITE_NODES=http://bootstrap-node:5001
|
||||
- RQLITE_DSN=http://bootstrap-node:5001
|
||||
- LOG_LEVEL=info
|
||||
networks:
|
||||
- debros-network
|
||||
depends_on:
|
||||
bootstrap-node:
|
||||
condition: service_healthy
|
||||
node-2:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:6001/health", "||", "exit", "1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
networks:
|
||||
debros-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
|
||||
volumes:
|
||||
bootstrap_data:
|
||||
driver: local
|
||||
bootstrap_logs:
|
||||
driver: local
|
||||
node2_data:
|
||||
driver: local
|
||||
node2_logs:
|
||||
driver: local
|
||||
node3_data:
|
||||
driver: local
|
||||
node3_logs:
|
||||
driver: local
|
||||
gateway_logs:
|
||||
driver: local
|
Loading…
x
Reference in New Issue
Block a user