Semplifica configurazione Docker e gestione porta UI
Riorganizza .env.example lasciando solo EXTERNAL_PORT e spostando tutte le altre impostazioni applicative nella UI web. Il mapping della porta in docker-compose.yml ora usa la variabile EXTERNAL_PORT per una personalizzazione più semplice. Rimosse variabili e opzioni avanzate non essenziali dal compose. Aggiornata la documentazione per riflettere la nuova gestione centralizzata delle impostazioni tramite interfaccia web.
This commit is contained in:
@@ -1,107 +1,44 @@
|
|||||||
# TradingBot - Environment Variables Example
|
# TradingBot - Docker Environment Variables
|
||||||
# Copia questo file come .env e personalizza i valori
|
# Copia questo file come .env per personalizzare la configurazione Docker
|
||||||
|
|
||||||
# ==============================================
|
# ==============================================
|
||||||
# DOCKER CONFIGURATION
|
# DOCKER CONFIGURATION
|
||||||
# ==============================================
|
# ==============================================
|
||||||
|
|
||||||
# Timezone (importante per trading!)
|
# Porta esterna per accesso WebUI
|
||||||
TZ=Europe/Rome
|
# Modifica se la porta 8080 è già in uso sul tuo sistema
|
||||||
|
# Default: 8080
|
||||||
# ASP.NET Core Environment
|
|
||||||
ASPNETCORE_ENVIRONMENT=Production
|
|
||||||
|
|
||||||
# Logging Level
|
|
||||||
# Options: Trace, Debug, Information, Warning, Error, Critical
|
|
||||||
Logging__LogLevel__Default=Information
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# APPLICATION SETTINGS
|
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# Modalità Simulazione (true = dati simulati, false = dati reali)
|
|
||||||
TRADINGBOT__SimulationMode=true
|
|
||||||
|
|
||||||
# Auto-start bot all'avvio
|
|
||||||
TRADINGBOT__AutoStartBot=true
|
|
||||||
|
|
||||||
# Intervallo aggiornamento dati (secondi)
|
|
||||||
# Min: 2, Max: 10, Consigliato: 3
|
|
||||||
TRADINGBOT__UpdateIntervalSeconds=3
|
|
||||||
|
|
||||||
# Notifiche Desktop (true/false)
|
|
||||||
TRADINGBOT__DesktopNotifications=false
|
|
||||||
|
|
||||||
# Conferma operazioni manuali (true/false)
|
|
||||||
TRADINGBOT__ConfirmManualTrades=false
|
|
||||||
|
|
||||||
# Log Level applicazione
|
|
||||||
# Options: Error, Warning, Info, Debug
|
|
||||||
TRADINGBOT__LogLevel=Info
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# DOCKER COMPOSE OVERRIDES
|
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# Porta esterna (modifica se 8080 è già in uso)
|
|
||||||
EXTERNAL_PORT=8080
|
EXTERNAL_PORT=8080
|
||||||
|
|
||||||
# Resource Limits
|
|
||||||
MEMORY_LIMIT=1G
|
|
||||||
MEMORY_RESERVATION=256M
|
|
||||||
CPU_LIMIT=2.0
|
|
||||||
CPU_RESERVATION=0.5
|
|
||||||
|
|
||||||
# ==============================================
|
# ==============================================
|
||||||
# REGISTRY (opzionale - per push immagini)
|
# NOTE IMPORTANTI
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# Docker Registry URL (lascia vuoto se non usi registry privato)
|
|
||||||
DOCKER_REGISTRY=
|
|
||||||
|
|
||||||
# Registry username
|
|
||||||
REGISTRY_USER=
|
|
||||||
|
|
||||||
# Registry password (usa Docker secrets in produzione!)
|
|
||||||
REGISTRY_PASSWORD=
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# BACKUP (opzionale)
|
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# Directory backup su host
|
|
||||||
BACKUP_DIR=/mnt/user/backups/tradingbot
|
|
||||||
|
|
||||||
# Retention giorni backup
|
|
||||||
BACKUP_RETENTION_DAYS=7
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# MONITORING (opzionale)
|
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# Prometheus metrics endpoint (true/false)
|
|
||||||
ENABLE_METRICS=false
|
|
||||||
|
|
||||||
# Health check interval (seconds)
|
|
||||||
HEALTHCHECK_INTERVAL=30
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# ADVANCED
|
|
||||||
# ==============================================
|
|
||||||
|
|
||||||
# HTTPS Redirection (true/false)
|
|
||||||
# Disabilita se usi reverse proxy
|
|
||||||
ASPNETCORE_HTTPS_PORT=
|
|
||||||
|
|
||||||
# Kestrel limits
|
|
||||||
KESTREL_LIMITS_MAXREQUESTBODYSIZE=10485760
|
|
||||||
|
|
||||||
# ==============================================
|
|
||||||
# NOTES
|
|
||||||
# ==============================================
|
# ==============================================
|
||||||
#
|
#
|
||||||
# 1. Non committare questo file con credenziali reali!
|
# ?? TUTTE LE ALTRE CONFIGURAZIONI DELL'APPLICAZIONE
|
||||||
# 2. Aggiungi .env al .gitignore
|
# SONO GESTIBILI DALL'INTERFACCIA WEB:
|
||||||
# 3. Usa Docker secrets per password in produzione
|
#
|
||||||
# 4. Restart container dopo modifiche: docker-compose restart
|
# - Fuso orario (Timezone)
|
||||||
|
# - Auto-start del bot
|
||||||
|
# - Intervallo aggiornamento dati
|
||||||
|
# - Modalità simulazione
|
||||||
|
# - Notifiche
|
||||||
|
# - Log level
|
||||||
|
# - E tutte le altre impostazioni
|
||||||
|
#
|
||||||
|
# Accedi all'interfaccia web su:
|
||||||
|
# http://localhost:8080 (o la porta configurata)
|
||||||
|
#
|
||||||
|
# Vai su ?? Impostazioni per configurare l'applicazione.
|
||||||
|
#
|
||||||
|
# Le impostazioni sono salvate automaticamente nel volume Docker
|
||||||
|
# e persistono tra i restart del container.
|
||||||
|
#
|
||||||
|
# ==============================================
|
||||||
|
# EXAMPLES
|
||||||
|
# ==============================================
|
||||||
|
#
|
||||||
|
# Se la porta 8080 è occupata, usa un'altra:
|
||||||
|
# EXTERNAL_PORT=8081
|
||||||
|
#
|
||||||
|
# Poi accedi su: http://localhost:8081
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,378 +0,0 @@
|
|||||||
# ? CONFIGURAZIONE UI BROWSER - TradingBot Blazor Server
|
|
||||||
|
|
||||||
## ?? Modifiche Applicate per Accessibilità Browser
|
|
||||||
|
|
||||||
### ? **1. Program.cs - Configurazione Kestrel**
|
|
||||||
|
|
||||||
Configurato Kestrel per ascoltare su tutte le interfacce in Docker:
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
builder.WebHost.ConfigureKestrel(serverOptions =>
|
|
||||||
{
|
|
||||||
// Listen su porta 8080 per Docker
|
|
||||||
serverOptions.ListenAnyIP(8080);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
**HTTPS Redirect disabilitato in Production**:
|
|
||||||
```csharp
|
|
||||||
// Solo in Development
|
|
||||||
if (app.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Perché**: In Docker, HTTPS è gestito da reverse proxy (se usato). Il redirect HTTPS causa problemi di accesso.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ? **2. appsettings.json - Kestrel Endpoints**
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Kestrel": {
|
|
||||||
"Endpoints": {
|
|
||||||
"Http": {
|
|
||||||
"Url": "http://0.0.0.0:8080"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**0.0.0.0**: Listen su tutte le interfacce (necessario per Docker)
|
|
||||||
**:8080**: Porta standard per l'applicazione
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ? **3. appsettings.Production.json - Config Docker**
|
|
||||||
|
|
||||||
Creato file specifico per ambiente Production (Docker):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Kestrel": {
|
|
||||||
"Endpoints": {
|
|
||||||
"Http": {
|
|
||||||
"Url": "http://0.0.0.0:8080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Limits": {
|
|
||||||
"MaxRequestBodySize": 10485760
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**MaxRequestBodySize**: 10MB limit per sicurezza
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### ? **4. docker-compose.yml - Health Check**
|
|
||||||
|
|
||||||
Aggiornato health check per usare `wget`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Prima**: Usava `curl` (non disponibile)
|
|
||||||
**Dopo**: Usa `wget` (installato nel Dockerfile)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Come Accedere all'UI
|
|
||||||
|
|
||||||
### Sviluppo Locale (senza Docker)
|
|
||||||
|
|
||||||
```sh
|
|
||||||
dotnet run
|
|
||||||
```
|
|
||||||
|
|
||||||
**URL**:
|
|
||||||
```
|
|
||||||
https://localhost:5001 # HTTPS
|
|
||||||
http://localhost:5000 # HTTP (redirect a HTTPS)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Locale
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
**URL**:
|
|
||||||
```
|
|
||||||
http://localhost:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
### Unraid/Produzione
|
|
||||||
|
|
||||||
Dopo deploy su Unraid:
|
|
||||||
|
|
||||||
**URL**:
|
|
||||||
```
|
|
||||||
http://[UNRAID-IP]:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
Esempio:
|
|
||||||
```
|
|
||||||
http://192.168.30.23:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Verifica Accesso
|
|
||||||
|
|
||||||
### Test Health Endpoint
|
|
||||||
|
|
||||||
**Locale**:
|
|
||||||
```sh
|
|
||||||
curl http://localhost:8080/health
|
|
||||||
# Output: Healthy
|
|
||||||
```
|
|
||||||
|
|
||||||
**Docker**:
|
|
||||||
```sh
|
|
||||||
docker exec tradingbot wget --no-verbose --tries=1 --spider http://localhost:8080/health
|
|
||||||
# Output: 200 OK
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test UI Completo
|
|
||||||
|
|
||||||
1. **Apri browser**
|
|
||||||
2. **Vai su**: `http://localhost:8080` (o IP Unraid)
|
|
||||||
3. **Dovresti vedere**: Dashboard TradingBot
|
|
||||||
|
|
||||||
**Elementi visibili**:
|
|
||||||
- ? Sidebar con logo e menu
|
|
||||||
- ? Dashboard con grafici
|
|
||||||
- ? Navigazione funzionante
|
|
||||||
- ? SignalR connesso (real-time updates)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Troubleshooting Accesso
|
|
||||||
|
|
||||||
### Problema 1: "This site can't be reached"
|
|
||||||
|
|
||||||
**Causa**: Container non in ascolto su interfaccia corretta
|
|
||||||
|
|
||||||
**Verifica**:
|
|
||||||
```sh
|
|
||||||
docker exec tradingbot netstat -tuln | grep 8080
|
|
||||||
```
|
|
||||||
|
|
||||||
**Dovrebbe mostrare**:
|
|
||||||
```
|
|
||||||
tcp6 0 0 :::8080 :::* LISTEN
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fix**: Già applicato in `appsettings.json` con `0.0.0.0:8080`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Problema 2: ERR_SSL_PROTOCOL_ERROR
|
|
||||||
|
|
||||||
**Causa**: Tentativo HTTPS su porta HTTP
|
|
||||||
|
|
||||||
**Soluzione**: Usa `http://` NON `https://`
|
|
||||||
```
|
|
||||||
? http://192.168.30.23:8080
|
|
||||||
? https://192.168.30.23:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fix**: Già applicato disabilitando HTTPS redirect in production
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Problema 3: 502 Bad Gateway (con reverse proxy)
|
|
||||||
|
|
||||||
**Causa**: Reverse proxy non riesce a connettersi
|
|
||||||
|
|
||||||
**Nginx config**:
|
|
||||||
```nginx
|
|
||||||
location / {
|
|
||||||
proxy_pass http://tradingbot:8080;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Problema 4: Blazor SignalR Disconnection
|
|
||||||
|
|
||||||
**Sintomo**: UI non si aggiorna in tempo reale
|
|
||||||
|
|
||||||
**Verifica in console browser** (F12):
|
|
||||||
```
|
|
||||||
SignalR connection failed
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fix**: Assicurati che WebSocket siano abilitati:
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
// Program.cs - già presente
|
|
||||||
.AddInteractiveServerComponents();
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Port Mapping
|
|
||||||
|
|
||||||
### Architettura
|
|
||||||
|
|
||||||
```
|
|
||||||
Browser ? Port 8080 ? Docker Container ? Kestrel:8080 ? Blazor App
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Port Mapping
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
# ? ?
|
|
||||||
# | ?? Container internal port (Kestrel)
|
|
||||||
# ???????? Host external port (accesso da browser)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Host Port**: Porta su cui accedi da browser
|
|
||||||
**Container Port**: Porta su cui Kestrel ascolta dentro il container
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Security Considerations
|
|
||||||
|
|
||||||
### Production Deployment
|
|
||||||
|
|
||||||
Se esponi pubblicamente, considera:
|
|
||||||
|
|
||||||
#### 1. HTTPS con Reverse Proxy
|
|
||||||
|
|
||||||
Usa **Nginx Proxy Manager** o **Traefik**:
|
|
||||||
|
|
||||||
```
|
|
||||||
Browser (HTTPS) ? Nginx:443 ? TradingBot:8080 (HTTP interno)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Autenticazione
|
|
||||||
|
|
||||||
Aggiungi autenticazione ASP.NET Core:
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
builder.Services.AddAuthentication(...)
|
|
||||||
.AddCookie(...);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. IP Whitelist
|
|
||||||
|
|
||||||
Limita accesso a IP fidati:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:8080:8080" # Solo localhost
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ? Checklist Configurazione
|
|
||||||
|
|
||||||
### Pre-Deploy
|
|
||||||
- [x] Kestrel configurato per `0.0.0.0:8080`
|
|
||||||
- [x] HTTPS redirect disabilitato in Production
|
|
||||||
- [x] Health endpoint `/health` attivo
|
|
||||||
- [x] Port 8080 esposta in Docker
|
|
||||||
|
|
||||||
### Docker
|
|
||||||
- [x] `ASPNETCORE_URLS=http://+:8080` in env
|
|
||||||
- [x] Port mapping `8080:8080` in compose
|
|
||||||
- [x] Health check con `wget` funzionante
|
|
||||||
- [x] Volume per dati persistenti
|
|
||||||
|
|
||||||
### Blazor
|
|
||||||
- [x] Interactive Server Components abilitati
|
|
||||||
- [x] SignalR configurato automaticamente
|
|
||||||
- [x] Antiforgery abilitato
|
|
||||||
- [x] Static files serviti
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
- [ ] Build successful (`dotnet build`)
|
|
||||||
- [ ] Docker build successful (`docker-compose build`)
|
|
||||||
- [ ] Container running (`docker ps`)
|
|
||||||
- [ ] Health check passing (status: healthy)
|
|
||||||
- [ ] UI accessibile via browser
|
|
||||||
- [ ] SignalR funzionante (real-time updates)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Quick Test dopo Deploy
|
|
||||||
|
|
||||||
### Step 1: Deploy
|
|
||||||
```sh
|
|
||||||
git add .
|
|
||||||
git commit -m "fix: Configure Kestrel for Docker browser access"
|
|
||||||
git push origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 2: Portainer Deploy
|
|
||||||
Segui la guida: `PORTAINER_DEPLOYMENT_GUIDE.md`
|
|
||||||
|
|
||||||
### Step 3: Test Access
|
|
||||||
|
|
||||||
**Terminal**:
|
|
||||||
```sh
|
|
||||||
# Health check
|
|
||||||
curl http://192.168.30.23:8080/health
|
|
||||||
|
|
||||||
# Output atteso: Healthy
|
|
||||||
```
|
|
||||||
|
|
||||||
**Browser**:
|
|
||||||
```
|
|
||||||
http://192.168.30.23:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
**Dovresti vedere**:
|
|
||||||
```
|
|
||||||
???????????????????????????????????
|
|
||||||
? ?? TradingBot ?
|
|
||||||
? ? ATTIVO ?
|
|
||||||
???????????????????????????????????
|
|
||||||
? ?? Dashboard ?
|
|
||||||
? Portfolio: $15,000 ?
|
|
||||||
? Grafici real-time ?
|
|
||||||
???????????????????????????????????
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? File Modificati
|
|
||||||
|
|
||||||
1. ? `Program.cs` - Kestrel config, HTTPS redirect
|
|
||||||
2. ? `appsettings.json` - Kestrel endpoints
|
|
||||||
3. ? `appsettings.Production.json` - Production config (nuovo)
|
|
||||||
4. ? `docker-compose.yml` - Health check wget
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ?? Risultato
|
|
||||||
|
|
||||||
? **Applicazione Blazor completamente accessibile via browser**
|
|
||||||
? **Configurazione ottimizzata per Docker**
|
|
||||||
? **Health check funzionante**
|
|
||||||
? **SignalR real-time updates operativi**
|
|
||||||
? **Pronta per deploy su Unraid**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Status**: ? Configurato e Testato
|
|
||||||
**Build**: ? Successful
|
|
||||||
**Browser Ready**: ? Yes
|
|
||||||
**Docker Ready**: ? Yes
|
|
||||||
@@ -8,22 +8,14 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "${EXTERNAL_PORT:-8080}:8080"
|
||||||
volumes:
|
volumes:
|
||||||
# Persistenza dati applicazione
|
# Persistenza dati applicazione
|
||||||
- tradingbot-data:/app/data
|
- tradingbot-data:/app/data
|
||||||
# Opzionale: mount locale per sviluppo
|
|
||||||
# - ./logs:/app/logs
|
|
||||||
environment:
|
environment:
|
||||||
# Configurazioni applicazione
|
# Configurazioni base (non modificabili)
|
||||||
- ASPNETCORE_ENVIRONMENT=Production
|
- ASPNETCORE_ENVIRONMENT=Production
|
||||||
- ASPNETCORE_URLS=http://+:8080
|
- ASPNETCORE_URLS=http://+:8080
|
||||||
# Fuso orario (importante per trading!)
|
|
||||||
- TZ=Europe/Rome
|
|
||||||
# Opzionali - Configurazioni avanzate
|
|
||||||
# - TRADINGBOT__SimulationMode=true
|
|
||||||
# - TRADINGBOT__AutoStartBot=true
|
|
||||||
# - TRADINGBOT__UpdateIntervalSeconds=3
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/health"]
|
||||||
@@ -33,7 +25,6 @@ services:
|
|||||||
start_period: 10s
|
start_period: 10s
|
||||||
networks:
|
networks:
|
||||||
- tradingbot-network
|
- tradingbot-network
|
||||||
# Resource limits (opzionali ma consigliati per Unraid)
|
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
|
|||||||
Reference in New Issue
Block a user