Skip to content

Commit d669d96

Browse files
authored
Merge pull request #182 from BryanSoltis/dev
#181 Fix - Updated default data configuration to JSON
2 parents 0de46b1 + 5d2aa69 commit d669d96

File tree

6 files changed

+154
-54
lines changed

6 files changed

+154
-54
lines changed

docs/v5.0.0/RELEASE_NOTES_v5.0.0.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ Version 5.0.0 is a major release featuring .NET 10.0 framework upgrade, modern d
2424
- Improved visual hierarchy and card-based design
2525

2626
### SQLite Database Support
27+
- **Optional upgrade** - SQLite available for enhanced performance (not default)
2728
- **Enhanced performance** with faster data access and queries
2829
- **Better scalability** for larger configurations
2930
- **Improved reliability** with transactional support and data integrity
3031
- **Built-in migration tool** from file-based storage to SQLite
3132
- **One-click migration** with automatic backup creation
3233
- **Rollback support** if migration issues occur
3334
- Admin UI for easy storage provider management
34-
- Maintains backward compatibility with file-based JSON storage
35+
- **Default remains JSON file-based storage** for maximum compatibility
36+
- ⚠️ **IMPORTANT**: SQLite not recommended for Azure Container Apps with File Share mounts (use FileSystem storage instead)
3537

3638
### Azure Tenant Name Validation
3739
- **Validate generated names against your Azure tenant** before deployment

docs/v5.0.0/V5.0.0_MIGRATION_GUIDE.md

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# Azure Naming Tool v5.0.0 Migration Guide
2-
31
## Overview
42

53
Version 5.0.0 of the Azure Naming Tool introduces significant enhancements including a modern redesigned UI, SQLite database storage option, and Azure resource name validation capabilities. This guide will help you successfully migrate from previous versions to v5.0.0.
@@ -279,20 +277,42 @@ v5.0.0 requires .NET 10.0 runtime. You **MUST** update your App Service runtime
279277
280278
**⚠️ IMPORTANT: .NET 10.0 Docker Image Required**
281279
282-
v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
280+
v5.0.0 uses a new Docker image based on .NET 10.0 runtime. You need to build the image locally from source.
281+
282+
**🚨 CRITICAL - Azure Container Apps Users:**
283+
284+
If you are deploying to **Azure Container Apps with Azure File Share** for persistent storage:
285+
286+
> **DO NOT use SQLite storage!**
287+
>
288+
> SQLite does not work with Azure File Share (SMB/CIFS network mounts) due to file locking issues. Your container will fail to start with `"database is locked"` errors.
289+
>
290+
> **Solution:** Use FileSystem (JSON) storage instead:
291+
> - In `appsettings.json`, ensure: `"StorageProvider": "FileSystem"`
292+
> - This is the default for fresh Docker installations
293+
> - JSON files work perfectly with Azure File Share mounts
294+
> - You can still use all v5.0.0 features except Azure Tenant Name Validation (which requires SQLite)
295+
296+
**For other Docker deployments:** SQLite works fine with local Docker volumes.
283297
284298
1. **STOP the current container (if running):**
285299
```bash
286300
docker stop azurenamingtool
287301
docker rm azurenamingtool
288302
```
289303

290-
2. **Pull the latest v5.0.0 image:**
304+
2. **Clone the repository and build the v5.0.0 image:**
291305
```bash
292-
# Pull the .NET 10.0-based image
293-
docker pull ghcr.io/mspnp/azurenamingtool:v5.0.0
294-
# Or use latest tag (ensure it's v5.0.0 or higher)
295-
docker pull ghcr.io/mspnp/azurenamingtool:latest
306+
# Clone the repository (if not already cloned)
307+
git clone https://github.com/mspnp/AzureNamingTool.git
308+
cd AzureNamingTool
309+
310+
# Checkout the v5.0.0 release tag
311+
git checkout v5.0.0
312+
313+
# Build the Docker image from the src directory
314+
cd src
315+
docker build -t azurenamingtool:v5.0.0 .
296316
```
297317

