GAAP uses a hybrid development model for optimal performance:
- API (Go): Runs locally with
airhot-reload - Web (Next.js): Runs locally with native HMR
- Middleware (Postgres, Redis, RabbitMQ, Caddy): Runs in Docker containers
This architecture provides the best HMR experience on Windows/macOS while keeping infrastructure isolated. Caddy provides HTTPS automatically for local development.
# Install Air for Go hot-reload
go install github.com/air-verse/air@v1.61.7
# Install Delve for Go debugging (optional)
go install github.com/go-delve/delve/cmd/dlv@latestThe root .env file is shared across all services via symlinks:
gaap/
├── .env # Single source of truth
├── gaap-api/
│ └── .env -> ../.env # Symlink (auto-created)
└── gaap-web/
└── .env.local -> ../.env # Symlink (auto-created)
When you run start-dev.bat start or ./start-dev.sh start, symlinks are automatically created.
If symlinks fail, create them manually:
Windows:
cd gaap-api
mklink .env ..\.env
cd gaap-web
mklink .env.local ..\.envmacOS/Linux:
cd gaap-api
ln -s ../.env .env
cd gaap-web
ln -s ../.env .env.localYou can create .env.local in gaap-web to override specific values without modifying the shared .env:
# gaap-web/.env.local (overrides)
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1macOS/Linux:
sudo nano /etc/hosts
# Add the following line
127.0.0.1 gaap.localWindows:
# Run Notepad as Administrator
notepad C:\Windows\System32\drivers\etc\hosts
# Add the following line
127.0.0.1 gaap.local# 1. Clone project (including submodules)
git clone --recursive https://github.com/gin-melodic/gaap.git
cd gaap
# 2. Configure environment variables
cp .env.example .env
# Modify .env file as needed
# 3. Start all services (middleware + local API/Web)
# Windows
start-dev.bat start
# macOS/Linux
./start-dev.sh start# Start only middleware (Docker containers)
# Windows
start-dev.bat start middleware
# macOS/Linux
./start-dev.sh start middleware
# Then manually start API and Web:
# API (in gaap-api directory)
cd gaap-api
air
# Web (in gaap-web directory, new terminal)
cd gaap-web
npm run dev# View all commands
start-dev.bat help # Windows
./start-dev.sh help # macOS/Linux
# Start/Stop services
start-dev.bat start # Start all
start-dev.bat stop # Stop all
start-dev.bat restart # Restart all
# Start specific services
start-dev.bat start middleware # Only Docker containers
start-dev.bat start api # Only API (local)
start-dev.bat start web # Only Web (local)
# Install dependencies
start-dev.bat install # Install both API and Web deps
start-dev.bat install api # Install Go dependencies
start-dev.bat install web # Install Node.js dependencies
# View logs (middleware only)
start-dev.bat logs middleware- Frontend (HTTP): http://localhost:3000
- Frontend (HTTPS): https://gaap.local
- Backend API: http://localhost:8000
- API Health: http://localhost:8000/api/health
- RabbitMQ Management: http://localhost:15672
- Caddy Admin API: http://localhost:2019
Step 1: Configure VSCode
Create gaap-api/.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug with Delve",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}",
"env": {},
"args": []
},
{
"name": "Attach to Remote Delve",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "${workspaceFolder}",
"port": 40000,
"host": "localhost",
"showLog": true,
"trace": "verbose",
"logOutput": "rpc"
}
]
}Step 2: Start Debugging
- Open
gaap-apiproject in VSCode - Set breakpoints in code
- Press
F5or click "Run and Debug" → "Debug with Delve" - Trigger API requests using browser or Postman
- Breakpoint triggers in VSCode, view variables, step through, etc.
Step 1: Create Run Configuration
- Go to Run → Edit Configurations
- Add Go Remote configuration:
- Host: localhost
- Port: 40000
Step 2: Start Debugging
- Start Delve manually:
cd gaap-api dlv debug --headless --listen=:40000 --api-version=2 - Click Debug icon in GoLand
Air automatically recompiles Go code when files change:
# Start with hot reload
cd gaap-api
air
# Configuration: gaap-api/.air.tomlcd gaap-web
# Standard development mode
npm run dev
# With polling (for WSL)
npm run dev:dockerCreate gaap-web/.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Next.js",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "npm",
"runtimeArgs": ["run", "dev"],
"console": "integratedTerminal"
}
]
}# Connect to PostgreSQL
docker exec -it gaap-postgres-dev psql -U gaap_user -d gaap
# Import SQL
docker exec -i gaap-postgres-dev psql -U gaap_user -d gaap < schema_ddl.sql
# Backup Database
docker exec gaap-postgres-dev pg_dump -U gaap_user gaap > backup.sqlAccess: http://localhost:15672
- Username:
gaap_mq - Password:
RABBITMQ_PASSWORDin.env
Browser will warn about untrusted certificate on first access, this is normal.
- Chrome/Edge: Click "Advanced" → "Proceed"
- Firefox: Click "Advanced" → "Accept the Risk and Continue"
# Export Caddy root certificate
docker exec gaap-caddy-dev cat /data/caddy/pki/authorities/local/root.crt > caddy-root.crt
# macOS: Add to Keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain caddy-root.crt
# Linux (Ubuntu/Debian)
sudo cp caddy-root.crt /usr/local/share/ca-certificates/caddy-root.crt
sudo update-ca-certificates
# Windows: Double click caddy-root.crt → Install Certificate → Trusted Root Certification Authorities# Test API connection
curl -k https://gaap.local/api/health
# View Caddy configuration
curl http://localhost:2019/config/ | jq
# Test frontend-backend communication (no CORS issues)
curl -k https://gaap.local/api/v1/users
# Check certificate
openssl s_client -connect gaap.local:443 -servername gaap.local# Check if port is open
netstat -an | grep 40000
# Check container permissions
docker inspect gaap-api-dev | grep -A 5 CapAdd
# Ensure SYS_PTRACE permission# Check Volume mounts
docker-compose -f docker-compose.dev.yml config | grep volumes -A 5
# Manually trigger recompilation
docker exec -it gaap-api-dev air# Use Go Proxy (China Region)
docker exec -it gaap-api-dev sh
go env -w GOPROXY=https://goproxy.cn,direct# Connect to PostgreSQL
docker exec -it gaap-postgres-dev psql -U gaap_user -d gaap
# Import SQL
docker exec -i gaap-postgres-dev psql -U gaap_user -d gaap < schema_ddl.sql
# Backup Database
docker exec gaap-postgres-dev pg_dump -U gaap_user gaap > backup.sqlAccess: http://localhost:15672
- Username:
gaap_mq - Password:
RABBITMQ_PASSWORDin.env