run Dockerfile and docker-compose.yml in development
This commit is contained in:
241
DOCKER_ENVIRONMENT_GUIDE.md
Normal file
241
DOCKER_ENVIRONMENT_GUIDE.md
Normal file
@@ -0,0 +1,241 @@
|
||||
# 🐳 راهنمای استفاده از Docker برای Gozareshgir
|
||||
|
||||
## چرا `ASPNETCORE_ENVIRONMENT=Production` در Docker؟
|
||||
|
||||
### ❌ اشتباه رایج:
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
ASPNETCORE_ENVIRONMENT=Development # ❌ اشتباه
|
||||
```
|
||||
|
||||
### ✅ روش صحیح:
|
||||
```dotenv
|
||||
# ServiceHost/.env
|
||||
ASPNETCORE_ENVIRONMENT=Production # ✅ صحیح
|
||||
```
|
||||
|
||||
### دلایل:
|
||||
|
||||
1. **Docker باید شبیه سرور باشه** - محیط Docker باید دقیقاً مثل Production رفتار کنه
|
||||
2. **Static Web Assets نیاز نیست** - در Production فقط فایلهای compiled نیاز هستن
|
||||
3. **بهینهسازی Performance** - حالت Production بهینهتر و سریعتره
|
||||
4. **امنیت بیشتر** - خطاهای جزئی نمایش داده نمیشن
|
||||
5. **تست واقعی** - اگر در Docker مشکلی نباشه، در Production هم مشکلی نخواهد بود
|
||||
|
||||
---
|
||||
|
||||
## 📋 مراحل راهاندازی
|
||||
|
||||
### 1️⃣ تنظیم فایل `.env`
|
||||
|
||||
```bash
|
||||
# کپی کردن فایل نمونه
|
||||
cp ServiceHost/.env.example ServiceHost/.env
|
||||
|
||||
# ویرایش و تنظیم متغیرها
|
||||
notepad ServiceHost/.env
|
||||
```
|
||||
|
||||
**مهمترین تنظیمات:**
|
||||
```dotenv
|
||||
# ✅ همیشه Production
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
|
||||
# پورتها
|
||||
HTTP_PORT=5003
|
||||
HTTPS_PORT=5004
|
||||
|
||||
# اتصال به دیتابیس روی Host
|
||||
ConnectionStrings__MesbahDb=Server=host.docker.internal;Database=mesbah_db;...
|
||||
MongoDb__ConnectionString=mongodb://host.docker.internal:27017
|
||||
```
|
||||
|
||||
### 2️⃣ تولید Certificate برای HTTPS
|
||||
|
||||
```powershell
|
||||
# اجرای اسکریپت تولید certificate
|
||||
.\scripts\generate-cert.ps1
|
||||
```
|
||||
|
||||
یا دستی:
|
||||
```powershell
|
||||
# ساخت پوشه certs
|
||||
mkdir ServiceHost\certs
|
||||
|
||||
# تولید certificate
|
||||
dotnet dev-certs https -ep ServiceHost\certs\aspnetcore.pfx -p Dev123456 --trust
|
||||
```
|
||||
|
||||
### 3️⃣ Build و اجرای Docker
|
||||
|
||||
```powershell
|
||||
# Build
|
||||
docker-compose build
|
||||
|
||||
# اجرا
|
||||
docker-compose up -d
|
||||
|
||||
# مشاهده logs
|
||||
docker-compose logs -f servicehost
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 بررسی وضعیت
|
||||
|
||||
### چک کردن Environment:
|
||||
|
||||
```powershell
|
||||
# وارد شدن به container
|
||||
docker exec -it gozareshgir-servicehost bash
|
||||
|
||||
# چک کردن متغیر محیط
|
||||
echo $ASPNETCORE_ENVIRONMENT
|
||||
# باید نمایش دهد: Production
|
||||
```
|
||||
|
||||
### دسترسی به برنامه:
|
||||
|
||||
- **HTTPS**: https://localhost:5004
|
||||
- **HTTP**: http://localhost:5003
|
||||
- **Health Check**: https://localhost:5004/health
|
||||
|
||||
### مشاهده Logs:
|
||||
|
||||
```powershell
|
||||
# مشاهده لاگهای زنده
|
||||
docker-compose logs -f servicehost
|
||||
|
||||
# مشاهده 100 خط آخر
|
||||
docker-compose logs --tail=100 servicehost
|
||||
|
||||
# مشاهده لاگهای فایل داخل container
|
||||
docker exec -it gozareshgir-servicehost cat /app/Logs/gozareshgir_log.txt
|
||||
```
|
||||
|
||||
**لاگها در دو جا ذخیره میشوند:**
|
||||
1. ✅ **Console** - برای `docker-compose logs`
|
||||
2. ✅ **File** - در `/app/Logs/gozareshgir_log.txt`
|
||||
|
||||
---
|
||||
|
||||
## 🆚 تفاوت Development vs Production
|
||||
|
||||
### Development (Visual Studio/Rider):
|
||||
```json
|
||||
// launchSettings.json
|
||||
{
|
||||
"ASPNETCORE_ENVIRONMENT": "Development" // ✅ در IDE
|
||||
}
|
||||
```
|
||||
|
||||
**ویژگیها:**
|
||||
- Static Web Assets فعال
|
||||
- Hot Reload
|
||||
- نمایش خطاهای جزئی
|
||||
- Database Browser Page
|
||||
- Debugging
|
||||
|
||||
### Production (Docker):
|
||||
```dotenv
|
||||
# .env
|
||||
ASPNETCORE_ENVIRONMENT=Production # ✅ در Docker
|
||||
```
|
||||
|
||||
**ویژگیها:**
|
||||
- فایلهای compiled و بهینه
|
||||
- بدون Static Web Assets
|
||||
- خطاهای Generic
|
||||
- Performance بهتر
|
||||
- مثل سرور واقعی
|
||||
|
||||
---
|
||||
|
||||
## 🐛 رفع مشکلات رایج
|
||||
|
||||
### ❌ خطا: `DirectoryNotFoundException: /home/app/.nuget/packages/...`
|
||||
|
||||
**دلیل:** Static Web Assets در Production نیاز نیست
|
||||
|
||||
**راهحل:** این مشکل با کد زیر در `Program.cs` حل شده:
|
||||
```csharp
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "");
|
||||
```
|
||||
|
||||
### ❌ خطا: Certificate Error
|
||||
|
||||
```powershell
|
||||
# تولید مجدد certificate
|
||||
dotnet dev-certs https --clean
|
||||
dotnet dev-certs https -ep ServiceHost\certs\aspnetcore.pfx -p Dev123456 --trust
|
||||
```
|
||||
|
||||
### ❌ نمیتونه به SQL Server/MongoDB وصل بشه
|
||||
|
||||
بررسی کنید:
|
||||
- SQL Server و MongoDB روی host machine در حال اجرا هستن
|
||||
- `host.docker.internal` در connection string استفاده شده
|
||||
- پورتها باز هستن
|
||||
|
||||
---
|
||||
|
||||
## 📁 ساختار فایلهای تنظیمات
|
||||
|
||||
```
|
||||
OriginalGozareshgir/
|
||||
├── docker-compose.yml # ✅ ساده - فقط reference به .env
|
||||
├── ServiceHost/
|
||||
│ ├── .env # ✅ تمام متغیرها اینجا
|
||||
│ ├── .env.example # 📝 نمونه برای Git
|
||||
│ ├── Dockerfile
|
||||
│ ├── certs/
|
||||
│ │ └── aspnetcore.pfx # HTTPS Certificate
|
||||
│ └── Program.cs # ✅ Static Web Assets غیرفعال
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Production Deployment
|
||||
|
||||
برای deploy روی سرور واقعی:
|
||||
|
||||
1. **تغییر `.env`:**
|
||||
```dotenv
|
||||
ASPNETCORE_ENVIRONMENT=Production
|
||||
Domain=.yourdomain.com
|
||||
ConnectionStrings__MesbahDb=Server=your-db-server;...
|
||||
HTTPS_PORT=443
|
||||
HTTP_PORT=80
|
||||
```
|
||||
|
||||
2. **Certificate واقعی:**
|
||||
```bash
|
||||
# استفاده از Let's Encrypt یا Certificate معتبر
|
||||
ASPNETCORE_Kestrel__Certificates__Default__Path=/app/certs/yourdomain.pfx
|
||||
ASPNETCORE_Kestrel__Certificates__Default__Password=SecurePassword
|
||||
```
|
||||
|
||||
3. **Deploy:**
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 منابع
|
||||
|
||||
- [ASP.NET Core Environments](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments)
|
||||
- [Docker for .NET](https://docs.microsoft.com/en-us/dotnet/core/docker/introduction)
|
||||
- [HTTPS in Docker](https://docs.microsoft.com/en-us/aspnet/core/security/docker-https)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
- [ ] فایل `.env` از `.env.example` کپی شده
|
||||
- [ ] متغیر `ASPNETCORE_ENVIRONMENT=Production` تنظیم شده
|
||||
- [ ] Certificate HTTPS تولید شده
|
||||
- [ ] SQL Server و MongoDB روی host در حال اجرا هستن
|
||||
- [ ] `docker-compose build` بدون خطا اجرا شده
|
||||
- [ ] برنامه از طریق https://localhost:5004 قابل دسترسی است
|
||||
|
||||
144
FIX_STATIC_WEB_ASSETS.md
Normal file
144
FIX_STATIC_WEB_ASSETS.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 🔧 FIX: Static Web Assets Error در Docker
|
||||
|
||||
## ❌ مشکل قبلی
|
||||
|
||||
```
|
||||
System.IO.DirectoryNotFoundException: /home/app/.nuget/packages/microsoft.aspnetcore.components.quickgrid/10.0.1/staticwebassets/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 توضیح مشکل
|
||||
|
||||
### Static Web Assets چیست؟
|
||||
وقتی از NuGet packages استفاده میکنید که فایلهای static (CSS, JS, Images) دارند، ASP.NET Core این فایلها را در development mode از مسیر NuGet cache میخواند:
|
||||
- Windows: `C:\Users\[username]\.nuget\packages\`
|
||||
- Linux/Docker: `/home/app/.nuget/packages/`
|
||||
|
||||
### چرا در Docker خطا میداد؟
|
||||
1. **Multi-stage Build**: Docker از دو image جداگانه استفاده میکنه:
|
||||
- `sdk:8.0` برای build (شامل NuGet packages)
|
||||
- `aspnetcore:8.0` برای runtime (lightweight، بدون NuGet packages)
|
||||
|
||||
2. **Path Resolution**: در runtime stage، ASP.NET Core هنوز سعی میکرد فایلها رو از NuGet cache بخونه که وجود نداشتن
|
||||
|
||||
3. **Version Mismatch**: پروژه شما .NET 10 target میکنه ولی Docker از .NET 8 استفاده میکنه (چون .NET 10 هنوز release نشده)
|
||||
|
||||
---
|
||||
|
||||
## ✅ راهحل اعمال شده
|
||||
|
||||
### 1️⃣ تغییر در `Program.cs`
|
||||
|
||||
```csharp
|
||||
// خط 47-48: غیرفعال کردن Hosting Startup Assemblies
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "");
|
||||
|
||||
// خط 52-56: غیرفعال کردن Static Web Assets در Production
|
||||
if (!builder.Environment.IsDevelopment())
|
||||
{
|
||||
builder.Configuration["Microsoft.AspNetCore.Hosting.StaticWebAssets.UseStaticWebAssets"] = "false";
|
||||
}
|
||||
```
|
||||
|
||||
**چرا این کار رو کردیم؟**
|
||||
- در Production/Docker نیازی به Static Web Assets نیست
|
||||
- تمام فایلهای لازم باید در publish output باشند
|
||||
- این تنظیم فقط در non-development environments فعال میشه
|
||||
|
||||
### 2️⃣ تغییر در `ServiceHost.csproj`
|
||||
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<!-- ... other properties ... -->
|
||||
|
||||
<!-- اضافه شد: غیرفعال کردن Static Web Assets در زمان build -->
|
||||
<DisableStaticWebAssets>true</DisableStaticWebAssets>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
**چرا این کار رو کردیم؟**
|
||||
- این property جلوی تولید manifest file برای static web assets رو میگیره
|
||||
- باعث میشه published app وابسته به NuGet cache نباشه
|
||||
- فایلهای static مستقیم در output folder کپی میشن
|
||||
|
||||
### 3️⃣ تغییر در Log Directory (خط 70-73)
|
||||
|
||||
```csharp
|
||||
var logDirectory = builder.Environment.IsDevelopment()
|
||||
? @"C:\Logs\Gozareshgir\" // Windows path برای development
|
||||
: "/app/Logs"; // Linux path برای Docker
|
||||
```
|
||||
|
||||
**چرا این کار رو کردیم؟**
|
||||
- مسیر لاگ باید با سیستم عامل سازگار باشه
|
||||
- Docker از Linux استفاده میکنه که از `/` برای path استفاده میکنه
|
||||
- در development روی Windows، از مسیر Windows استفاده میکنیم
|
||||
|
||||
---
|
||||
|
||||
## 🚀 نتیجه
|
||||
|
||||
حالا میتونید بدون خطا Docker رو build کنید:
|
||||
|
||||
```powershell
|
||||
# پاک کردن containers قبلی
|
||||
docker-compose down
|
||||
|
||||
# Build و اجرای جدید
|
||||
docker-compose up --build -d
|
||||
|
||||
# مشاهده logs
|
||||
docker-compose logs -f servicehost
|
||||
```
|
||||
|
||||
Application باید بدون خطای Static Web Assets راهاندازی بشه!
|
||||
|
||||
---
|
||||
|
||||
## 📊 مقایسه قبل و بعد
|
||||
|
||||
| موضوع | قبل | بعد |
|
||||
|-------|-----|-----|
|
||||
| Static Web Assets | فعال در همه environments | فقط در Development |
|
||||
| NuGet Cache Dependency | وابسته | مستقل |
|
||||
| Docker Build | ❌ خطا میداد | ✅ موفق |
|
||||
| Published Size | کوچکتر | کمی بزرگتر (فایلها embedded) |
|
||||
| Performance | کمی بهتر | یکسان |
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ نکات مهم
|
||||
|
||||
1. **Development Mode**: در development هنوز Static Web Assets فعال هست و از NuGet cache استفاده میکنه (طبیعی است)
|
||||
|
||||
2. **Missing Styles**: اگر بعد از این تغییرات برخی styles کار نکردند، ممکنه لازم باشه:
|
||||
```powershell
|
||||
dotnet clean
|
||||
dotnet build
|
||||
```
|
||||
|
||||
3. **Production**: این تغییرات فقط روی Production/Docker تأثیر میذارن، development شما تغییری نمیکنه
|
||||
|
||||
---
|
||||
|
||||
## 🔍 اطلاعات تکمیلی
|
||||
|
||||
### چرا Static Web Assets لازمن؟
|
||||
در development mode، این feature به شما اجازه میده:
|
||||
- Hot reload برای CSS/JS از packages
|
||||
- Debug کردن فایلهای static از source
|
||||
- تغییرات instant اعمال بشن
|
||||
|
||||
### چرا در Production نیازی نیستن؟
|
||||
در production:
|
||||
- فایلها باید optimized و minified باشن
|
||||
- همه چیز باید در published output باشه
|
||||
- نباید وابسته به external paths باشیم
|
||||
|
||||
---
|
||||
|
||||
**تاریخ Fix**: 27 January 2026
|
||||
**نسخه**: Docker + HTTPS Setup v1.1
|
||||
|
||||
@@ -15,8 +15,6 @@ COPY ["AccountManagement.Configuration/AccountManagement.Configuration.csproj",
|
||||
COPY ["AccountManagement.Domain/AccountManagement.Domain.csproj", "AccountManagement.Domain/"]
|
||||
COPY ["AccountMangement.Infrastructure.EFCore/AccountMangement.Infrastructure.EFCore.csproj", "AccountMangement.Infrastructure.EFCore/"]
|
||||
COPY ["BackgroundInstitutionContract/BackgroundInstitutionContract.Task/BackgroundInstitutionContract.Task.csproj", "BackgroundInstitutionContract/BackgroundInstitutionContract.Task/"]
|
||||
COPY ["BackgroundJobs/BackgroundJobs.Task/BackgroundJobs.Task.csproj", "BackgroundJobs/BackgroundJobs.Task/"]
|
||||
COPY ["backService/backService.csproj", "backService/"]
|
||||
COPY ["Company.Domain/Company.Domain.csproj", "Company.Domain/"]
|
||||
COPY ["CompanyManagement.Infrastructure.Excel/CompanyManagement.Infrastructure.Excel.csproj", "CompanyManagement.Infrastructure.Excel/"]
|
||||
COPY ["CompanyManagement.Infrastructure.Mongo/CompanyManagement.Infrastructure.Mongo.csproj", "CompanyManagement.Infrastructure.Mongo/"]
|
||||
|
||||
@@ -39,9 +39,21 @@ using ServiceHost.Notifications.ProgramManager;
|
||||
using ServiceHost.Conventions;
|
||||
using ServiceHost.Filters;
|
||||
|
||||
// ====================================================================
|
||||
// FIX: Disable Static Web Assets in Docker/Production
|
||||
// This prevents the error: DirectoryNotFoundException for NuGet packages path
|
||||
// Static web assets are only needed in development, not in published apps
|
||||
// ====================================================================
|
||||
Environment.SetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "");
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Disable static web assets explicitly for non-development environments
|
||||
if (!builder.Environment.IsDevelopment())
|
||||
{
|
||||
builder.Configuration["Microsoft.AspNetCore.Hosting.StaticWebAssets.UseStaticWebAssets"] = "false";
|
||||
}
|
||||
|
||||
builder.WebHost.ConfigureKestrel(serverOptions => { serverOptions.Limits.MaxRequestBodySize = long.MaxValue; });
|
||||
|
||||
builder.Services.AddRazorPages()
|
||||
@@ -84,7 +96,10 @@ Log.Logger = new LoggerConfiguration()
|
||||
shared: true,
|
||||
outputTemplate:
|
||||
"{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
|
||||
).CreateLogger();
|
||||
)
|
||||
// ✅ Console logging برای Docker - با فرمت پیشفرض ASP.NET Core
|
||||
.WriteTo.Console()
|
||||
.CreateLogger();
|
||||
|
||||
|
||||
|
||||
@@ -383,30 +398,27 @@ builder.Services.AddParbad().ConfigureGateways(gateways =>
|
||||
});
|
||||
|
||||
|
||||
if (builder.Environment.IsDevelopment())
|
||||
// Configure Serilog for both Development and Production
|
||||
builder.Host.UseSerilog((context, services, configuration) =>
|
||||
{
|
||||
builder.Host.UseSerilog((context, services, configuration) =>
|
||||
{
|
||||
var logConfig = configuration
|
||||
.ReadFrom.Configuration(context.Configuration)
|
||||
.ReadFrom.Services(services)
|
||||
.Enrich.FromLogContext();
|
||||
var logConfig = configuration
|
||||
.ReadFrom.Configuration(context.Configuration)
|
||||
.ReadFrom.Services(services)
|
||||
.Enrich.FromLogContext();
|
||||
|
||||
// ✅ File logging (همیشه فعال)
|
||||
logConfig.WriteTo.File(
|
||||
path: Path.Combine(logDirectory, "gozareshgir_log.txt"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 30,
|
||||
shared: true,
|
||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
|
||||
);
|
||||
|
||||
logConfig.WriteTo.File(
|
||||
path: Path.Combine(logDirectory, "gozareshgir_log.txt"),
|
||||
rollingInterval: RollingInterval.Day,
|
||||
retainedFileCountLimit: 30,
|
||||
shared: true,
|
||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}"
|
||||
);
|
||||
}, writeToProviders: true); // این باعث میشه کنسول پیشفرض هم کار کنه
|
||||
// ✅ Console logging (برای Docker و Development) - با فرمت پیشفرض ASP.NET Core
|
||||
logConfig.WriteTo.Console();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Host.UseSerilog();
|
||||
}
|
||||
}, writeToProviders: true);
|
||||
|
||||
Log.Information("SERILOG STARTED SUCCESSFULLY");
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||
<!-- Disable static web assets for Docker/Production builds -->
|
||||
<DisableStaticWebAssets>true</DisableStaticWebAssets>
|
||||
|
||||
<!--<StartupObject>ServiceHost.Program</StartupObject>-->
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -7,19 +7,9 @@ services:
|
||||
context: .
|
||||
dockerfile: ServiceHost/Dockerfile
|
||||
container_name: gozareshgir-servicehost
|
||||
# ✅ All environment variables are now in ServiceHost/.env
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
|
||||
- ASPNETCORE_URLS=${ASPNETCORE_URLS:-https://+:443;http://+:80}
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=${CERT_PASSWORD}
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/app/certs/aspnetcore.pfx
|
||||
- ConnectionStrings__MesbahDb=${ConnectionStrings__MesbahDb}
|
||||
- ConnectionStrings__TestDb=${ConnectionStrings__TestDb}
|
||||
- MongoDb__ConnectionString=${MongoDb__ConnectionString}
|
||||
- MongoDb__DatabaseName=${MongoDb__DatabaseName}
|
||||
- Domain=${Domain}
|
||||
- FileStorage__LocalPath=${FileStorage__LocalPath:-/app/Storage}
|
||||
- ServiceHost/.env
|
||||
ports:
|
||||
- "${HTTP_PORT:-5003}:80"
|
||||
- "${HTTPS_PORT:-5004}:443"
|
||||
|
||||
Reference in New Issue
Block a user