This guide will walk you through setting up the Wallet Framework project on your local machine. Follow these steps to get the entire system running from scratch.
- Prerequisites
- Installation Steps
- Initial Data Seeding
- Keycloak Configuration
- Creating Test Users
- Testing the Setup
- Troubleshooting
Before you begin, ensure you have the following tools installed on your system:
| Tool | Minimum Version | Purpose | Download |
|---|---|---|---|
| Docker Desktop | Latest | Container orchestration for all services | Docker Desktop |
| .NET 10 SDK | 10.0+ | Required for local development (optional if only running via Docker) | .NET 10 SDK |
| Git | Latest | Repository cloning | Git |
| IDE | - | Code editing (VS Code, Visual Studio, or Rider) | - |
# Check Docker
docker --version
docker-compose --version
# Check .NET SDK (if developing locally)
dotnet --version
# Check Git
git --versiongit clone <repository-url>
cd WalletFrameworkReplace <repository-url> with your actual repository URL.
The project uses Docker Compose to orchestrate all services. Start all containers with a single command:
docker-compose up -dThis command will:
- Pull required Docker images (if not already present)
- Create Docker networks and volumes
- Start all services in detached mode (
-dflag)
Docker Compose automatically handles dependencies. Services start in this order:
- Infrastructure Services (PostgreSQL, RabbitMQ, Redis, Vault)
- Keycloak (depends on PostgreSQL)
- Observability Stack (Prometheus, Grafana, Jaeger)
- Microservices (CustomerService, WalletService, TransactionService, FraudService)
- API Gateway (depends on all services)
Watch container logs to verify services are starting correctly:
# View all logs
docker-compose logs -f
# View logs for a specific service
docker-compose logs -f customerservice
docker-compose logs -f keycloakCheck that all containers are running:
docker-compose psYou should see all services with status Up. Wait 30-60 seconds for all services to fully initialize, especially Keycloak and the microservices.
| Container | Status | Ports |
|---|---|---|
postgres_db2 |
Up | 5432:5432 |
pgadmin_gui |
Up | 5050:80 |
rabbitmq_broker |
Up | 5672:5672, 15672:15672 |
redis_cache |
Up | 6379:6379 |
keycloak_idm |
Up | 8080:8080 |
vault_secrets |
Up | 8200:8200 |
prometheus_metrics |
Up | 9090:9090 |
grafana_dashboard |
Up | 3000:3000 |
jaeger_tracing |
Up | 16686:16686, 4317:4317 |
wf_apigateway |
Up | 5000:8080 |
wf_customerservice |
Up | 7001:8080 |
wf_walletservice |
Up | 7004:8080 |
wf_transactionservice |
Up | 7003:8080 |
wf_fraudservice |
Up | 7002:8080 |
mailhog |
Up | 1025:1025, 8025:8025 |
When PostgreSQL starts for the first time, it automatically executes init-db.sql to create all required databases:
WF_KeycloakDb- Keycloak identity and access management databaseWF_CustomerDb- Customer service databaseWF_WalletDb- Wallet service databaseWF_TransactionDb- Transaction service databaseWF_FraudDb- Fraud detection service database
Note: The script runs automatically on first container startup. If you need to reset databases, remove the PostgreSQL volume:
docker-compose down -v # Removes volumes
docker-compose up -d # Recreates everythingKeycloak automatically imports the realm configuration from wallet-realm.json on startup. This includes:
- Realm Name:
wallet-realm - Client:
wallet-client(OAuth 2.0 / OIDC client) - Service Account: Pre-configured service account for inter-service authentication
- Roles and Scopes: Default realm roles and client scopes
Important: The realm import happens automatically when Keycloak starts with the --import-realm flag. You should see a log message confirming the import:
Added realm 'wallet-realm' from file /opt/keycloak/data/import/realm.json
**********). You must regenerate it in Keycloak UI and update service configurations.
-
Access Keycloak Admin Console
- Navigate to: http://localhost:8080
- Click "Administration Console"
- Login with:
- Username:
admin - Password:
admin
- Username:
-
Select the Wallet Realm
- In the top-left dropdown, select
wallet-realm(notmaster)
- In the top-left dropdown, select
-
Navigate to Clients
- In the left sidebar, click Clients
- Find and click on
wallet-client
-
Regenerate Client Secret
- Click on the Credentials tab
- Click the Regenerate button next to "Client Secret"
- Copy the new secret immediately (you won't be able to see it again)
-
Save the Secret
- Store the secret securely (you'll need it in the next step)
After regenerating the client secret, you must update it in service configurations. Choose one of the following methods:
Update the Keycloak__ClientSecret environment variable in docker-compose.yml for all services:
# Example for CustomerService
customerservice:
environment:
Keycloak__ClientSecret: <YOUR_NEW_CLIENT_SECRET> # Replace thisServices to update:
customerservicewalletservicetransactionservicefraudserviceapigateway
After updating, restart the affected services:
docker-compose restart customerservice walletservice transactionservice fraudservice apigatewayStore the client secret in Vault for centralized secret management:
-
Access Vault UI
- Navigate to: http://localhost:8200
- Login with token:
my-root-token(dev mode)
-
Store the Secret
- Navigate to: Secrets → secret → wallet → shared
- Create/Update key:
Keycloak__ClientSecret - Value:
<YOUR_NEW_CLIENT_SECRET>
-
Verify Service Configuration
- Services automatically reload secrets from Vault every 600 seconds (10 minutes)
- Check service logs to confirm Vault connection:
docker-compose logs customerservice | grep -i vault
If running services locally (not via Docker), update appsettings.Development.json:
| Service | Configuration File |
|---|---|
| CustomerService | src/Services/CustomerService/WF.CustomerService.Api/appsettings.Development.json |
| WalletService | src/Services/WalletService/WF.WalletService.Api/appsettings.Development.json |
| TransactionService | src/Services/TransactionService/WF.TransactionService.Api/appsettings.Development.json |
| FraudService | src/Services/FraudService/WF.FraudService.Api/appsettings.Development.json |
| ApiGateway | src/Infrastructure/WF.ApiGateway/appsettings.json |
Update the Keycloak section:
{
"Keycloak": {
"BaseUrl": "http://localhost:8080",
"Realm": "wallet-realm",
"ClientId": "wallet-client",
"ClientSecret": "<YOUR_NEW_CLIENT_SECRET>"
}
}To test the system, you need to create users in Keycloak. Users can then register via the CustomerService API, but for initial testing, you can create them directly in Keycloak.
-
Navigate to Users
- In Keycloak Admin Console (wallet-realm)
- Click Users in the left sidebar
- Click Add user button
-
Fill User Details
- Username: (e.g.,
testuser1) - Email: (e.g.,
testuser1@example.com) - First name: (optional)
- Last name: (optional)
- Toggle Email verified to ON (for testing)
- Click Create
- Username: (e.g.,
-
Set Password
- Click on the Credentials tab
- Click Set password
- Enter password (e.g.,
Password123!) - Toggle Temporary to OFF (so password doesn't expire)
- Click Save
- Confirm by clicking Set password in the dialog
-
Assign Roles (Optional)
- Click on the Role mapping tab
- Assign realm roles if needed (usually not required for basic testing)
Alternatively, users can register via the CustomerService API. See the Services Documentation for API details.
# Check PostgreSQL is ready
docker exec postgres_db2 pg_isready -U postgres
# Or access via PgAdmin
# Navigate to: http://localhost:5050
# Login: admin@example.com / admin
# Add server: postgres:5432, user: postgres, password: myStrongPassword123!- Management UI: http://localhost:15672
- Username:
user - Password:
password - Verify queues and exchanges are created by services
# Test Redis connection
docker exec redis_cache redis-cli ping
# Should return: PONG- Admin Console: http://localhost:8080
- Realm:
wallet-realm - Verify realm is imported and
wallet-clientexists
- UI: http://localhost:8200
- Token:
my-root-token(dev mode) - Verify secrets can be stored and retrieved
Each service exposes a Swagger UI for API testing:
| Service | Swagger URL |
|---|---|
| API Gateway | http://localhost:5000/swagger |
| CustomerService | http://localhost:7001/swagger |
| WalletService | http://localhost:7004/swagger |
| TransactionService | http://localhost:7003/swagger |
| FraudService | http://localhost:7002/swagger |
Note: Most endpoints require authentication. Use the "Authorize" button in Swagger UI with a Bearer token.
To authenticate API requests, you need to obtain a JWT token from Keycloak:
curl -X POST "http://localhost:5000/api/v1/auth/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=wallet-client" \
-d "username=<YOUR_USERNAME>" \
-d "password=<YOUR_PASSWORD>"Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ...",
"expires_in": 300,
"refresh_expires_in": 1800,
"token_type": "Bearer",
...
}- Open any service's Swagger UI (e.g., http://localhost:7001/swagger)
- Click the Authorize button (lock icon)
- In the "Value" field, paste your
access_tokenfrom the curl response - Click Authorize, then Close
- Now you can test authenticated endpoints
All services expose health check endpoints:
# API Gateway
curl http://localhost:5000/health
# CustomerService
curl http://localhost:7001/health
# WalletService
curl http://localhost:7004/health
# TransactionService
curl http://localhost:7003/health
# FraudService
curl http://localhost:7002/healthExpected response: Healthy or JSON health status.
- Jaeger UI: http://localhost:16686 - View distributed traces
- Prometheus: http://localhost:9090 - View metrics
- Grafana: http://localhost:3000 - View dashboards (login:
admin/admin)
Problem: Containers fail to start or exit immediately.
Solutions:
- Check logs:
docker-compose logs <service-name> - Verify ports are not in use:
netstat -an | grep <port>(Windows) orlsof -i :<port>(Mac/Linux) - Ensure Docker has enough resources (CPU/Memory)
- Try removing volumes and restarting:
docker-compose down -v && docker-compose up -d
Problem: Services cannot connect to PostgreSQL.
Solutions:
- Verify PostgreSQL is running:
docker-compose ps postgres - Check PostgreSQL logs:
docker-compose logs postgres - Verify database exists: Connect via PgAdmin and check for
WF_*databases - Check connection string in service configuration matches docker-compose.yml
Problem: "401 Unauthorized" or "Invalid token" errors.
Solutions:
- Verify client secret is updated in all service configurations
- Check token expiration (default: 5 minutes)
- Verify Keycloak is accessible: http://localhost:8080
- Check Keycloak logs:
docker-compose logs keycloak - Ensure you're using the correct realm (
wallet-realm, notmaster)
Problem: Services cannot communicate via RabbitMQ.
Solutions:
- Verify RabbitMQ is running:
docker-compose ps rabbitmq - Check RabbitMQ Management UI: http://localhost:15672
- Verify queues exist in RabbitMQ UI
- Check service logs for connection errors:
docker-compose logs <service-name> | grep -i rabbit
Problem: wallet-realm is not available in Keycloak.
Solutions:
- Check Keycloak logs for import errors:
docker-compose logs keycloak | grep -i realm - Verify
wallet-realm.jsonfile exists in project root - Restart Keycloak:
docker-compose restart keycloak - Manually import realm via Keycloak Admin Console if needed
Problem: "Port is already allocated" error.
Solutions:
- Find process using the port:
# Windows netstat -ano | findstr :<port> # Mac/Linux lsof -i :<port>
- Stop the conflicting process or change the port in docker-compose.yml
- Restart Docker Desktop if needed
Problem: Services cannot connect to Vault.
Solutions:
- Verify Vault is running:
docker-compose ps vault - Check Vault UI: http://localhost:8200
- Verify Vault token in service configuration:
my-root-token(dev mode) - Check service logs for Vault errors:
docker-compose logs <service-name> | grep -i vault
Problem: Health check endpoint returns unhealthy.
Solutions:
- Check service logs for errors:
docker-compose logs <service-name> - Verify database connection
- Verify RabbitMQ connection
- Check for missing environment variables
- Verify Keycloak connection and client secret
Now that your environment is set up:
- Explore the Architecture: Read Architecture Documentation to understand system design
- Learn About Services: Check Services Documentation for API details
- Understand Patterns: Review Patterns and Practices for implementation details
- Configure Security: See Security Documentation for authentication flows