Beginner

Development Configuration

Configure Tapioca for local development with minimal dependencies and fast iteration.

This guide covers configuring Tapioca for local development. Development configuration prioritizes ease of setup, fast iteration, and helpful debugging tools over production-grade security and performance.

Quick Start

The fastest way to get started with development:

Complete Development Configuration

Here’s a fully annotated development config.yaml:

# ==============================================================================
# DEVELOPMENT CONFIGURATION
# This configuration is optimized for local development
# ==============================================================================

# Server Configuration
server:
  host: "0.0.0.0"              # Listen on all interfaces
  port: 8080                    # Standard development port
  read_timeout: "30s"
  write_timeout: "30s"
  idle_timeout: "120s"

# Database Configuration
database:
  # Local PostgreSQL - started with docker-compose
  url: "postgres://tapioca:tapioca_dev_password@localhost:5432/tapioca?sslmode=disable"
  max_open_conns: 10            # Lower for development
  max_idle_conns: 2
  conn_max_lifetime: "15m"
  conn_max_idle_time: "5m"
  
  # Auto-migrate on startup for convenience
  # Saves manual migration steps during development
  auto_migrate: true
  
  # Don't force migrations in dirty state
  # Prevents accidental data loss
  force_migrate: false

# Cache Configuration
cache:
  # Use in-memory cache for simplicity
  # No Redis required for basic development
  # Switch to "redis" when testing real-time features
  type: "memory"
  
  # Redis configuration (if type: "redis")
  redis:
    address: "localhost:6379"
    password: ""
    db: 0
    key_prefix: "tapioca:dev:"
  
  # Shorter TTLs for development
  # See changes faster
  ttl:
    default: "5m"
    permissions: "5m"
    sessions: "24h"
    queries: "1m"
    users: "10m"
    projects: "10m"
  
  # Disable cache warming for faster startup
  warming:
    enabled: false
    on_startup: false

# Authentication Configuration
auth:
  # Development session secret - CHANGE IN PRODUCTION
  session_secret: "dev-secret-change-in-production-32b"
  session_duration: "720h"       # 30 days - stay logged in
  token_expiration: "720h"
  frontend_url: "http://localhost:5173"  # Vite dev server
  
  # Integration encryption key for OAuth tokens
  integration_encryption_key: "d22f064a2fd6dded6970d2d49559c4c090c36fd3ca4c5b05e06b1870843f9106"
  
  # Development Authentication - INSTANT LOGIN
  # Allows you to log in as any user without password
  # Access at: http://localhost:8080/auth/dev/login?user_id=1
  dev:
    enabled: true               # NEVER enable in production
  
  # Local email/password authentication
  local:
    enabled: true
    password_policy:
      min_length: 4             # Relaxed for development
      require_uppercase: false
      require_lowercase: false
      require_number: false
      require_special: false
  
  # OIDC/SAML disabled for development
  # Enable if testing SSO integration
  oidc:
    enabled: false
  saml:
    enabled: false
  cloudflare_zero:
    enabled: false

# SMTP Configuration
smtp:
  # Emails are logged to console instead of sent
  # Perfect for development - see email content without sending
  host: ""
  port: 587
  username: ""
  password: ""
  from: "dev@localhost"
  from_name: "Tapioca Dev"
  tls: false

# Rate Limiting
rate_limit:
  # Disabled for development
  # No rate limiting while testing
  enabled: false

# Jobs Configuration
jobs:
  enabled: true
  worker_mode: "embedded"       # Jobs run in same process
  concurrency: 5                # Lower concurrency for dev
  
  # Shorter retention for development
  cleanup:
    session_retention_days: 1
    token_retention_days: 7
    audit_log_retention_days: 30
    job_history_retention_days: 7

# WebSocket Configuration
websocket:
  enabled: true
  max_connections_per_user: 10  # Higher for multi-tab development
  
  # Redis pub/sub disabled (single instance)
  redis:
    enabled: false

# Storage Configuration
storage:
  # Local filesystem storage
  type: "local"
  local:
    base_path: "./data/dev/storage"

# Logging Configuration
log:
  # Pretty console logging for development
  stdout:
    enabled: true
    level: "debug"              # Verbose logging
    format: "pretty"            # Colored, human-readable
    colors: true
    timestamps: true
  
  # No file or Loki logging needed
  file:
    enabled: false
  loki:
    enabled: false
  
  # Request logging - see all HTTP requests
  request:
    verbosity: 2                # Detailed request logging
    slow_request_threshold: 100 # Lower threshold for dev
    skip_health_checks: false   # Log everything
    log_request_body: false     # Enable if debugging API issues
    log_response_body: false

# Audit Configuration
audit:
  enabled: true
  retention_days: 30            # Shorter retention for dev
  granularity: "standard"       # Less detailed for dev
  async_logging: false          # Sync for easier debugging