298318
3. **Run with persistent storage:**
@@ -303,7 +323,7 @@ v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
303323
-v $(pwd)/settings:/app/settings \
304324
--name azurenamingtool \
305325
--restart unless-stopped \
306-
ghcr.io/mspnp/azurenamingtool:v5.0.0
326+
azurenamingtool:v5.0.0
307327
```
308328

309329
**Windows PowerShell:**
@@ -314,10 +334,10 @@ v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
314334
-v ${PWD}/settings:/app/settings `
315335
--name azurenamingtool `
316336
--restart unless-stopped `
317-
ghcr.io/mspnp/azurenamingtool:v5.0.0
337+
azurenamingtool:v5.0.0
318338
```
319339

320-
4. **Verify container started:**
340+
5. **Verify container started:**
321341
```bash
322342
# Check container is running
323343
docker ps
@@ -328,25 +348,25 @@ v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
328348
# Should see: "Now listening on: http://[::]:80"
329349
```
330350

331-
5. Wait 30-60 seconds, then access the application at `http://localhost`
351+
6. Access the application at `http://localhost:8081` (or your chosen port)
332352

333-
6. **VERIFY DEPLOYMENT:**
334-
- Check container logs: `docker logs azurenamingtool | grep "Application started"`
335-
- Access http://localhost and verify v5.0.0 loads
353+
7. **VERIFY DEPLOYMENT:**
354+
- Check container logs: `docker logs azurenamingtool`
355+
- Access http://localhost:8081 and verify v5.0.0 loads
336356
- Check footer for version "5.0.0"
337357

