Development Environment
Set up your local development environment for working on Easy AppServer.
Prerequisites
Before setting up your development environment, ensure you have:
- Go 1.22+ installed and configured
- Docker and Docker Compose for infrastructure
- Git for version control
- Make for running build commands
- IDE/Editor (VS Code, GoLand, or similar)
- Node.js 18+ and pnpm (for SDK development)
Quick Setup
1. Clone the Repository
git clone <repository-url>
cd easy.appserver
2. Install Go Dependencies
# Download all Go modules
go mod download
# Verify modules
go mod verify
3. Start Development Environment
# Start infrastructure and appserver
make run-dev
This command will:
- Start all Docker infrastructure services
- Wait for services to be ready
- Start the AppServer in development mode
4. Verify Setup
# Check appserver health
curl http://localhost:8080/health
# Check infrastructure
make docker-ps
Makefile Commands
The project includes a comprehensive Makefile for common development tasks.
Infrastructure Commands
Start Infrastructure
# Start core infrastructure services
make docker-up
Starts all Docker services:
- PostgreSQL, Redis, RabbitMQ
- Kratos (identity), Hydra (OAuth2), OpenFGA (authorization), Oathkeeper (proxy)
- Observability stack (OpenTelemetry Collector, Prometheus, Loki, Tempo, Grafana)
Stop Infrastructure
# Stop services (preserve volumes)
make docker-down
# Stop and remove volumes (clean slate)
make docker-clean
View Logs
# View all service logs
make docker-logs
# View specific service logs
docker-compose -f docker/docker-compose.yml logs -f kratos
docker-compose -f docker/docker-compose.yml logs -f postgres
Check Status
# View running containers
make docker-ps
# Restart all services
make docker-restart
AppServer Commands
Run AppServer
# Run appserver (requires infrastructure)
make run
# Run complete dev environment (infrastructure + appserver)
make run-dev
Build Binary
# Build for multiple platforms
make build
# Build production binary (Linux amd64, optimized)
make build-prod
# Build for ARM v7
make build-armv7
Build output locations:
bin/amd64/main- Linux AMD64bin/arm/main- Linux ARMbin/armv7/main- Linux ARM v7bin/windows/main.exe- Windows AMD64
Testing Commands
Run Tests
# Run all tests
make test
# Run tests with docker-compose infrastructure
make docker-test
# Run tests with coverage
go test ./... -cover -coverprofile=coverage.out
# View coverage report
go tool cover -html=coverage.out
Test Specific Packages
# Test a specific package
go test ./pkg/v2/application/...
# Run with verbose output
go test -v ./pkg/v2/application/marketplace/...
# Run specific test
go test -v -run TestAppRegistration ./pkg/v2/application/marketplace/...
Docker Development Workflow
Docker Compose Commands
# Start all services
docker-compose -f docker/docker-compose.yml up -d
# Start specific service
docker-compose -f docker/docker-compose.yml up -d postgres
# Stop all services
docker-compose -f docker/docker-compose.yml down
# View logs (all services)
docker-compose -f docker/docker-compose.yml logs -f
# View logs (specific service)
docker-compose -f docker/docker-compose.yml logs -f appserver
# Rebuild service
docker-compose -f docker/docker-compose.yml up -d --build appserver
# Execute command in container
docker-compose -f docker/docker-compose.yml exec postgres psql -U partner
# Remove all containers and volumes
docker-compose -f docker/docker-compose.yml down -v
Database Access
PostgreSQL
# Connect to PostgreSQL
docker exec -it appserver-postgres psql -U partner
# Connect to specific database
docker exec -it appserver-postgres psql -U partner -d appserver
# List databases
docker exec -it appserver-postgres psql -U partner -c "\l"
# List tables in appserver database
docker exec -it appserver-postgres psql -U partner -d appserver -c "\dt"
# Execute SQL query
docker exec -it appserver-postgres psql -U partner -d appserver \
-c "SELECT * FROM apps LIMIT 10;"
# Backup database
docker exec appserver-postgres pg_dump -U partner appserver > backup.sql
# Restore database
docker exec -i appserver-postgres psql -U partner appserver < backup.sql
Redis
# Connect to Redis CLI
docker exec -it appserver-redis redis-cli
# Test connection
docker exec appserver-redis redis-cli ping
# Get all keys
docker exec appserver-redis redis-cli keys '*'
# Get value
docker exec appserver-redis redis-cli get "key-name"
# Flush all data (⚠️ use with caution)
docker exec appserver-redis redis-cli flushall
RabbitMQ
# Check status
docker exec appserver-rabbitmq rabbitmqctl status
# List queues
docker exec appserver-rabbitmq rabbitmqctl list_queues
# List exchanges
docker exec appserver-rabbitmq rabbitmqctl list_exchanges
# Management UI
open http://localhost:15672 # guest/guest
Service Health Checks
# Check all services
make docker-ps
# AppServer
curl http://localhost:8080/health
# Kratos
curl http://localhost:4433/health/ready
# Hydra
curl http://localhost:4444/health/ready
# OpenFGA
curl http://localhost:8090/healthz
# Prometheus
curl http://localhost:9090/-/healthy
# Grafana
curl http://localhost:3000/api/health
Development Tools
gRPC Development
Install grpcurl
# macOS
brew install grpcurl
# Linux
go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Enable gRPC Reflection
Add to your config or environment:
export APPSERVER_GRPC_REFLECTION_ENABLED=true
Use grpcurl
# List services
grpcurl -plaintext localhost:9090 list
# List methods
grpcurl -plaintext localhost:9090 list easy.marketplace.v2.Marketplace
# Describe service
grpcurl -plaintext localhost:9090 describe easy.marketplace.v2.Marketplace
# Call method
grpcurl -plaintext -d '{"name": "de.easy-m.test"}' \
localhost:9090 easy.marketplace.v2.Marketplace/GetApp
GraphQL Development
Enable GraphQL Playground
export APPSERVER_GRAPHQL_PLAYGROUND_ENABLED=true
Then visit: http://localhost:8080/graphql
GraphQL CLI Queries
# Install graphql-cli
npm install -g graphql-cli
# Query using curl
curl -X POST http://localhost:8080/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ apps { edges { node { id name } } } }"}'
Database Migrations
Run Migrations
# Run all pending migrations
go run cmd/appserver-v2/main.go migrate up
# Check migration status
go run cmd/appserver-v2/main.go migrate status
# Rollback last migration
go run cmd/appserver-v2/main.go migrate down
# Force migration version (if stuck)
go run cmd/appserver-v2/main.go migrate force <version>
Create New Migration
Migrations are in pkg/v2/migrations/ as embedded SQL files:
-- pkg/v2/migrations/000X_description.up.sql
CREATE TABLE example (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
-- pkg/v2/migrations/000X_description.down.sql
DROP TABLE example;
Debugging
Enable Debug Logging
# Set log level to debug
export APPSERVER_LOG_LEVEL=debug
# Run appserver
make run
Attach Debugger (VS Code)
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug AppServer (v2)",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/cmd/appserver-v2",
"args": [],
"env": {
"APPSERVER_DB_HOST": "localhost",
"APPSERVER_DB_PASSWORD": "changeme-in-production",
"APPSERVER_SETTINGS_ENCRYPTION_KEY": "changeme-32-char-encryption-key",
"APPSERVER_LOG_LEVEL": "debug"
}
}
]
}
Press F5 to start debugging.
Attach Debugger (GoLand)
- Go to Run → Edit Configurations
- Add Go Build
- Set:
- Run kind: File
- Files:
cmd/appserver-v2/main.go - Program arguments: (leave empty for v2)
- Environment: Add required env vars (including
APPSERVER_SETTINGS_ENCRYPTION_KEY)
- Click Debug
Debug with Delve
# Install delve
go install github.com/go-delve/delve/cmd/dlv@latest
# Start appserver with debugger (v2 needs no arguments)
dlv debug cmd/appserver-v2/main.go
# Or use legacy CLI with serve subcommand
dlv debug cmd/app/main.go -- serve
View Application Logs
# AppServer logs (if running via make run)
# Logs appear in terminal
# View with log levels
export APPSERVER_LOG_LEVEL=debug
make run
# View infrastructure logs
make docker-logs
# View specific service
docker-compose -f docker/docker-compose.yml logs -f kratos
Distributed Tracing
View traces in Grafana:
- Open http://localhost:3000
- Login: admin/admin
- Go to Explore → Tempo
- Search by:
- Service name:
appserver - Trace ID
- Tags (e.g.,
http.method=POST)
- Service name:
Log Aggregation
View logs in Grafana:
- Open http://localhost:3000
- Go to Explore → Loki
- Query examples:
# All appserver logs
{service_name="appserver"}
# Error logs only
{service_name="appserver"} |= "error"
# Logs for specific trace
{service_name="appserver"} | json | trace_id="abc123"
Hot Reload
Air - Live Reload for Go
Install Air:
go install github.com/cosmtrek/air@latest
Create .air.toml in project root:
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = ["serve"]
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ./cmd/appserver-v2"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "web"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
kill_delay = "0s"
log = "build-errors.log"
send_interrupt = false
stop_on_error = true
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
time = false
[misc]
clean_on_exit = false
Run with hot reload:
air
Reflex - Alternative
# Install reflex
go install github.com/cespare/reflex@latest
# Run with reflex
reflex -r '\.go$' -s -- sh -c 'go run cmd/appserver-v2/main.go serve'
IDE Setup
VS Code
Recommended Extensions
Install these extensions:
- Go (golang.go) - Official Go extension
- Docker (ms-azuretools.vscode-docker)
- PostgreSQL (ckolkman.vscode-postgres)
- GraphQL (graphql.vscode-graphql)
- REST Client (humao.rest-client)
- YAML (redhat.vscode-yaml)
- Proto 3 (zxh404.vscode-proto3)
Workspace Settings
Create .vscode/settings.json:
{
"go.testFlags": ["-v"],
"go.testTimeout": "60s",
"go.coverOnSave": false,
"go.lintTool": "golangci-lint",
"go.lintOnSave": "workspace",
"go.buildOnSave": "off",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"files.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/bin": true,
"**/tmp": true
}
}
Tasks
Create .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Start Infrastructure",
"type": "shell",
"command": "make docker-up",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "new"
}
},
{
"label": "Run AppServer",
"type": "shell",
"command": "make run",
"group": "build",
"dependsOn": ["Start Infrastructure"]
}
]
}
GoLand / IntelliJ IDEA
Enable Go Modules
- Go to Settings → Go → Go Modules
- Enable Enable Go modules integration
- Set Proxy:
https://proxy.golang.org,direct
Database Tools
- Open Database tool window
- Add PostgreSQL data source:
- Host:
localhost - Port:
5432 - Database:
appserver - User:
partner - Password:
changeme-in-production
- Host:
Docker Integration
- Open Services tool window
- Add Docker Compose:
- Path:
docker/docker-compose.yml
- Path:
Run Configurations
Create run configurations for:
- AppServer:
cmd/appserver-v2/main.go serve - Tests: All packages with coverage
- Docker Compose: Start infrastructure
SDK Development
Node.js SDK
Located in web/v2/packages/appserver-sdk/
Setup
cd web/v2/packages/appserver-sdk
# Install dependencies
pnpm install
# Build
pnpm build
# Run tests
pnpm test
# Type check
pnpm type-check
Watch Mode
# Watch for changes and rebuild
pnpm build:watch
Frontend SDK
Located in web/v2/packages/appserver-frontend-sdk/
cd web/v2/packages/appserver-frontend-sdk
pnpm install
pnpm build
pnpm test
Link SDKs Locally
# In SDK directory
cd web/v2/packages/appserver-sdk
pnpm link
# In your app
cd /path/to/your-app
pnpm link @easy/appserver-sdk
Testing Strategies
Unit Tests
# Run all tests
go test ./...
# Test specific package
go test ./pkg/v2/marketplace
# Run with coverage
go test ./... -cover
# Generate coverage report
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out
Integration Tests
# With docker-compose infrastructure
make docker-test
# Or manually
USE_DOCKER_COMPOSE=true go test ./pkg/v2/integration/...
E2E Tests
Located in web/v2/packages/appserver-sdk/test/e2e/:
# Run E2E tests (Node.js/TypeScript)
cd web/v2/packages/appserver-sdk
pnpm test:e2e
Test Docker Orchestrator
# Build orchestrator
go build -o bin/orchestrator cmd/orchestrator/main.go
# Run with test config
./bin/orchestrator --config test/orchestrator-test.yml
Performance Profiling
CPU Profiling
# Run with CPU profiling
go test -cpuprofile=cpu.prof ./pkg/v2/marketplace
# Analyze profile
go tool pprof cpu.prof
Memory Profiling
# Run with memory profiling
go test -memprofile=mem.prof ./pkg/v2/marketplace
# Analyze profile
go tool pprof mem.prof
Live Profiling
Enable pprof endpoint:
import _ "net/http/pprof"
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
Access profiles:
- http://localhost:6060/debug/pprof/
- http://localhost:6060/debug/pprof/heap
- http://localhost:6060/debug/pprof/goroutine
Common Issues & Solutions
Port Already in Use
# Find process using port
lsof -i :8080
# Kill process
kill -9 <PID>
Docker Containers Won't Start
# Clean everything and restart
make docker-clean
make docker-up
# Check logs for errors
make docker-logs
Go Module Issues
# Clean module cache
go clean -modcache
# Re-download modules
go mod download
# Verify modules
go mod verify
# Tidy modules
go mod tidy
Database Connection Errors
# Test PostgreSQL connection
docker exec appserver-postgres pg_isready -U partner
# Check if database exists
docker exec appserver-postgres psql -U partner -c "\l"
# Restart database
docker-compose -f docker/docker-compose.yml restart postgres
gRPC Reflection Not Working
# Ensure reflection is enabled
export APPSERVER_GRPC_REFLECTION_ENABLED=true
# Restart appserver
make run
Best Practices
Code Organization
- Keep business logic in
pkg/v2/ - Put commands in
cmd/ - Store migrations in
pkg/v2/migrations/ - Write tests alongside code (
*_test.go)
Git Workflow
# Create feature branch
git checkout -b feature/my-feature
# Make changes and commit
git add .
git commit -m "feat: add new feature"
# Push to remote
git push origin feature/my-feature
# Create pull request
Environment Variables
Use .env file for local development:
# Create .env file
cp docker/.env.example .env
# Load env vars
export $(cat .env | xargs)
Logging
Use structured logging:
log.Info().
Str("app_id", appID).
Str("state", state).
Msg("App state changed")
Additional Resources
- Quick Start - Get up and running quickly
- Installation Guide - Detailed installation
- Platform Architecture - System design overview
- Building Apps - App development guide