# Performance Configuration
performance:
  # Enable profiling for development
  profiling:
    enabled: true
    pprof_enabled: true
    pprof_auth: false           # No auth required in dev
    request_timing: true
    detailed_metrics: true
  
  # Disable compression for easier debugging
  compression:
    enabled: false
  
  # Low slow query threshold
  slow_query:
    enabled: true
    threshold: "50ms"           # Catch slow queries early
    log_query: true
    log_stack_trace: true       # See where queries originate

# Public Roadmap (for testing)
public_roadmap:
  enabled: false                # Enable if testing this feature

# Development Seeding
# Automatically populate database with realistic data
dev_seed:
  enabled: true                 # Enable for realistic test data
  url: "https://tapioca.work/api/v1/public/roadmap/dev"
  org_name: "BCP Technology"
  org_slug: "bcp-technology"
  timeout: "30s"
  skip_if_exists: true          # Only seed once

Environment Variables for Development

Create a .env file in the project root for local overrides:

# .env - Local development environment variables
# This file is .gitignored - safe for local config

# Database
TAPIOCA_DATABASE_URL="postgres://tapioca:tapioca_dev_password@localhost:5432/tapioca?sslmode=disable"

# Enable auto-migrations
TAPIOCA_DATABASE_AUTO_MIGRATE=true

# Development auth (instant login)
TAPIOCA_AUTH_DEV_ENABLED=true

# Verbose logging
TAPIOCA_LOG_STDOUT_LEVEL=debug

# Frontend URL (if using different port)
TAPIOCA_AUTH_FRONTEND_URL="http://localhost:5173"

# Disable rate limiting
TAPIOCA_RATE_LIMIT_ENABLED=false

# Optional: Test with Redis instead of memory cache
# TAPIOCA_CACHE_TYPE=redis
# TAPIOCA_CACHE_REDIS_ADDRESS=localhost:6379

# Optional: Enable development seeding
# TAPIOCA_DEV_SEED_ENABLED=true

Docker Compose for Dependencies

Use this docker-compose.yml for development dependencies:

# docker-compose.yml
version: '3.8'

services:
  # PostgreSQL Database
  postgres:
    image: postgres:16-alpine
    container_name: tapioca-postgres-dev
    environment:
      POSTGRES_USER: tapioca
      POSTGRES_PASSWORD: tapioca_dev_password
      POSTGRES_DB: tapioca
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U tapioca"]
      interval: 5s
      timeout: 5s
      retries: 5

  # Redis Cache (optional - only needed for WebSocket testing)
  redis:
    image: redis:7-alpine
    container_name: tapioca-redis-dev
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5

  # MailHog - Email testing UI
  # View sent emails at http://localhost:8025
  mailhog:
    image: mailhog/mailhog:latest
    container_name: tapioca-mailhog-dev
    ports:
      - "1025:1025"   # SMTP server
      - "8025:8025"   # Web UI
    environment:
      MH_STORAGE: maildir
      MH_MAILDIR_PATH: /maildir

volumes:
  postgres_data:
  redis_data:

Start dependencies:

# Start all services
docker compose up -d

# Start only PostgreSQL
docker compose up -d postgres

# View logs
docker compose logs -f

# Stop all services
docker compose down

# Reset everything (deletes data!)
docker compose down -v

Development Workflow

Starting the Application

# Terminal 1: Start backend
go run ./cmd/tapiocad

# Terminal 2: Start frontend dev server
cd web
npm run dev

# Terminal 3: Watch for file changes and rebuild
# (optional - for automatic backend reloads)
air  # or your preferred Go hot-reload tool

Common Development Tasks

Reset Database

# Drop and recreate database
docker compose exec postgres psql -U tapioca -c "DROP DATABASE tapioca;"
docker compose exec postgres psql -U tapioca -c "CREATE DATABASE tapioca;"

# Run migrations
go run ./cmd/tapiocad migrate up

Run Migrations

# Apply all pending migrations
go run ./cmd/tapiocad migrate up

# Rollback last migration
go run ./cmd/tapiocad migrate down

# Check migration status
go run ./cmd/tapiocad migrate status

# Create new migration
go run ./cmd/tapiocad migrate create add_user_preferences

Seed Test Data

# Use development seeding (from config)
# Just start the server with dev_seed.enabled: true

# Or manually seed data
go run ./cmd/tapiocad seed --data=dev

Test Email Sending

With MailHog running:

  1. Update SMTP config to use MailHog:
smtp:
  host: "localhost"
  port: 1025
  from: "dev@localhost"
  tls: false
  1. Send a test email through the app
  2. View it at http://localhost:8025

Clear Cache

# Memory cache: Just restart the server

# Redis cache:
docker compose exec redis redis-cli FLUSHALL

# Or flush only Tapioca keys:
docker compose exec redis redis-cli --scan --pattern "tapioca:*" | xargs redis-cli DEL

Development Tools

Debugging

Enable pprof Profiling