338358
**Docker Compose Example:**
339359
```yaml
340360
version: '3.8'
341361
services:
342362
azurenamingtool:
343-
image: ghcr.io/mspnp/azurenamingtool:v5.0.0
363+
build: . # Build from local Dockerfile
364+
image: azurenamingtool:latest
344365
container_name: azurenamingtool
345366
ports:
346-
- "80:80"
367+
- "8081:80" # Map host port 8081 to container port 80
347368
volumes:
348-
- ./repository:/app/repository
349-
- ./settings:/app/settings
369+
- azurenamingtoolvol:/app/settings # Use Docker volume for persistence
350370
restart: unless-stopped
351371
environment:
352372
- ASPNETCORE_ENVIRONMENT=Production
@@ -574,6 +594,25 @@ v5.0.0 introduces SQLite database support for improved performance and reliabili
574594
> - The application **MUST BE RESTARTED** after migration completes
575595
> - Ensure you have adequate disk space (at least 2x your current data size)
576596

597+
> **🚨 CRITICAL - Azure Container Apps & File Share Users:**
598+
>
599+
> **DO NOT migrate to SQLite if you are using:**
600+
> - **Azure Container Apps with Azure File Share** mounted volumes
601+
> - **Any network file system** (SMB/CIFS/NFS) for persistent storage
602+
> - **Docker with bind mounts to network drives**
603+
>
604+
> **Why:** SQLite does not support network file systems due to file locking limitations. The database file will become locked and your container will fail to start with error: `"database is locked"`.
605+
>
606+
> **Solution:** Keep using **FileSystem (JSON)** storage provider for these scenarios. JSON file storage works perfectly with network mounts.
607+
>
608+
> **When SQLite works:**
609+
> - ✅ Azure App Service (local disk)
610+
> - ✅ Docker with Docker volumes (local)
611+
> - ✅ Standalone installations (local disk)
612+
> - ✅ Kubernetes with local persistent volumes
613+
> - ❌ Azure Container Apps with File Share
614+
> - ❌ Any network-based storage
615+
577616
#### Prerequisites
578617

579618
1. **Complete Steps 1-5** (Deploy v5.0.0 and restore configuration)
@@ -746,6 +785,44 @@ If you need to rollback from SQLite to file-based storage:
746785
4. Try rollback procedure (see Step 6)
747786
5. Restore from pre-migration backup
748787

788+
#### Container Fails with "Database is Locked" Error
789+
**Symptom:** Docker container or Azure Container App fails to start with SQLite error: `"SQLite Error 5: 'database is locked'"` or `"Microsoft.Data.Sqlite.SqliteException (0x80004005)"`
790+
791+
**Root Cause:** SQLite does not support network file systems (Azure File Share uses SMB/CIFS protocol). File locking doesn't work correctly over network mounts.
792+
793+
**Solution:**
794+
1. **Immediate Fix - Switch to FileSystem Storage:**
795+
```bash
796+
# Stop the container
797+
docker stop azurenamingtool
798+
docker rm azurenamingtool
799+
800+
# Edit settings/appsettings.json and change:
801+
"StorageProvider": "FileSystem" # Change from "SQLite"
802+
803+
# Delete the SQLite database file (optional, but recommended)
804+
rm settings/azurenamingtool.db
805+
806+
# Restart container
807+
docker run -d \
808+
-p 8081:80 \
809+
--mount source=azurenamingtoolvol,target=/app/settings \
810+
--name azurenamingtool \
811+
azurenamingtool:latest
812+
```
813+
814+
2. **For Azure Container Apps:**
815+
- Keep using FileSystem (JSON) storage
816+
- Do NOT migrate to SQLite
817+
- JSON files work perfectly with Azure File Share
818+
819+
3. **Long-term Solution:**
820+
- Use FileSystem storage for Azure Container Apps with File Share
821+
- OR migrate to Azure App Service with local disk for SQLite support
822+
- OR use Azure SQL Database (future enhancement)
823+
824+
**Prevention:** Always check deployment platform before migrating to SQLite (see warning in Step 6).
825+
749826
#### Azure Validation Not Working
750827
**Symptom:** Azure validation features are not available
751828

docs/v5.0.0/wiki/V5.0.0_MIGRATION_GUIDE.md

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -279,45 +279,52 @@ v5.0.0 requires .NET 10.0 runtime. You **MUST** update your App Service runtime
279279
280280
**⚠️ IMPORTANT: .NET 10.0 Docker Image Required**
281281
282-
v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
282+
v5.0.0 uses a new Docker image based on .NET 10.0 runtime. You must build the image from source.
283283
284284
1. **STOP the current container (if running):**
285285
```bash
286286
docker stop azurenamingtool
287287
docker rm azurenamingtool
288288
```
289289

290-
2. **Pull the latest v5.0.0 image:**
290+
2. **Download and extract v5.0.0 release:**
291+
- Navigate to the [Releases page](https://github.com/mspnp/AzureNamingTool/releases)
292+
- Download **AzureNamingTool.zip** from the v5.0.0 release assets
293+
- Extract the ZIP file to a folder
294+
- Verify the extracted files match the repository contents
295+
296+
3. **Build the v5.0.0 Docker image:**
291297
```bash
292-
# Pull the .NET 10.0-based image
293-
docker pull ghcr.io/mspnp/azurenamingtool:v5.0.0
294-
# Or use latest tag (ensure it's v5.0.0 or higher)
295-
docker pull ghcr.io/mspnp/azurenamingtool:latest
298+
# Navigate to the extracted folder
299+
cd path/to/extracted/AzureNamingTool
300+
301+
# Build the Docker image
302+
docker build -t azurenamingtool .
296303
```
304+
305+
> **NOTE:** Ensure the '.' is included in the command
297306
298-
3. **Run with persistent storage:**
307+
4. **Run with persistent storage using a Docker volume:**
299308
```bash
300309
docker run -d \
301-
-p 80:80 \
302-
-v $(pwd)/repository:/app/repository \
303-
-v $(pwd)/settings:/app/settings \
310+
-p 8081:80 \
311+
--mount source=azurenamingtoolvol,target=/app/settings \
304312
--name azurenamingtool \
305313
--restart unless-stopped \
306-
ghcr.io/mspnp/azurenamingtool:v5.0.0
314+
azurenamingtool:latest
307315
```
308316

309-
**Windows PowerShell:**
310-
```powershell
311-
docker run -d `
312-
-p 80:80 `
313-
-v ${PWD}/repository:/app/repository `
314-
-v ${PWD}/settings:/app/settings `
315-
--name azurenamingtool `
316-
--restart unless-stopped `
317-
ghcr.io/mspnp/azurenamingtool:v5.0.0
317+
**Windows Command Prompt:**
318+
```cmd
319+
docker run -d -p 8081:80 --mount source=azurenamingtoolvol,target=/app/settings --name azurenamingtool --restart unless-stopped azurenamingtool:latest
318320
```
321+
322+
> **NOTES:**
323+
> - Substitute 8081 for any port not in use on your machine
324+
> - The volume mount ensures settings persist across container restarts
325+
> - You may see warnings about DataProtection keys - these are normal and indicate keys are local to the container
319326
320-
4. **Verify container started:**
327+
5. **Verify container started:**
321328
```bash
322329
# Check container is running
323330
docker ps
@@ -328,25 +335,25 @@ v5.0.0 uses a new Docker image based on .NET 10.0 runtime.
328335
# Should see: "Now listening on: http://[::]:80"
329336
```
330337

