564 lines
14 KiB
Markdown
564 lines
14 KiB
Markdown
# Configuration Guide
|
|
|
|
This document describes how to configure the NOCR microservices system for different deployment scenarios.
|
|
|
|
## Table of Contents
|
|
|
|
1. [Configuration System Overview](#configuration-system-overview)
|
|
2. [Deployment Scenarios](#deployment-scenarios)
|
|
- [Local Development (VS Code)](#local-development-vs-code)
|
|
- [Docker Compose](#docker-compose)
|
|
- [Kubernetes](#kubernetes)
|
|
3. [Configuration Priority](#configuration-priority)
|
|
4. [Service-Specific Settings](#service-specific-settings)
|
|
5. [Debug Mode](#debug-mode)
|
|
6. [Troubleshooting](#troubleshooting)
|
|
|
|
---
|
|
|
|
## Configuration System Overview
|
|
|
|
The system uses ASP.NET Core's layered configuration approach with the following sources (listed from lowest to highest priority):
|
|
|
|
1. `appsettings.json` - Base configuration (committed to git)
|
|
2. `appsettings.{Environment}.json` - Environment-specific settings (some committed, some not)
|
|
3. User Secrets - Development-only secrets (stored locally, not in git)
|
|
4. **Environment Variables** - **Highest priority** (overrides everything)
|
|
|
|
### Important Notes
|
|
|
|
- **Never commit secrets to git**
|
|
- Use `.example` files as templates
|
|
- Environment Variables always win in priority
|
|
- Each service has its own configuration requirements
|
|
|
|
---
|
|
|
|
## Deployment Scenarios
|
|
|
|
### Local Development (VS Code)
|
|
|
|
For debugging services individually in VS Code:
|
|
|
|
#### Step 1: Create Environment-Specific Configuration
|
|
|
|
For each service you want to run, create `appsettings.Development.json` from the example:
|
|
|
|
```bash
|
|
# Telegram Listener
|
|
cd telegram-listener/src/Nocr.TelegramListener.Host
|
|
cp appsettings.Development.json.example appsettings.Development.json
|
|
|
|
# Text Matcher
|
|
cd text-matcher/src/Nocr.TextMatcher.Host
|
|
cp appsettings.Development.json.example appsettings.Development.json
|
|
|
|
# Users
|
|
cd users/src/Nocr.Users.Host
|
|
cp appsettings.Development.json.example appsettings.Development.json
|
|
|
|
# Telegram Client
|
|
cd telegram-client/src/Nocr.TelegramClient.Host
|
|
cp appsettings.Development.json.example appsettings.Development.json
|
|
```
|
|
|
|
#### Step 2: Fill in Your Values
|
|
|
|
Edit each `appsettings.Development.json` file and replace placeholder values with your actual credentials.
|
|
|
|
**Example for Telegram Listener:**
|
|
```json
|
|
{
|
|
"RebusRabbitMqOptions": {
|
|
"ConnectionString": "amqp://admin:admin@localhost:5672/"
|
|
},
|
|
"WTelegramClientOptions": {
|
|
"ApiId": "22101230",
|
|
"ApiHash": "c72f884d8eb84cb7134a14362bff060b",
|
|
"PhoneNumber": "79167310711"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Step 3: Alternative - Use Environment Variables
|
|
|
|
Instead of creating `appsettings.Development.json`, you can use environment variables in `.vscode/launch.json`:
|
|
|
|
```json
|
|
{
|
|
"name": "Launch Service",
|
|
"type": "coreclr",
|
|
"request": "launch",
|
|
"env": {
|
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
|
"RebusRabbitMqOptions__ConnectionString": "amqp://admin:admin@localhost:5672/",
|
|
"WTelegramClientOptions__ApiId": "22101230",
|
|
"WTelegramClientOptions__ApiHash": "c72f884d8eb84cb7134a14362bff060b",
|
|
"WTelegramClientOptions__PhoneNumber": "79167310711"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Use double underscores `__` to represent nested configuration sections in environment variables.
|
|
|
|
#### Step 4: Start Infrastructure
|
|
|
|
You need RabbitMQ and databases running:
|
|
|
|
```bash
|
|
# Start only infrastructure services
|
|
docker-compose up nocr-rabbitmq nocr-text-matcher-db nocr-users-db -d
|
|
```
|
|
|
|
#### Step 5: Debug in VS Code
|
|
|
|
Press F5 or use the Run and Debug panel to start your service.
|
|
|
|
---
|
|
|
|
### Docker Compose
|
|
|
|
For running the entire system locally with Docker:
|
|
|
|
#### Step 1: Create .nocr.env File
|
|
|
|
```bash
|
|
cd /path/to/project/root
|
|
cp .nocr.env.example .nocr.env
|
|
```
|
|
|
|
#### Step 2: Edit .nocr.env
|
|
|
|
Open `.nocr.env` and fill in your actual credentials:
|
|
|
|
```bash
|
|
# Telegram Listener - get from https://my.telegram.org/apps
|
|
WTelegramClientOptions__ApiId=22101230
|
|
WTelegramClientOptions__ApiHash=c72f884d8eb84cb7134a14362bff060b
|
|
WTelegramClientOptions__PhoneNumber=79167310711
|
|
|
|
# Telegram Client Bot - get from @BotFather
|
|
TelegramBotOptions__Token=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
|
|
|
|
# Optional: Enable debug logging
|
|
# NOCR_DEBUG_MODE=true
|
|
```
|
|
|
|
#### Step 3: Create DockerCompose Configuration Files
|
|
|
|
Each service needs `appsettings.DockerCompose.json`:
|
|
|
|
```bash
|
|
# For each service
|
|
cd telegram-listener/src/Nocr.TelegramListener.Host
|
|
cp appsettings.DockerCompose.json.example appsettings.DockerCompose.json
|
|
|
|
cd text-matcher/src/Nocr.TextMatcher.Host
|
|
cp appsettings.DockerCompose.json.example appsettings.DockerCompose.json
|
|
|
|
cd users/src/Nocr.Users.Host
|
|
cp appsettings.DockerCompose.json.example appsettings.DockerCompose.json
|
|
|
|
cd telegram-client/src/Nocr.TelegramClient.Host
|
|
cp appsettings.DockerCompose.json.example appsettings.DockerCompose.json
|
|
```
|
|
|
|
**Note:** These files contain Docker network hostnames (e.g., `nocr-rabbitmq:5672` instead of `localhost:5672`).
|
|
|
|
#### Step 4: Start All Services
|
|
|
|
```bash
|
|
docker-compose up
|
|
```
|
|
|
|
Or build and start:
|
|
|
|
```bash
|
|
docker-compose up --build
|
|
```
|
|
|
|
#### Step 5: Verify Services are Running
|
|
|
|
- Telegram Listener: http://localhost:5040/health
|
|
- Text Matcher: http://localhost:5041/health
|
|
- Users: http://localhost:5042/health
|
|
- Telegram Client: http://localhost:5050/health
|
|
- RabbitMQ Management: http://localhost:15672 (admin/admin)
|
|
|
|
---
|
|
|
|
### Kubernetes
|
|
|
|
For production deployment on Kubernetes:
|
|
|
|
#### Step 1: Create Kubernetes Secrets
|
|
|
|
**Do NOT use `.nocr.env` file in K8s.** Instead, create Secrets:
|
|
|
|
```bash
|
|
# Create namespace
|
|
kubectl create namespace nocr
|
|
|
|
# Create secrets for Telegram Listener
|
|
kubectl create secret generic telegram-listener-secrets \
|
|
--from-literal=WTelegramClientOptions__ApiId=22101230 \
|
|
--from-literal=WTelegramClientOptions__ApiHash=c72f884d8eb84cb7134a14362bff060b \
|
|
--from-literal=WTelegramClientOptions__PhoneNumber=79167310711 \
|
|
-n nocr
|
|
|
|
# Create secrets for Telegram Client
|
|
kubectl create secret generic telegram-client-secrets \
|
|
--from-literal=TelegramBotOptions__Token=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz \
|
|
-n nocr
|
|
```
|
|
|
|
#### Step 2: Reference Secrets in Deployment
|
|
|
|
Example Kubernetes deployment manifest:
|
|
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: telegram-listener
|
|
namespace: nocr
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: telegram-listener
|
|
image: nocr-telegram-listener:latest
|
|
env:
|
|
- name: ASPNETCORE_ENVIRONMENT
|
|
value: "Production"
|
|
envFrom:
|
|
- secretRef:
|
|
name: telegram-listener-secrets
|
|
```
|
|
|
|
#### Step 3: Create appsettings.Production.json
|
|
|
|
Create production config files with K8s service names:
|
|
|
|
```json
|
|
{
|
|
"RebusRabbitMqOptions": {
|
|
"ConnectionString": "amqp://admin:admin@rabbitmq-service:5672/"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Secrets from environment variables will override these values.
|
|
|
|
#### Step 4: Deploy
|
|
|
|
```bash
|
|
kubectl apply -f deployment/
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration Priority
|
|
|
|
Understanding priority is crucial when troubleshooting configuration issues.
|
|
|
|
### Priority Order (Lowest → Highest)
|
|
|
|
1. ⬇️ `appsettings.json` (base)
|
|
2. ⬆️ `appsettings.{Environment}.json` (e.g., Development, DockerCompose, Production)
|
|
3. ⬆️ User Secrets (Development only)
|
|
4. ⬆️⬆️ **Environment Variables (ALWAYS WINS)**
|
|
|
|
### Example Scenario
|
|
|
|
If you have:
|
|
|
|
- `appsettings.json`: `"ConnectionString": ""`
|
|
- `appsettings.DockerCompose.json`: `"ConnectionString": "amqp://admin:admin@nocr-rabbitmq:5672/"`
|
|
- Environment Variable: `RebusRabbitMqOptions__ConnectionString=amqp://admin:admin@localhost:5672/`
|
|
|
|
**Result:** Environment variable wins! Connection will use `localhost:5672`.
|
|
|
|
This is why we removed `appsettings.protected.json` - it was overriding Docker Compose settings incorrectly.
|
|
|
|
---
|
|
|
|
## Service-Specific Settings
|
|
|
|
### Telegram Listener
|
|
|
|
**Required Configuration:**
|
|
|
|
```json
|
|
{
|
|
"RebusRabbitMqOptions": {
|
|
"ConnectionString": "amqp://user:pass@host:port/"
|
|
},
|
|
"WTelegramClientOptions": {
|
|
"ApiId": "YOUR_API_ID",
|
|
"ApiHash": "YOUR_API_HASH",
|
|
"PhoneNumber": "YOUR_PHONE_NUMBER"
|
|
}
|
|
}
|
|
```
|
|
|
|
**How to obtain Telegram credentials:**
|
|
1. Visit https://my.telegram.org/apps
|
|
2. Log in with your phone number
|
|
3. Create a new application
|
|
4. Copy `api_id` and `api_hash`
|
|
|
|
---
|
|
|
|
### Text Matcher
|
|
|
|
**Required Configuration:**
|
|
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"TextMatcherContext": "server=host;port=3306;database=nocr_text_matcher;uid=root;pwd=password"
|
|
},
|
|
"RebusRabbitMqOptions": {
|
|
"ConnectionString": "amqp://user:pass@host:port/"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Ports by environment:**
|
|
- Development: `localhost:3316`
|
|
- Docker Compose: `nocr-text-matcher-db:3306`
|
|
- Kubernetes: `text-matcher-db-service:3306`
|
|
|
|
---
|
|
|
|
### Users
|
|
|
|
**Required Configuration:**
|
|
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"UsersContext": "server=host;port=3306;database=nocr_users;uid=root;pwd=password"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Ports by environment:**
|
|
- Development: `localhost:3326`
|
|
- Docker Compose: `nocr-users-db:3306`
|
|
- Kubernetes: `users-db-service:3306`
|
|
|
|
---
|
|
|
|
### Telegram Client
|
|
|
|
**Required Configuration:**
|
|
|
|
```json
|
|
{
|
|
"RebusRabbitMqOptions": {
|
|
"ConnectionString": "amqp://user:pass@host:port/"
|
|
},
|
|
"UsersRestEaseOptions": {
|
|
"BasePath": "http://users-service:8080"
|
|
},
|
|
"TextMatcherRestEaseOptions": {
|
|
"BasePath": "http://text-matcher-service:8080"
|
|
},
|
|
"TelegramBotOptions": {
|
|
"Token": "YOUR_BOT_TOKEN"
|
|
}
|
|
}
|
|
```
|
|
|
|
**How to obtain Bot Token:**
|
|
1. Open Telegram and find @BotFather
|
|
2. Send `/newbot` command
|
|
3. Follow instructions to create your bot
|
|
4. Copy the token provided
|
|
|
|
---
|
|
|
|
## Debug Mode
|
|
|
|
Enable debug mode to print masked configuration values on startup.
|
|
|
|
### How to Enable
|
|
|
|
Set environment variable:
|
|
|
|
```bash
|
|
export NOCR_DEBUG_MODE=true
|
|
```
|
|
|
|
Or in `.nocr.env`:
|
|
|
|
```bash
|
|
NOCR_DEBUG_MODE=true
|
|
```
|
|
|
|
Or in `docker-compose.yml`:
|
|
|
|
```yaml
|
|
environment:
|
|
NOCR_DEBUG_MODE: "true"
|
|
```
|
|
|
|
### Example Output
|
|
|
|
When debug mode is enabled, you'll see masked configuration on startup:
|
|
|
|
```
|
|
=== [NOCR_DEBUG] Configuration Values ===
|
|
[NOCR_DEBUG] RebusRabbitMqOptions:
|
|
[NOCR_DEBUG] ConnectionString: amqp://admin:***@nocr-rabbitmq:5672/
|
|
[NOCR_DEBUG] InputQueueName: nocr.telegram.listener.queue
|
|
[NOCR_DEBUG] DirectExchangeName: nocr.direct
|
|
[NOCR_DEBUG] TopicsExchangeName: nocr.topics
|
|
[NOCR_DEBUG] WTelegramClientOptions:
|
|
[NOCR_DEBUG] ApiId: 22101230
|
|
[NOCR_DEBUG] ApiHash: c7...0b
|
|
[NOCR_DEBUG] PhoneNumber: 79...11
|
|
=== [NOCR_DEBUG] End Configuration ===
|
|
```
|
|
|
|
**Security:** Passwords and secrets are automatically masked to protect sensitive data.
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Problem: Service can't connect to RabbitMQ
|
|
|
|
**Symptoms:**
|
|
```
|
|
Connection refused to nocr-rabbitmq:5672
|
|
```
|
|
|
|
**Solution:**
|
|
1. Check if RabbitMQ is running: `docker-compose ps nocr-rabbitmq`
|
|
2. Enable debug mode: `NOCR_DEBUG_MODE=true`
|
|
3. Verify ConnectionString in debug output
|
|
4. For Docker Compose, ensure hostname is `nocr-rabbitmq:5672`, NOT `localhost:5672`
|
|
5. Check if environment variable is overriding appsettings
|
|
|
|
---
|
|
|
|
### Problem: Service can't connect to database
|
|
|
|
**Symptoms:**
|
|
```
|
|
Unable to connect to any of the specified MySQL hosts
|
|
```
|
|
|
|
**Solution:**
|
|
1. Check database is running: `docker-compose ps nocr-text-matcher-db`
|
|
2. Enable debug mode to see masked connection string
|
|
3. Verify hostname in connection string:
|
|
- Docker Compose: `nocr-text-matcher-db:3306`
|
|
- Local dev: `localhost:3316`
|
|
4. Wait for database healthcheck to pass (may take 10-30 seconds on first start)
|
|
|
|
---
|
|
|
|
### Problem: Configuration values not applied
|
|
|
|
**Symptoms:**
|
|
- Settings in `appsettings.Development.json` are ignored
|
|
- Service uses wrong configuration
|
|
|
|
**Solution:**
|
|
1. Check `ASPNETCORE_ENVIRONMENT` is set correctly:
|
|
- VS Code: `Development`
|
|
- Docker Compose: `DockerCompose`
|
|
- K8s: `Production`
|
|
2. Enable debug mode to see which values are loaded
|
|
3. Check for environment variables overriding your settings
|
|
4. Remember: **Environment Variables always win!**
|
|
|
|
---
|
|
|
|
### Problem: Secrets exposed in logs
|
|
|
|
**Solution:**
|
|
- Debug mode automatically masks sensitive values
|
|
- Never log configuration in production without masking
|
|
- Review debug output format in `Startup.cs`:
|
|
- Passwords: `amqp://user:***@host`
|
|
- Secrets: `ab...yz` (first 2 + last 2 chars only)
|
|
|
|
---
|
|
|
|
### Problem: Missing .nocr.env file
|
|
|
|
**Symptoms:**
|
|
```
|
|
docker-compose up fails with missing environment variables
|
|
```
|
|
|
|
**Solution:**
|
|
1. Copy example file: `cp .nocr.env.example .nocr.env`
|
|
2. Fill in your actual values
|
|
3. Make sure `.nocr.env` is in the project root (same level as `docker-compose.yml`)
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
### Environment Variable Naming Convention
|
|
|
|
ASP.NET Core uses double underscores `__` to represent nested JSON structure:
|
|
|
|
```bash
|
|
# JSON: { "Section": { "Key": "Value" } }
|
|
# Environment Variable:
|
|
Section__Key=Value
|
|
|
|
# Example:
|
|
WTelegramClientOptions__ApiId=12345
|
|
RebusRabbitMqOptions__ConnectionString=amqp://localhost
|
|
```
|
|
|
|
### File Locations
|
|
|
|
```
|
|
flea/ # Project root
|
|
├── .nocr.env # Your secrets (gitignored)
|
|
├── .nocr.env.example # Template (committed)
|
|
├── docker-compose.yml # References .nocr.env
|
|
│
|
|
├── telegram-listener/
|
|
│ └── src/Nocr.TelegramListener.Host/
|
|
│ ├── appsettings.json # Base (committed)
|
|
│ ├── appsettings.Development.json # Local dev (gitignored)
|
|
│ ├── appsettings.Development.json.example # Template (committed)
|
|
│ ├── appsettings.DockerCompose.json # Docker (gitignored)
|
|
│ └── appsettings.DockerCompose.json.example # Template (committed)
|
|
│
|
|
└── [same structure for text-matcher, users, telegram-client]
|
|
```
|
|
|
|
---
|
|
|
|
## Security Best Practices
|
|
|
|
1. ✅ **Never commit secrets** - Use `.example` files as templates
|
|
2. ✅ **Use environment variables** for sensitive data in production
|
|
3. ✅ **Use K8s Secrets** for Kubernetes deployments
|
|
4. ✅ **Enable debug mode** only when troubleshooting
|
|
5. ✅ **Rotate credentials** regularly
|
|
6. ✅ **Use User Secrets** for local development (optional)
|
|
7. ❌ **Don't commit** `.nocr.env` or `appsettings.*.json` (except `.example` files)
|
|
8. ❌ **Don't use** `appsettings.protected.json` (removed from code)
|
|
|
|
---
|
|
|
|
## Additional Resources
|
|
|
|
- [ASP.NET Core Configuration Docs](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/)
|
|
- [Docker Compose Environment Variables](https://docs.docker.com/compose/environment-variables/)
|
|
- [Kubernetes Secrets](https://kubernetes.io/docs/concepts/configuration/secret/)
|
|
- [Telegram API Documentation](https://core.telegram.org/api)
|
|
- [Telegram Bot API](https://core.telegram.org/bots/api)
|