Already enabled in development config. Access profiling tools at:

  • Heap Profile: http://localhost:8080/debug/pprof/heap
  • CPU Profile: http://localhost:8080/debug/pprof/profile?seconds=30
  • Goroutines: http://localhost:8080/debug/pprof/goroutine
  • All Profiles: http://localhost:8080/debug/pprof/

Use with go tool pprof:

# CPU profile (30 seconds)
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30

# Heap profile
go tool pprof http://localhost:8080/debug/pprof/heap

# Interactive web UI
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/heap

Database Query Logging

Enable verbose query logging:

performance:
  slow_query:
    enabled: true
    threshold: "1ms"      # Log ALL queries
    log_query: true
    log_args: true        # Include query parameters
    log_stack_trace: true

Request Tracing

Enable detailed request logging:

log:
  request:
    verbosity: 3          # Maximum verbosity
    log_request_body: true
    log_response_body: true
    max_body_size: 8192

Development Browser Extensions

Recommended browser extensions:

  • React DevTools - Inspect React component tree
  • Redux DevTools - Debug Redux state (if using Redux)
  • WebSocket Inspector - Monitor WebSocket connections
  • JSON Formatter - Pretty-print API responses

API Testing Tools

Use these tools for API testing:

# cURL
curl http://localhost:8080/api/v1/tasks 
  -H "Authorization: Bearer your-dev-token"

# HTTPie (prettier output)
http :8080/api/v1/tasks Authorization:"Bearer your-dev-token"

# Or use GUI tools:
# - Postman
# - Insomnia
# - Bruno (open-source)

VS Code Configuration

Recommended .vscode/settings.json:

{
  "go.testFlags": ["-v"],
  "go.testTimeout": "30s",
  "go.lintOnSave": "package",
  "go.formatTool": "gofmt",
  "editor.formatOnSave": true,
  "files.exclude": {
    "**/.git": true,
    "**/.DS_Store": true,
    "**/node_modules": true,
    "**/dist": true,
    "**/*.exe": true
  }
}

Recommended .vscode/launch.json for debugging:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Tapiocad",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "${workspaceFolder}/cmd/tapiocad",
      "env": {
        "TAPIOCA_LOG_STDOUT_LEVEL": "debug",
        "TAPIOCA_AUTH_DEV_ENABLED": "true"
      },
      "args": []
    },
    {
      "name": "Debug Tests",
      "type": "go",
      "request": "launch",
      "mode": "test",
      "program": "${workspaceFolder}",
      "env": {
        "TAPIOCA_DATABASE_URL": "postgres://tapioca:tapioca_dev_password@localhost:5432/tapioca_test?sslmode=disable"
      }
    }
  ]
}

Testing Configuration

Unit Tests

Use in-memory implementations for unit tests:

// tests setup
cfg := &config.Config{
	Cache: config.CacheConfig{
		Type: "memory",  // No Redis needed
	},
	Log: config.LogConfig{
		Stdout: config.LogStdoutConfig{
			Level: "error",  // Quiet during tests
		},
	},
}

Integration Tests

Use Testcontainers for integration tests:

import (
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/postgres"
)

func setupTestDB(t *testing.T) *postgres.PostgresContainer {
	ctx := context.Background()
	
	container, err := postgres.RunContainer(ctx,
		testcontainers.WithImage("postgres:16-alpine"),
		postgres.WithDatabase("tapioca_test"),
		postgres.WithUsername("tapioca"),
		postgres.WithPassword("test"),
	)
	require.NoError(t, err)
	
	return container
}

Run integration tests:

# All tests
go test ./...

# Integration tests only
go test -tags=integration ./...

# With coverage
go test -cover ./...

# Verbose output
go test -v ./...

Common Development Issues

Port Already in Use

# Find process using port 8080
lsof -i :8080

# Kill process
kill -9 <PID>

# Or use different port
TAPIOCA_SERVER_PORT=8081 go run ./cmd/tapiocad

Database Connection Failed

# Check PostgreSQL is running
docker compose ps postgres

# Check connection manually
psql -h localhost -U tapioca -d tapioca

# Restart PostgreSQL
docker compose restart postgres

Cache Not Working

# If using memory cache: Restart server

# If using Redis: Check Redis is running
docker compose ps redis
redis-cli ping

# Clear Redis cache
docker compose exec redis redis-cli FLUSHALL

Build Fails

# Clean build cache
go clean -cache

# Update dependencies
go mod tidy
go mod download

# Rebuild from scratch
rm -rf bin/
go build ./cmd/tapiocad

Next Steps

Tips for Productive Development

Development Best Practices

  1. Use dev auth for speed - Skip login during development
  2. Enable auto-migrations - Database updates automatically
  3. Use MailHog - See all outgoing emails
  4. Keep dependencies running - docker-compose up -d
  5. Use verbose logging - Catch issues early
  6. Profile regularly - Find performance issues before production
  7. Test with real data - Use dev seeding for realistic scenarios

Was this page helpful?

Let us know how we can improve