331-
5. Wait 30-60 seconds, then access the application at `http://localhost`
338+
6. Access the application at `http://localhost:8081` (or your chosen port)
332339

333-
6. **VERIFY DEPLOYMENT:**
334-
- Check container logs: `docker logs azurenamingtool | grep "Application started"`
335-
- Access http://localhost and verify v5.0.0 loads
340+
7. **VERIFY DEPLOYMENT:**
341+
- Check container logs: `docker logs azurenamingtool`
342+
- Access http://localhost:8081 and verify v5.0.0 loads
336343
- Check footer for version "5.0.0"
337344

338345
**Docker Compose Example:**
339346
```yaml
340347
version: '3.8'
341348
services:
342349
azurenamingtool:
343-
image: ghcr.io/mspnp/azurenamingtool:v5.0.0
350+
build: . # Build from local Dockerfile
351+
image: azurenamingtool:latest
344352
container_name: azurenamingtool
345353
ports:
346-
- "80:80"
354+
- "8081:80" # Map host port 8081 to container port 80
347355
volumes:
348-
- ./repository:/app/repository
349-
- ./settings:/app/settings
356+
- azurenamingtoolvol:/app/settings # Use Docker volume for persistence
350357
restart: unless-stopped
351358
environment:
352359
- ASPNETCORE_ENVIRONMENT=Production

src/Components/Modals/MigrationPromptModal.razor

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@
4141
</div>
4242
</div>
4343

44+
<div class="modern-notification-danger" style="margin-bottom: 1rem;">
45+
<i class="bi bi-exclamation-triangle-fill"></i>
46+
<div>
47+
<strong>⚠️ CRITICAL - Azure Container Apps Users:</strong>
48+
<p style="margin: 0.5rem 0 0 0;">
49+
<strong>DO NOT migrate to SQLite</strong> if you are using <strong>Azure Container Apps with Azure File Share</strong> for persistent storage.
50+
SQLite does not work with network file systems (Azure File Share uses SMB/CIFS) and will cause "database is locked" errors.
51+
</p>
52+
<p style="margin: 0.5rem 0 0 0;">
53+
<strong>Keep using JSON (FileSystem)</strong> storage for Azure Container Apps deployments with File Share.
54+
</p>
55+
</div>
56+
</div>
57+
4458
@if (showMigrationStatus)
4559
{
4660
<div class="modern-notification-warning">

src/Program.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,17 +290,17 @@
290290
else
291291
{
292292
// No settings/appsettings.json = Fresh install
293-
// VerifyConfiguration will copy repository/appsettings.json with StorageProvider=SQLite
294-
Console.WriteLine("[Storage] Fresh install detected - will use default (SQLite)");
293+
// VerifyConfiguration will copy repository/appsettings.json with StorageProvider=FileSystem (default)
294+
Console.WriteLine("[Storage] Fresh install detected - will use default (FileSystem)");
295295
}
296296

297297
// Run VerifyConfiguration to ensure all config files exist
298-
// For fresh installs, this copies repository/appsettings.json → settings/appsettings.json (with StorageProvider=SQLite)
298+
// For fresh installs, this copies repository/appsettings.json → settings/appsettings.json (with StorageProvider=FileSystem)
299299
ConfigurationHelper.VerifyConfiguration(new StateContainer());
300300

301301
// Read the configuration and use the StorageProvider value
302302
var siteConfig = ConfigurationHelper.GetConfigurationData();
303-
var provider = siteConfig.StorageProvider?.ToLower() ?? "sqlite";
303+
var provider = siteConfig.StorageProvider?.ToLower() ?? "filesystem";
304304

305305
if (provider == "sqlite")
306306
{

src/repository/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@
2424
"GeneratedNamesLogEnabled": "True",
2525
"InstructionsEnabled": "True",
2626
"IdentityHeaderName": "X-MS-CLIENT-PRINCIPAL-NAME",
27-
"StorageProvider": "SQLite"
27+
"StorageProvider": "FileSystem"
2828
}

0 commit comments

Comments
 (0)