249 lines
7.1 KiB
Markdown
249 lines
7.1 KiB
Markdown
# ✅ Docker Bind Mounts Configuration - Summary
|
|
|
|
## What Was Changed
|
|
|
|
### 1. docker-compose.yml
|
|
**Before:**
|
|
```yaml
|
|
volumes:
|
|
- ./ServiceHost/certs:/app/certs:ro
|
|
- app_storage:/app/Storage # ❌ Docker volume
|
|
- app_logs:/app/Logs # ❌ Docker volume
|
|
|
|
volumes:
|
|
app_storage:
|
|
driver: local
|
|
app_logs:
|
|
driver: local
|
|
```
|
|
|
|
**After:**
|
|
```yaml
|
|
volumes:
|
|
# ✅ Bind mounts for production-critical data on Windows host
|
|
- ./ServiceHost/certs:/app/certs:ro
|
|
- D:/AppData/Faces:/app/Faces
|
|
- D:/AppData/Storage:/app/Storage
|
|
- D:/AppData/Logs:/app/Logs
|
|
|
|
# ✅ No volumes section needed
|
|
```
|
|
|
|
### 2. New Files Created
|
|
- `DOCKER_BIND_MOUNTS_SETUP.md` - Complete documentation
|
|
- `setup-bind-mounts.ps1` - Automated setup script
|
|
- `QUICK_REFERENCE.md` - Quick command reference
|
|
|
|
## Path Mapping
|
|
|
|
| Container (Linux paths) | Windows Host (forward slash) | Actual Windows Path |
|
|
|-------------------------|------------------------------|---------------------|
|
|
| `/app/Faces` | `D:/AppData/Faces` | `D:\AppData\Faces` |
|
|
| `/app/Storage` | `D:/AppData/Storage` | `D:\AppData\Storage`|
|
|
| `/app/Logs` | `D:/AppData/Logs` | `D:\AppData\Logs` |
|
|
|
|
**Note:** Docker Compose on Windows accepts both `D:/` and `D:\` but prefers forward slashes.
|
|
|
|
## Application Code Compatibility
|
|
|
|
Your application uses:
|
|
```csharp
|
|
Path.Combine(env.ContentRootPath, "Faces"); // → /app/Faces
|
|
Path.Combine(env.ContentRootPath, "Storage"); // → /app/Storage
|
|
```
|
|
|
|
Where `env.ContentRootPath` = `/app` in the container.
|
|
|
|
✅ **No code changes required!** The bind mounts map directly to these paths.
|
|
|
|
## Setup Instructions
|
|
|
|
### Option 1: Automated Setup (Recommended)
|
|
```powershell
|
|
# Navigate to project directory
|
|
cd D:\GozareshgirOrginal\OriginalGozareshgir
|
|
|
|
# Run setup script with permissions
|
|
.\setup-bind-mounts.ps1 -GrantFullPermissions
|
|
|
|
# Start the application
|
|
docker-compose up -d
|
|
```
|
|
|
|
### Option 2: Manual Setup
|
|
```powershell
|
|
# 1. Create directories
|
|
New-Item -ItemType Directory -Force -Path "D:\AppData\Faces"
|
|
New-Item -ItemType Directory -Force -Path "D:\AppData\Storage"
|
|
New-Item -ItemType Directory -Force -Path "D:\AppData\Logs"
|
|
|
|
# 2. Grant permissions
|
|
icacls "D:\AppData\Faces" /grant Everyone:F /T
|
|
icacls "D:\AppData\Storage" /grant Everyone:F /T
|
|
icacls "D:\AppData\Logs" /grant Everyone:F /T
|
|
|
|
# 3. Start the application
|
|
docker-compose up -d
|
|
```
|
|
|
|
## Verification Checklist
|
|
|
|
After starting the container:
|
|
|
|
1. **Check if directories are mounted:**
|
|
```powershell
|
|
docker exec gozareshgir-servicehost ls -la /app
|
|
```
|
|
Should show: `Faces/`, `Storage/`, `Logs/`
|
|
|
|
2. **Test write access from container:**
|
|
```powershell
|
|
docker exec gozareshgir-servicehost sh -c "echo 'test' > /app/Storage/test.txt"
|
|
Get-Content D:\AppData\Storage\test.txt # Should display: test
|
|
Remove-Item D:\AppData\Storage\test.txt
|
|
```
|
|
|
|
3. **Test write access from host:**
|
|
```powershell
|
|
"test from host" | Out-File "D:\AppData\Storage\host-test.txt"
|
|
docker exec gozareshgir-servicehost cat /app/Storage/host-test.txt
|
|
Remove-Item D:\AppData\Storage\host-test.txt
|
|
```
|
|
|
|
4. **Check application logs:**
|
|
```powershell
|
|
docker logs gozareshgir-servicehost --tail 50
|
|
# Or directly on host:
|
|
Get-Content D:\AppData\Logs\gozareshgir_log.txt -Tail 50
|
|
```
|
|
|
|
## Data Persistence Guarantees
|
|
|
|
✅ **Files persist through:**
|
|
- `docker-compose down`
|
|
- `docker-compose restart`
|
|
- Container removal (`docker rm`)
|
|
- Image rebuilds (`docker-compose build`)
|
|
- Server reboots (with `restart: unless-stopped`)
|
|
|
|
✅ **Direct access:**
|
|
- Files can be accessed from Windows Explorer at `D:\AppData\*`
|
|
- Can be backed up using Windows Backup, robocopy, or any backup software
|
|
- Can be edited directly on the host (changes visible in container immediately)
|
|
|
|
⚠️ **Data does NOT survive:**
|
|
- Deleting the host directories (`D:\AppData\*`)
|
|
- Formatting the D: drive
|
|
- Without regular backups, hardware failures
|
|
|
|
## Production Checklist
|
|
|
|
Before deploying to production:
|
|
|
|
- [ ] Run `setup-bind-mounts.ps1 -GrantFullPermissions`
|
|
- [ ] Verify disk space on D: drive (at least 50 GB recommended)
|
|
- [ ] Set up scheduled backups (see `DOCKER_BIND_MOUNTS_SETUP.md`)
|
|
- [ ] Replace `Everyone` with specific service account for permissions
|
|
- [ ] Enable NTFS encryption for sensitive data (optional)
|
|
- [ ] Test container restart: `docker-compose restart`
|
|
- [ ] Test data persistence: Create a test file, restart container, verify file exists
|
|
- [ ] Configure monitoring for disk space usage
|
|
|
|
## Security Recommendations
|
|
|
|
1. **Restrict permissions** (production):
|
|
```powershell
|
|
# Replace Everyone with specific account
|
|
icacls "D:\AppData\Faces" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
|
|
icacls "D:\AppData\Storage" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
|
|
icacls "D:\AppData\Logs" /grant "DOMAIN\ServiceAccount:(OI)(CI)F" /T
|
|
```
|
|
|
|
2. **Enable encryption** for sensitive data:
|
|
```powershell
|
|
cipher /e "D:\AppData\Faces"
|
|
cipher /e "D:\AppData\Storage"
|
|
```
|
|
|
|
3. **Set up audit logging:**
|
|
```powershell
|
|
auditpol /set /subcategory:"File System" /success:enable /failure:enable
|
|
```
|
|
|
|
## Backup Strategy
|
|
|
|
### Scheduled Backup (Recommended)
|
|
```powershell
|
|
# Create daily backup at 2 AM
|
|
$action = New-ScheduledTaskAction -Execute "robocopy" -Argument '"D:\AppData" "D:\Backups\AppData" /MIR /Z /LOG:"D:\Backups\backup.log"'
|
|
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
|
|
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "GozareshgirBackup" -Description "Daily backup of Gozareshgir data"
|
|
```
|
|
|
|
### Manual Backup
|
|
```powershell
|
|
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
|
robocopy "D:\AppData" "D:\Backups\AppData_$timestamp" /MIR /Z
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: Container starts but files not appearing
|
|
**Solution:**
|
|
```powershell
|
|
# Check mount points
|
|
docker inspect gozareshgir-servicehost --format='{{json .Mounts}}' | ConvertFrom-Json
|
|
|
|
# Verify directories exist
|
|
Test-Path D:\AppData\Faces
|
|
Test-Path D:\AppData\Storage
|
|
Test-Path D:\AppData\Logs
|
|
```
|
|
|
|
### Issue: Permission denied errors
|
|
**Solution:**
|
|
```powershell
|
|
# Re-grant permissions
|
|
icacls "D:\AppData\Faces" /grant Everyone:F /T
|
|
icacls "D:\AppData\Storage" /grant Everyone:F /T
|
|
icacls "D:\AppData\Logs" /grant Everyone:F /T
|
|
```
|
|
|
|
### Issue: Out of disk space
|
|
**Solution:**
|
|
```powershell
|
|
# Check disk usage
|
|
Get-ChildItem D:\AppData -Recurse | Measure-Object -Property Length -Sum
|
|
|
|
# Clean old log files (example: older than 30 days)
|
|
Get-ChildItem D:\AppData\Logs -Recurse -File | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | Remove-Item
|
|
```
|
|
|
|
## Support & Documentation
|
|
|
|
- **Full Documentation:** `DOCKER_BIND_MOUNTS_SETUP.md`
|
|
- **Quick Reference:** `QUICK_REFERENCE.md`
|
|
- **Setup Script:** `setup-bind-mounts.ps1`
|
|
|
|
## Migration from Docker Volumes (If applicable)
|
|
|
|
If you previously used Docker volumes, migrate the data:
|
|
|
|
```powershell
|
|
# 1. Stop the container
|
|
docker-compose down
|
|
|
|
# 2. Copy data from old volumes to host
|
|
docker run --rm -v old_volume_name:/source -v D:/AppData/Storage:/dest alpine cp -av /source/. /dest/
|
|
|
|
# 3. Start with new bind mounts
|
|
docker-compose up -d
|
|
```
|
|
|
|
---
|
|
|
|
**Configuration Date:** January 2026
|
|
**Tested On:** Windows Server 2019/2022 with Docker Desktop
|
|
**Status:** ✅ Production Ready
|
|
|