534 lines
24 KiB
Makefile
534 lines
24 KiB
Makefile
# ==============================================================================
|
|
# VEZA MONOREPO - ULTIMATE CONTROL PLANE
|
|
# ==============================================================================
|
|
# Stack: Docker + Incus (LXD) Support
|
|
# System: Linux / Bash
|
|
# ==============================================================================
|
|
|
|
# --- Auto-Configuration ---
|
|
-include .env
|
|
|
|
# Shell setup
|
|
SHELL := /bin/bash
|
|
.ONESHELL:
|
|
.DEFAULT_GOAL := help
|
|
|
|
# --- Variables ---
|
|
PROJECT_NAME := veza
|
|
COMPOSE_FILE := docker-compose.yml
|
|
COMPOSE_PROD := docker-compose.prod.yml
|
|
|
|
# Services
|
|
SERVICES := backend-api chat-server stream-server web haproxy
|
|
INFRA_SERVICES := postgres redis rabbitmq
|
|
|
|
# Ports
|
|
PORT_GO ?= 8080
|
|
PORT_CHAT ?= 3000
|
|
PORT_STREAM ?= 3001
|
|
PORT_WEB ?= 5173
|
|
PORT_HAPROXY ?= 80
|
|
|
|
# Database & Infra
|
|
DB_USER ?= veza
|
|
DB_PASS ?= password
|
|
DB_NAME ?= veza
|
|
DB_HOST ?= localhost
|
|
DB_PORT ?= 5432
|
|
|
|
# Connection Strings
|
|
DATABASE_URL = postgres://$(DB_USER):$(DB_PASS)@$(DB_HOST):$(DB_PORT)/$(DB_NAME)?sslmode=disable
|
|
REDIS_URL = redis://localhost:6379
|
|
AMQP_URL = amqp://$(DB_USER):$(DB_PASS)@localhost:5672
|
|
|
|
# Directories
|
|
DIR_GO := veza-backend-api
|
|
DIR_CHAT := veza-chat-server
|
|
DIR_STREAM := veza-stream-server
|
|
DIR_WEB := apps/web
|
|
|
|
# Deployment
|
|
DEPLOY_TARGET ?= docker
|
|
INCUS_PROFILE := veza-profile
|
|
INCUS_NETWORK := veza-network
|
|
|
|
# --- Aesthetics & UI ---
|
|
BOLD := \033[1m
|
|
RED := \033[0;31m
|
|
GREEN := \033[0;32m
|
|
YELLOW := \033[0;33m
|
|
BLUE := \033[0;34m
|
|
PURPLE := \033[0;35m
|
|
CYAN := \033[0;36m
|
|
NC := \033[0m
|
|
|
|
ECHO_CMD = echo -e
|
|
|
|
# ==============================================================================
|
|
# HELP & DASHBOARD
|
|
# ==============================================================================
|
|
.PHONY: help
|
|
help: ## Show this dashboard
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}${PURPLE}⚡ VEZA MONOREPO CLI ⚡${NC}"
|
|
@$(ECHO_CMD) "================================================================="
|
|
@$(ECHO_CMD) "${BOLD}INFRASTRUCTURE:${NC}"
|
|
@printf " ${CYAN}%-15s${NC} %s\n" "Postgres" "${DATABASE_URL}"
|
|
@printf " ${CYAN}%-15s${NC} %s\n" "Redis" "${REDIS_URL}"
|
|
@printf " ${CYAN}%-15s${NC} %s\n" "RabbitMQ" "UI: http://localhost:15672 (veza/password)"
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}${GREEN}HIGH LEVEL COMMANDS:${NC}"
|
|
@grep -E '^[a-zA-Z0-9_-]+:.*?## \[HIGH\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${YELLOW}%-25s${NC} %s\n", $$1, $$2}'
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}${BLUE}INTERMEDIATE COMMANDS:${NC}"
|
|
@grep -E '^[a-zA-Z0-9_-]+:.*?## \[MID\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${CYAN}%-25s${NC} %s\n", $$1, $$2}'
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}${PURPLE}LOW LEVEL / DEBUG:${NC}"
|
|
@grep -E '^[a-zA-Z0-9_-]+:.*?## \[LOW\] .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " ${PURPLE}%-25s${NC} %s\n", $$1, $$2}'
|
|
@$(ECHO_CMD) ""
|
|
|
|
# ==============================================================================
|
|
# HIGH LEVEL COMMANDS
|
|
# ==============================================================================
|
|
.PHONY: setup stop-all restart-all clean deploy-docker deploy-incus status-full
|
|
|
|
setup: check-tools install-tools install-deps ## [HIGH] Full project initialization
|
|
@$(ECHO_CMD) "${BOLD}${GREEN}✅ Setup Complete! Ready to rock with 'make dev'.${NC}"
|
|
|
|
stop-all: ## [HIGH] Stop all services (Docker + Local)
|
|
@$(ECHO_CMD) "${RED}🛑 Stopping all services...${NC}"
|
|
@docker compose -f $(COMPOSE_FILE) down 2>/dev/null || true
|
|
@docker compose -f $(COMPOSE_PROD) down 2>/dev/null || true
|
|
@$(MAKE) -s stop-local-services
|
|
@$(ECHO_CMD) "${GREEN}✅ All services stopped.${NC}"
|
|
|
|
restart-all: stop-all ## [HIGH] Restart all services
|
|
@$(ECHO_CMD) "${BLUE}🔄 Restarting all services...${NC}"
|
|
@$(MAKE) -s infra-up
|
|
@$(MAKE) -s dev
|
|
@$(ECHO_CMD) "${GREEN}✅ All services restarted.${NC}"
|
|
|
|
clean: ## [HIGH] Clean build artifacts and caches
|
|
@$(ECHO_CMD) "${YELLOW}🧹 Cleaning build artifacts...${NC}"
|
|
@rm -rf $(DIR_WEB)/node_modules/.cache
|
|
@rm -rf $(DIR_CHAT)/target/debug $(DIR_STREAM)/target/debug
|
|
@find . -type d -name "node_modules" -prune -o -type f -name "*.log" -delete
|
|
@$(ECHO_CMD) "${GREEN}✅ Clean complete.${NC}"
|
|
|
|
clean-deep: ## [HIGH] ⚠️ Nuclear Clean (Confirm required)
|
|
@read -p "${RED}Are you sure? This will delete ALL builds, volumes, and caches! [y/N]${NC} " ans && [ $${ans:-N} = y ]
|
|
@$(ECHO_CMD) "${RED}☢️ DESTROYING ARTIFACTS...${NC}"
|
|
@rm -rf $(DIR_WEB)/node_modules
|
|
@rm -rf $(DIR_CHAT)/target $(DIR_STREAM)/target
|
|
@docker compose -f $(COMPOSE_FILE) down -v 2>/dev/null || true
|
|
@docker compose -f $(COMPOSE_PROD) down -v 2>/dev/null || true
|
|
@$(ECHO_CMD) "${GREEN}System Cleaned.${NC}"
|
|
|
|
deploy-docker: build-all ## [HIGH] Deploy all services with Docker + HAProxy
|
|
@$(ECHO_CMD) "${BOLD}${BLUE}🐳 Deploying with Docker...${NC}"
|
|
@docker compose -f $(COMPOSE_PROD) up -d --build
|
|
@$(MAKE) -s wait-for-services
|
|
@$(ECHO_CMD) "${GREEN}✅ Deployment complete! Access via http://localhost:$(PORT_HAPROXY)${NC}"
|
|
|
|
deploy-incus: build-all-native ## [HIGH] Deploy all services with Incus containers (native, no Docker)
|
|
@$(ECHO_CMD) "${BOLD}${BLUE}📦 Deploying with Incus (native)...${NC}"
|
|
@$(MAKE) -s incus-setup-network
|
|
@$(MAKE) -s incus-deploy-infra
|
|
@$(MAKE) -s incus-deploy-all-native
|
|
@$(MAKE) -s incus-start-all
|
|
@$(ECHO_CMD) "${GREEN}✅ Incus deployment complete!${NC}"
|
|
@$(ECHO_CMD) "${BLUE}Access services at:${NC}"
|
|
@$(ECHO_CMD) " Backend API: http://10.10.10.2:8080"
|
|
@$(ECHO_CMD) " Chat Server: http://10.10.10.3:8081"
|
|
@$(ECHO_CMD) " Stream Server: http://10.10.10.4:3002"
|
|
@$(ECHO_CMD) " Web Frontend: http://10.10.10.5:80"
|
|
@$(ECHO_CMD) " HAProxy: http://10.10.10.6:80"
|
|
|
|
status-full: ## [HIGH] Show complete system status
|
|
@$(ECHO_CMD) "${BOLD}${CYAN}📊 SYSTEM STATUS${NC}"
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}Docker Containers:${NC}"
|
|
@docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAME|veza" || echo " No containers running"
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}Local Processes:${NC}"
|
|
@lsof -i :$(PORT_GO) -i :$(PORT_CHAT) -i :$(PORT_STREAM) -i :$(PORT_WEB) 2>/dev/null | grep LISTEN || echo " No local processes"
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}Incus Containers:${NC}"
|
|
@incus list veza- 2>/dev/null | grep -E "NAME|veza" || echo " No Incus containers"
|
|
@$(ECHO_CMD) ""
|
|
|
|
# ==============================================================================
|
|
# INTERMEDIATE COMMANDS
|
|
# ==============================================================================
|
|
.PHONY: start-service stop-service restart-service logs-service build-service
|
|
|
|
start-service: ## [MID] Start a specific service (usage: make start-service SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@$(ECHO_CMD) "${BLUE}🚀 Starting $(SERVICE)...${NC}"
|
|
@docker compose -f $(COMPOSE_PROD) up -d $(SERVICE) || \
|
|
$(MAKE) -s start-local-service SERVICE=$(SERVICE)
|
|
@$(ECHO_CMD) "${GREEN}✅ $(SERVICE) started.${NC}"
|
|
|
|
stop-service: ## [MID] Stop a specific service (usage: make stop-service SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@$(ECHO_CMD) "${YELLOW}🛑 Stopping $(SERVICE)...${NC}"
|
|
@docker compose -f $(COMPOSE_PROD) stop $(SERVICE) 2>/dev/null || \
|
|
$(MAKE) -s stop-local-service SERVICE=$(SERVICE)
|
|
@$(ECHO_CMD) "${GREEN}✅ $(SERVICE) stopped.${NC}"
|
|
|
|
restart-service: stop-service ## [MID] Restart a specific service (usage: make restart-service SERVICE=backend-api)
|
|
@$(ECHO_CMD) "${BLUE}🔄 Restarting $(SERVICE)...${NC}"
|
|
@$(MAKE) -s start-service SERVICE=$(SERVICE)
|
|
@$(ECHO_CMD) "${GREEN}✅ $(SERVICE) restarted.${NC}"
|
|
|
|
logs-service: ## [MID] Show logs for a service (usage: make logs-service SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@docker compose -f $(COMPOSE_PROD) logs -f $(SERVICE) || \
|
|
$(ECHO_CMD) "${YELLOW}Service not running in Docker, check local logs${NC}"
|
|
|
|
build-service: ## [MID] Build a specific service (usage: make build-service SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building $(SERVICE)...${NC}"
|
|
@$(MAKE) -s build-$(SERVICE)
|
|
@$(ECHO_CMD) "${GREEN}✅ $(SERVICE) built.${NC}"
|
|
|
|
build-all: ## [MID] Build all services (Docker images)
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building all services...${NC}"
|
|
@$(MAKE) -s build-backend-api
|
|
@$(MAKE) -s build-chat-server
|
|
@$(MAKE) -s build-stream-server
|
|
@$(MAKE) -s build-web
|
|
@$(ECHO_CMD) "${GREEN}✅ All services built.${NC}"
|
|
|
|
build-all-native: ## [MID] Build all services natively (for Incus)
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building all services natively...${NC}"
|
|
@$(PROJECT_ROOT)/config/incus/build-native.sh all
|
|
@$(ECHO_CMD) "${GREEN}✅ All services built natively.${NC}"
|
|
|
|
# ==============================================================================
|
|
# LOW LEVEL / DEBUG COMMANDS
|
|
# ==============================================================================
|
|
.PHONY: check-tools install-tools install-deps check-ports
|
|
|
|
check-tools: ## [LOW] Check required tools
|
|
@$(ECHO_CMD) "${BLUE}Checking core requirements...${NC}"
|
|
@for tool in docker go cargo npm; do \
|
|
command -v $$tool >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ $$tool is missing!${NC}"; exit 1; }; \
|
|
done
|
|
@$(ECHO_CMD) "${GREEN}✅ All tools present.${NC}"
|
|
|
|
check-tools-incus: ## [LOW] Check required tools for Incus deployment
|
|
@$(ECHO_CMD) "${BLUE}Checking Incus deployment requirements...${NC}"
|
|
@command -v incus >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ incus is missing! Install with: sudo snap install incus${NC}"; exit 1; }
|
|
@command -v go >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ go is missing!${NC}"; exit 1; }
|
|
@command -v cargo >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ cargo is missing!${NC}"; exit 1; }
|
|
@command -v npm >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ npm is missing!${NC}"; exit 1; }
|
|
@$(ECHO_CMD) "${GREEN}✅ All Incus tools present.${NC}"
|
|
|
|
install-tools: ## [LOW] Install Power User tools (Hot Reload, Linters)
|
|
@$(ECHO_CMD) "${BLUE}🛠️ Installing Dev Tools...${NC}"
|
|
@command -v air >/dev/null 2>&1 || go install github.com/air-verse/air@latest
|
|
@command -v cargo-watch >/dev/null 2>&1 || cargo install cargo-watch
|
|
@command -v sqlx >/dev/null 2>&1 || cargo install sqlx-cli --no-default-features --features native-tls,postgres
|
|
@$(ECHO_CMD) "${GREEN}✅ Tools installed.${NC}"
|
|
|
|
install-deps: ## [LOW] Install code dependencies
|
|
@$(ECHO_CMD) "${BLUE}📦 Installing dependencies...${NC}"
|
|
@$(ECHO_CMD) " -> [Go] Downloading modules..."
|
|
@(cd $(DIR_GO) && go mod download)
|
|
@$(ECHO_CMD) " -> [Rust Chat] Fetching crates..."
|
|
@(cd $(DIR_CHAT) && cargo fetch)
|
|
@$(ECHO_CMD) " -> [Rust Stream] Fetching crates..."
|
|
@(cd $(DIR_STREAM) && cargo fetch)
|
|
@$(ECHO_CMD) " -> [Web] Installing npm packages..."
|
|
@(cd $(DIR_WEB) && npm install --silent)
|
|
|
|
check-ports: ## [LOW] Check if ports are available
|
|
@$(ECHO_CMD) "${BLUE}🔍 Checking ports...${NC}"
|
|
@for port in $(PORT_GO) $(PORT_CHAT) $(PORT_STREAM) $(PORT_WEB); do \
|
|
if lsof -i :$$port -t >/dev/null 2>&1; then \
|
|
$(ECHO_CMD) "${YELLOW}⚠️ Port $$port is busy${NC}"; \
|
|
else \
|
|
$(ECHO_CMD) "${GREEN}✅ Port $$port is free${NC}"; \
|
|
fi; \
|
|
done
|
|
|
|
# ==============================================================================
|
|
# INFRASTRUCTURE
|
|
# ==============================================================================
|
|
.PHONY: infra-up infra-down wait-for-infra db-shell redis-shell db-migrate
|
|
|
|
infra-up: ## [MID] Start Docker Infra (with health checks)
|
|
@$(ECHO_CMD) "${BLUE}🐳 Starting Infrastructure...${NC}"
|
|
@docker compose -f $(COMPOSE_FILE) up -d
|
|
@$(MAKE) -s wait-for-infra
|
|
|
|
infra-down: ## [MID] Stop Docker Infra
|
|
@$(ECHO_CMD) "${BLUE}🛑 Stopping Infrastructure...${NC}"
|
|
@docker compose -f $(COMPOSE_FILE) down
|
|
|
|
wait-for-infra: ## [LOW] Wait for infrastructure to be ready
|
|
@printf "${BLUE}⏳ Waiting for services...${NC}"
|
|
@until docker compose -f $(COMPOSE_FILE) exec -T postgres pg_isready -U $(DB_USER) > /dev/null 2>&1; do printf "."; sleep 1; done
|
|
@until docker compose -f $(COMPOSE_FILE) exec -T redis redis-cli ping > /dev/null 2>&1; do printf "."; sleep 1; done
|
|
@$(ECHO_CMD) " ${GREEN}OK${NC}"
|
|
|
|
wait-for-services: ## [LOW] Wait for all application services
|
|
@printf "${BLUE}⏳ Waiting for services...${NC}"
|
|
@for service in backend-api chat-server stream-server web; do \
|
|
until docker compose -f $(COMPOSE_PROD) exec -T $$service echo "ready" > /dev/null 2>&1; do \
|
|
printf "."; sleep 1; \
|
|
done; \
|
|
done
|
|
@$(ECHO_CMD) " ${GREEN}OK${NC}"
|
|
|
|
db-shell: ## [MID] Connect to Postgres shell
|
|
@docker compose -f $(COMPOSE_FILE) exec postgres psql -U $(DB_USER) -d $(DB_NAME)
|
|
|
|
redis-shell: ## [MID] Connect to Redis shell
|
|
@docker compose -f $(COMPOSE_FILE) exec redis redis-cli
|
|
|
|
db-migrate: infra-up ## [MID] Run all database migrations
|
|
@$(ECHO_CMD) "${BLUE}🔄 Running Migrations...${NC}"
|
|
@$(ECHO_CMD) " -> [Go] Migrating..."
|
|
@(cd $(DIR_GO) && go run cmd/migrate_tool/main.go up || $(ECHO_CMD) "${YELLOW}Warning: Go migration failed${NC}")
|
|
@$(ECHO_CMD) " -> [Chat] Migrating..."
|
|
@(cd $(DIR_CHAT) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Chat migration failed${NC}")
|
|
@$(ECHO_CMD) " -> [Stream] Migrating..."
|
|
@(cd $(DIR_STREAM) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Stream migration failed${NC}")
|
|
@$(ECHO_CMD) "${GREEN}✅ Migrations done.${NC}"
|
|
|
|
# ==============================================================================
|
|
# DEVELOPMENT
|
|
# ==============================================================================
|
|
.PHONY: dev dev-backend stop-local-services start-local-service stop-local-service
|
|
|
|
dev: check-ports infra-up ## [HIGH] Start Everything (Detects Hot Reload tools)
|
|
@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING HYBRID DEV ENVIRONMENT${NC}"
|
|
@$(ECHO_CMD) " Go: http://localhost:${PORT_GO}"
|
|
@$(ECHO_CMD) " Chat: http://localhost:${PORT_CHAT}"
|
|
@$(ECHO_CMD) " Web: http://localhost:${PORT_WEB}"
|
|
@$(ECHO_CMD) "${YELLOW}Hit Ctrl+C to stop all.${NC}"
|
|
@(trap 'kill 0' SIGINT; \
|
|
if command -v air >/dev/null; then \
|
|
$(ECHO_CMD) "${GREEN}[Go] Hot Reload Active (Air)${NC}" && cd $(DIR_GO) && air & \
|
|
else \
|
|
$(ECHO_CMD) "${YELLOW}[Go] Standard Run${NC}" && cd $(DIR_GO) && go run cmd/modern-server/main.go & \
|
|
fi; \
|
|
if command -v cargo-watch >/dev/null; then \
|
|
$(ECHO_CMD) "${GREEN}[Chat] Hot Reload Active${NC}" && cd $(DIR_CHAT) && cargo watch -x run -q & \
|
|
$(ECHO_CMD) "${GREEN}[Stream] Hot Reload Active${NC}" && cd $(DIR_STREAM) && cargo watch -x run -q & \
|
|
else \
|
|
$(ECHO_CMD) "${YELLOW}[Chat] Standard Run${NC}" && cd $(DIR_CHAT) && cargo run -q & \
|
|
$(ECHO_CMD) "${YELLOW}[Stream] Standard Run${NC}" && cd $(DIR_STREAM) && cargo run -q & \
|
|
fi; \
|
|
$(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}" && cd $(DIR_WEB) && npm run dev & \
|
|
wait)
|
|
|
|
dev-backend: check-ports infra-up ## [MID] Start Backends Only (Hot Reload supported)
|
|
@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING BACKEND ONLY${NC}"
|
|
@(trap 'kill 0' SIGINT; \
|
|
if command -v air >/dev/null; then cd $(DIR_GO) && air & else cd $(DIR_GO) && go run cmd/modern-server/main.go & fi; \
|
|
if command -v cargo-watch >/dev/null; then cd $(DIR_CHAT) && cargo watch -x run -q & else cd $(DIR_CHAT) && cargo run -q & fi; \
|
|
if command -v cargo-watch >/dev/null; then cd $(DIR_STREAM) && cargo watch -x run -q & else cd $(DIR_STREAM) && cargo run -q & fi; \
|
|
wait)
|
|
|
|
stop-local-services: ## [LOW] Stop all local processes
|
|
@pkill -f "air\|cargo watch\|npm run dev\|go run.*modern-server" 2>/dev/null || true
|
|
|
|
start-local-service: ## [LOW] Start a service locally
|
|
@case "$(SERVICE)" in \
|
|
backend-api) \
|
|
if command -v air >/dev/null; then cd $(DIR_GO) && air & else cd $(DIR_GO) && go run cmd/modern-server/main.go & fi ;; \
|
|
chat-server) \
|
|
if command -v cargo-watch >/dev/null; then cd $(DIR_CHAT) && cargo watch -x run -q & else cd $(DIR_CHAT) && cargo run -q & fi ;; \
|
|
stream-server) \
|
|
if command -v cargo-watch >/dev/null; then cd $(DIR_STREAM) && cargo watch -x run -q & else cd $(DIR_STREAM) && cargo run -q & fi ;; \
|
|
web) \
|
|
cd $(DIR_WEB) && npm run dev & ;; \
|
|
*) \
|
|
$(ECHO_CMD) "${RED}Unknown service: $(SERVICE)${NC}"; exit 1 ;; \
|
|
esac
|
|
|
|
stop-local-service: ## [LOW] Stop a local service
|
|
@case "$(SERVICE)" in \
|
|
backend-api) pkill -f "air\|go run.*modern-server" ;; \
|
|
chat-server|stream-server) pkill -f "cargo.*$(SERVICE)" ;; \
|
|
web) pkill -f "npm run dev\|vite" ;; \
|
|
*) $(ECHO_CMD) "${RED}Unknown service: $(SERVICE)${NC}" ;; \
|
|
esac
|
|
|
|
# ==============================================================================
|
|
# BUILD COMMANDS
|
|
# ==============================================================================
|
|
.PHONY: build-backend-api build-chat-server build-stream-server build-web
|
|
|
|
build-backend-api: ## [LOW] Build Go backend
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building backend-api...${NC}"
|
|
@docker build -t $(PROJECT_NAME)-backend-api:latest -f $(DIR_GO)/Dockerfile.production $(DIR_GO) || \
|
|
$(ECHO_CMD) "${YELLOW}Using local Dockerfile...${NC}" && \
|
|
docker build -t $(PROJECT_NAME)-backend-api:latest -f $(DIR_GO)/Dockerfile $(DIR_GO)
|
|
|
|
build-chat-server: ## [LOW] Build Rust chat server
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building chat-server...${NC}"
|
|
@docker build -t $(PROJECT_NAME)-chat-server:latest -f $(DIR_CHAT)/Dockerfile.production $(DIR_CHAT) || \
|
|
docker build -t $(PROJECT_NAME)-chat-server:latest -f $(DIR_CHAT)/Dockerfile $(DIR_CHAT)
|
|
|
|
build-stream-server: ## [LOW] Build Rust stream server
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building stream-server...${NC}"
|
|
@docker build -t $(PROJECT_NAME)-stream-server:latest -f $(DIR_STREAM)/Dockerfile.production $(DIR_STREAM) || \
|
|
docker build -t $(PROJECT_NAME)-stream-server:latest -f $(DIR_STREAM)/Dockerfile $(DIR_STREAM)
|
|
|
|
build-web: ## [LOW] Build web frontend
|
|
@$(ECHO_CMD) "${BLUE}🔨 Building web...${NC}"
|
|
@docker build -t $(PROJECT_NAME)-web:latest -f $(DIR_WEB)/Dockerfile.production $(DIR_WEB) || \
|
|
docker build -t $(PROJECT_NAME)-web:latest -f $(DIR_WEB)/Dockerfile $(DIR_WEB)
|
|
|
|
# ==============================================================================
|
|
# INCUS / LXD DEPLOYMENT
|
|
# ==============================================================================
|
|
.PHONY: incus-setup-network incus-deploy-all incus-deploy-all-native incus-deploy-service incus-deploy-service-native incus-deploy-infra incus-start-all incus-stop-all incus-logs
|
|
|
|
incus-setup-network: ## [LOW] Setup Incus network profile
|
|
@$(ECHO_CMD) "${BLUE}📦 Setting up Incus network...${NC}"
|
|
@incus network show $(INCUS_NETWORK) >/dev/null 2>&1 || \
|
|
incus network create $(INCUS_NETWORK) ipv4.address=10.10.10.1/24 ipv4.nat=true
|
|
@incus profile show $(INCUS_PROFILE) >/dev/null 2>&1 || \
|
|
incus profile create $(INCUS_PROFILE) && \
|
|
incus profile device add $(INCUS_PROFILE) eth0 nic network=$(INCUS_NETWORK)
|
|
@$(ECHO_CMD) "${GREEN}✅ Incus network ready.${NC}"
|
|
|
|
incus-deploy-all: incus-setup-network ## [MID] Deploy all services to Incus (legacy Docker method)
|
|
@$(ECHO_CMD) "${BLUE}📦 Deploying all services to Incus (Docker)...${NC}"
|
|
@$(MAKE) -s incus-deploy-service SERVICE=backend-api
|
|
@$(MAKE) -s incus-deploy-service SERVICE=chat-server
|
|
@$(MAKE) -s incus-deploy-service SERVICE=stream-server
|
|
@$(MAKE) -s incus-deploy-service SERVICE=web
|
|
@$(MAKE) -s incus-deploy-service SERVICE=haproxy
|
|
@$(ECHO_CMD) "${GREEN}✅ All services deployed to Incus.${NC}"
|
|
|
|
incus-deploy-all-native: incus-setup-network ## [MID] Deploy all services to Incus (native, no Docker)
|
|
@$(ECHO_CMD) "${BLUE}📦 Deploying all services to Incus (native)...${NC}"
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=backend-api
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=chat-server
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=stream-server
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=web
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=haproxy
|
|
@$(ECHO_CMD) "${GREEN}✅ All services deployed to Incus.${NC}"
|
|
|
|
incus-deploy-service: ## [LOW] Deploy a service to Incus with Docker (usage: make incus-deploy-service SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@$(ECHO_CMD) "${BLUE}📦 Deploying $(SERVICE) to Incus (Docker)...${NC}"
|
|
@if incus list -c n --format csv | grep -q "^veza-$(SERVICE)$$"; then \
|
|
$(ECHO_CMD) "${YELLOW}Container exists, removing...${NC}"; \
|
|
incus delete veza-$(SERVICE) --force; \
|
|
fi
|
|
@incus init images:ubuntu/22.04 veza-$(SERVICE) --profile $(INCUS_PROFILE)
|
|
@incus start veza-$(SERVICE)
|
|
@$(ECHO_CMD) "${BLUE}Installing Docker in container...${NC}"
|
|
@incus exec veza-$(SERVICE) -- bash -c "apt-get update && apt-get install -y docker.io docker-compose && systemctl enable docker && systemctl start docker" || true
|
|
@$(ECHO_CMD) "${GREEN}✅ $(SERVICE) deployed.${NC}"
|
|
|
|
incus-deploy-service-native: ## [LOW] Deploy a service to Incus natively (usage: make incus-deploy-service-native SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@$(ECHO_CMD) "${BLUE}📦 Deploying $(SERVICE) to Incus (native)...${NC}"
|
|
@$(shell pwd)/config/incus/deploy-service-native.sh $(SERVICE)
|
|
|
|
incus-deploy-infra: incus-setup-network ## [LOW] Deploy infrastructure services (PostgreSQL, Redis)
|
|
@$(ECHO_CMD) "${BLUE}📦 Deploying infrastructure services...${NC}"
|
|
@$(MAKE) -s incus-deploy-service-native SERVICE=infra
|
|
@$(ECHO_CMD) "${BLUE}Waiting for infrastructure to be ready...${NC}"
|
|
@sleep 10
|
|
@$(ECHO_CMD) "${GREEN}✅ Infrastructure deployed.${NC}"
|
|
|
|
incus-start-all: ## [MID] Start all Incus services
|
|
@$(ECHO_CMD) "${BLUE}🚀 Starting all Incus services...${NC}"
|
|
@for service in backend-api chat-server stream-server; do \
|
|
if incus list -c n --format csv | grep -q "^veza-$$service$$"; then \
|
|
$(ECHO_CMD) "Starting veza-$$service..."; \
|
|
incus exec veza-$$service -- systemctl start veza-$$service 2>/dev/null || true; \
|
|
fi; \
|
|
done
|
|
@if incus list -c n --format csv | grep -q "^veza-web$$"; then \
|
|
$(ECHO_CMD) "Starting veza-web..."; \
|
|
incus exec veza-web -- systemctl start apache2 2>/dev/null || true; \
|
|
fi
|
|
@if incus list -c n --format csv | grep -q "^veza-haproxy$$"; then \
|
|
$(ECHO_CMD) "Starting veza-haproxy..."; \
|
|
incus exec veza-haproxy -- systemctl start haproxy 2>/dev/null || true; \
|
|
fi
|
|
@if incus list -c n --format csv | grep -q "^veza-infra$$"; then \
|
|
$(ECHO_CMD) "Starting infrastructure services..."; \
|
|
incus exec veza-infra -- systemctl start postgresql 2>/dev/null || true; \
|
|
incus exec veza-infra -- systemctl start redis-server 2>/dev/null || true; \
|
|
fi
|
|
@$(ECHO_CMD) "${GREEN}✅ All services started.${NC}"
|
|
|
|
incus-stop-all: ## [MID] Stop all Incus containers
|
|
@$(ECHO_CMD) "${YELLOW}🛑 Stopping all Incus containers...${NC}"
|
|
@for container in $$(incus list -c n --format csv | grep veza-); do \
|
|
incus stop $$container 2>/dev/null || true; \
|
|
done
|
|
@$(ECHO_CMD) "${GREEN}✅ All Incus containers stopped.${NC}"
|
|
|
|
incus-logs: ## [LOW] Show logs from Incus container (usage: make incus-logs SERVICE=backend-api)
|
|
@if [ -z "$(SERVICE)" ]; then \
|
|
$(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; \
|
|
exit 1; \
|
|
fi
|
|
@incus exec veza-$(SERVICE) -- journalctl -f
|
|
|
|
# ==============================================================================
|
|
# TEST & QUALITY
|
|
# ==============================================================================
|
|
.PHONY: test lint fmt status
|
|
|
|
test: infra-up ## [MID] Run All Tests (Fastest strategy)
|
|
@$(ECHO_CMD) "${BLUE}🧪 Running Tests...${NC}"
|
|
@$(ECHO_CMD) " [Go] Unit Tests..."
|
|
@(cd $(DIR_GO) && go test ./... -short)
|
|
@$(ECHO_CMD) " [Rust] Unit Tests..."
|
|
@(cd $(DIR_CHAT) && cargo test --lib -q)
|
|
@(cd $(DIR_STREAM) && cargo test --lib -q)
|
|
@$(ECHO_CMD) " [Web] Unit Tests..."
|
|
@(cd $(DIR_WEB) && npm run test -- --run)
|
|
@$(ECHO_CMD) "${GREEN}✅ All tests passed.${NC}"
|
|
|
|
lint: ## [MID] Lint everything
|
|
@$(ECHO_CMD) "${BLUE}🔍 Linting Codebase...${NC}"
|
|
@(cd $(DIR_CHAT) && cargo clippy -- -D warnings) || true
|
|
@(cd $(DIR_STREAM) && cargo clippy -- -D warnings) || true
|
|
@(cd $(DIR_GO) && golangci-lint run ./...) || true
|
|
@(cd $(DIR_WEB) && npm run lint) || true
|
|
|
|
fmt: ## [MID] Format everything
|
|
@$(ECHO_CMD) "${BLUE}✨ Formatting...${NC}"
|
|
@(cd $(DIR_GO) && go fmt ./...)
|
|
@(cd $(DIR_CHAT) && cargo fmt)
|
|
@(cd $(DIR_STREAM) && cargo fmt)
|
|
@(cd $(DIR_WEB) && npm run format) || true
|
|
|
|
status: ## [MID] Show system health & stats
|
|
@$(ECHO_CMD) "${BOLD}DOCKER STATS:${NC}"
|
|
@docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" 2>/dev/null | grep -E "NAME|veza" || echo "No containers running"
|
|
@$(ECHO_CMD) ""
|
|
@$(ECHO_CMD) "${BOLD}LOCAL PORTS:${NC}"
|
|
@lsof -i :$(PORT_GO) -i :$(PORT_CHAT) -i :$(PORT_STREAM) -i :$(PORT_WEB) 2>/dev/null | grep LISTEN || echo "No apps listening."
|