diff --git a/DEPLOYMENT_GUIDE_IIS_Windows11.md b/DEPLOYMENT_GUIDE_IIS_Windows11.md new file mode 100644 index 0000000..f464b28 --- /dev/null +++ b/DEPLOYMENT_GUIDE_IIS_Windows11.md @@ -0,0 +1,723 @@ +# TuneRipper Deployment Guide - IIS on Windows 11 + +This guide provides step-by-step instructions for manually deploying the TuneRipper Blazor WebAssembly application and API to Internet Information Services (IIS) on Windows 11. + +## Deployment Scenarios + +### Scenario A: Production Server (Recommended) +Deploy pre-built applications to a clean production server. +**Requirements**: Only .NET 10 Hosting Bundle + IIS + +### Scenario B: Build + Deploy on Same Machine +Build and deploy applications on the same machine. +**Requirements**: .NET 10 SDK + .NET 10 Hosting Bundle + IIS + +--- + +## Prerequisites + +### System Requirements +- Windows 11 (Pro, Enterprise, or Education edition recommended) +- **IIS (Internet Information Services)** already installed and configured +- Administrative privileges +- Internet connection for downloading dependencies +- **Domain names configured** (for production HTTPS setup) + +### Software Dependencies +- **.NET 10 Hosting Bundle** (production) OR **.NET 10 SDK** (development) +- **yt-dlp.exe** (for video processing) +- **ffmpeg** (required by yt-dlp for audio conversion) +- **Let's Encrypt ACME tool** (for SSL certificates in production) + +--- + +## Step 1: Install .NET 10 Hosting Bundle for IIS + +> **Critical**: This step is required for ALL deployment scenarios + +### 1.1 Download .NET 10 Hosting Bundle +The Hosting Bundle contains the ASP.NET Core runtime and IIS integration components needed to run .NET 10 applications on IIS. + +1. Go to [Microsoft .NET Downloads](https://dotnet.microsoft.com/download/dotnet/10.0) +2. Scroll to **"ASP.NET Core Runtime"** section +3. Under **"Run server apps"**, find **"Hosting Bundle"** +4. Download **"Hosting Bundle"** for Windows (e.g., `dotnet-hosting-10.0.x-win.exe`) +5. **Important**: This is different from the SDK - it's specifically for IIS hosting + +### 1.2 Install the Hosting Bundle +1. Close all IIS Manager windows and web browsers +2. Run the downloaded hosting bundle installer as **Administrator** +3. Follow the installation wizard: + - Accept license terms + - Complete the installation +4. **Critical**: Restart IIS services by running this command in **Command Prompt as Administrator**: + ```cmd + iisreset /restart + ``` +5. Alternatively, restart the entire computer to ensure all services are updated + +### 1.3 Verify Hosting Bundle Installation +1. Open **Command Prompt as Administrator** +2. Run: `dotnet --info` +3. Look for the ASP.NET Core Module in IIS: + ```cmd + %windir%\system32\inetsrv\appcmd.exe list modules + ``` +4. You should see `AspNetCoreModuleV2` in the output +5. Check the registry for the module (PowerShell as Administrator): + ```powershell + Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\IIS Extensions\IIS AspNetCore Module V2" + ``` + +### 1.4 Verify ASP.NET Core Module Installation +1. Open **IIS Manager** (`Win + R` ? `inetmgr`) +2. Select your server name in the left panel +3. Double-click **"Modules"** in the main panel +4. Look for **"AspNetCoreModuleV2"** - it should be present and enabled +5. If not visible, you may need to restart IIS again: + ```cmd + iisreset + ``` + +--- + +## Step 2: Install Required Tools + +### 2.1 Download yt-dlp +1. Go to [yt-dlp releases](https://github.com/yt-dlp/yt-dlp/releases) +2. Download the latest `yt-dlp.exe` (Windows executable) +3. **Important**: Keep this file ready for later deployment + +### 2.2 Install FFmpeg +1. Go to [FFmpeg downloads](https://ffmpeg.org/download.html#build-windows) +2. Choose **"Windows"** ? **"Windows builds by BtbN"** +3. Download the latest **"ffmpeg-master-latest-win64-gpl.zip"** +4. Extract to `C:\ffmpeg\` +5. Add `C:\ffmpeg\bin` to your System PATH: + - Press `Win + X`, select **"System"** + - Click **"Advanced system settings"** + - Click **"Environment Variables"** + - Under **"System Variables"**, find and edit **"Path"** + - Click **"New"** and add: `C:\ffmpeg\bin` + - Click **OK** to save all dialogs +6. Restart Command Prompt and verify: `ffmpeg -version` + +### 2.3 Install Let's Encrypt ACME Tool (Production HTTPS) +For production deployment with custom domains, install an ACME client: + +1. **Install win-acme (Recommended for Windows/IIS)**: + - Go to [win-acme releases](https://github.com/win-acme/win-acme/releases) + - Download the latest `win-acme.v2.x.x.x.pluggable.zip` + - Extract to `C:\win-acme\` + +--- + +## Step 3: Get Application Files + +### Option A: Use Pre-Built Files (Production Deployment) +If you have pre-built application files from another machine: +1. Copy the published API files to: `C:\Publish\TuneRipper.Api\` +2. Copy the published Blazor WebAssembly files to: `C:\Publish\TuneRipper\` +3. **Skip to Step 4** (Prepare Deployment Files) + +### Option B: Build Applications (Build + Deploy Scenario) +If you need to build the applications on this machine, continue below: + +#### 3B.1 Install .NET 10 SDK (If Building Locally) +1. Go to [Microsoft .NET Downloads](https://dotnet.microsoft.com/download/dotnet/10.0) +2. Download and install the .NET 10 SDK +3. Restart your computer after installation + +#### 3B.2 Verify Build Environment +Before publishing, ensure your development environment is ready: +1. Open **Command Prompt** in your project directory: `C:\DevHome\TuneRipper` +2. Run: `dotnet --version` (should show 10.0.x) +3. Run: `dotnet restore` (restore NuGet packages) +4. Run: `dotnet build` (verify everything compiles) + +#### 3B.3 Publish the API (TuneRipper.Api) + +**Using Visual Studio:** +1. Open the TuneRipper solution in **Visual Studio 2022** +2. Ensure you have **.NET 10 workload** installed in Visual Studio: + - Go to **Tools** ? **Get Tools and Features** + - Under **Workloads**, ensure **"ASP.NET and web development"** is checked + - Under **Individual Components**, ensure **.NET 10 Runtime** is selected +3. Right-click on **TuneRipper.Api** project +4. Select **"Publish..."** +5. Choose **"Folder"** as the publish target +6. Set publish folder to: `C:\Publish\TuneRipper.Api` +7. Click **"Show all settings"** and configure: + - **Configuration**: `Release` + - **Target Framework**: `net10.0` + - **Deployment Mode**: `Framework-dependent` + - **Target Runtime**: `Portable` +8. Click **"Save"** and then **"Publish"** + +**Using Command Line:** +```cmd +cd C:\DevHome\TuneRipper +dotnet publish TuneRipper.Api\TuneRipper.Api.csproj -c Release -f net10.0 -o C:\Publish\TuneRipper.Api --verbosity normal +``` + +#### 3B.4 Publish the Blazor WebAssembly App (TuneRipper) + +**Using Visual Studio:** +1. Right-click on **TuneRipper** project +2. Select **"Publish..."** +3. Choose **"Folder"** as the publish target +4. Set publish folder to: `C:\Publish\TuneRipper` +5. Configure settings: + - **Configuration**: `Release` + - **Target Framework**: `net10.0` +6. Click **"Save"** and then **"Publish"** + +**Using Command Line:** +```cmd +cd C:\DevHome\TuneRipper +dotnet publish TuneRipper\TuneRipper.csproj -c Release -f net10.0 -o C:\Publish\TuneRipper --verbosity normal +``` + +#### 3B.5 Verify Published Output +After publishing, check the output directories: + +**API Output** (`C:\Publish\TuneRipper.Api\`): +- `TuneRipper.Api.dll` +- `TuneRipper.Api.exe` +- `web.config` (should be auto-generated) +- `appsettings.json` +- Various .NET 10 runtime files + +**Blazor Output** (`C:\Publish\TuneRipper\`): +- `wwwroot\` folder containing: + - `index.html` + - `_framework\` folder + - Static assets (CSS, JS, etc.) + +--- + +## Step 4: Prepare Deployment Files + +### 4.1 Create Deployment Directories +```cmd +mkdir C:\inetpub\wwwroot\TuneRipper +mkdir C:\inetpub\wwwroot\TuneRipperApi +mkdir C:\inetpub\wwwroot\TuneRipperApi\wwwroot +mkdir C:\inetpub\wwwroot\TuneRipperApi\wwwroot\downloads +``` + +### 4.2 Copy API Files +1. Copy all contents from `C:\Publish\TuneRipper.Api\` to `C:\inetpub\wwwroot\TuneRipperApi\` +2. Copy `yt-dlp.exe` to `C:\inetpub\wwwroot\TuneRipperApi\wwwroot\yt-dlp.exe` +3. Verify the API structure: + ``` + C:\inetpub\wwwroot\TuneRipperApi\ + ??? TuneRipper.Api.dll + ??? TuneRipper.Api.exe + ??? appsettings.json + ??? web.config + ??? wwwroot\ + ? ??? yt-dlp.exe + ? ??? downloads\ + ??? [other .NET 10 runtime files] + ``` + +### 4.3 Copy Blazor WebAssembly Files +1. Copy all contents from `C:\Publish\TuneRipper\wwwroot\` to `C:\inetpub\wwwroot\TuneRipper\` +2. Verify the Blazor structure: + ``` + C:\inetpub\wwwroot\TuneRipper\ + ??? index.html + ??? _framework\ + ? ??? blazor.webassembly.js + ? ??? dotnet.10.x.x.js + ? ??? [.NET 10 WebAssembly files] + ??? css\ + ??? images\ + ??? [other static files] + ``` + +--- + +## Step 5: Configure IIS Sites + +### 5.1 Open IIS Manager +1. Press `Win + R`, type `inetmgr`, press Enter +2. IIS Manager should open + +### 5.2 Create API Application +1. In IIS Manager, expand the server node +2. Right-click **"Sites"** ? **"Add Website..."** +3. Configure the API site: + - **Site name**: `TuneRipper API` + - **Physical path**: `C:\inetpub\wwwroot\TuneRipperApi` + - **Port**: `80` (HTTP) and `443` (HTTPS) + - **Host name**: `tuneripper-api.vrba.one` +4. Click **"OK"** + +### 5.3 Create Blazor WebAssembly Application +1. Right-click **"Sites"** ? **"Add Website..."** +2. Configure the Blazor site: + - **Site name**: `TuneRipper App` + - **Physical path**: `C:\inetpub\wwwroot\TuneRipper` + - **Port**: `80` (HTTP) and `443` (HTTPS) + - **Host name**: `tuneripper.vrba.one` +3. Click **"OK"** + +### 5.4 Configure Application Pool for API (.NET 10 Specific) +1. Click **"Application Pools"** in the left panel +2. Find the application pool for **TuneRipper API** (usually has the same name) +3. Right-click ? **"Advanced Settings..."** +4. Set the following **.NET 10 specific settings**: + - **.NET CLR Version**: `No Managed Code` (This is correct for .NET 10!) + - **Managed Pipeline Mode**: `Integrated` + - **Start Mode**: `OnDemand` + - **Process Identity**: `ApplicationPoolIdentity` + - **Load User Profile**: `True` (important for .NET 10) + - **Idle Time-out (minutes)**: `20` or `0` (no timeout for testing) +5. Click **"OK"** + +### 5.5 Verify ASP.NET Core Module for API Site +1. Select your **TuneRipper API** site in IIS Manager +2. Double-click **"Modules"** +3. Ensure **AspNetCoreModuleV2** is present and enabled +4. If not present, the Hosting Bundle installation may have failed + +--- + +## Step 6: Configure SSL Certificates with Let's Encrypt + +### 6.1 Using win-acme (Recommended) +1. Open **Command Prompt as Administrator** +2. Navigate to win-acme directory: + ```cmd + cd C:\win-acme\ + ``` +3. Run win-acme and create certificates for both domains: + ```cmd + wacs.exe --target iis --siteid 1 --commonname tuneripper.vrba.one + wacs.exe --target iis --siteid 2 --commonname tuneripper-api.vrba.one + ``` +4. Follow the prompts to: + - Select the IIS sites + - Validate domain ownership + - Install certificates + - Set up automatic renewal + +### 6.2 Configure HTTPS Bindings in IIS +1. In IIS Manager, select **TuneRipper App** site +2. Click **"Bindings..."** in the Actions panel +3. Click **"Add..."** +4. Configure HTTPS binding: + - **Type**: `https` + - **Port**: `443` + - **Host name**: `tuneripper.vrba.one` + - **SSL certificate**: Select the Let's Encrypt certificate +5. Repeat for **TuneRipper API** site with `tuneripper-api.vrba.one` + +--- + +## Step 7: Configure Production Settings + +### 7.1 Update API Configuration for Production +1. Navigate to `C:\inetpub\wwwroot\TuneRipperApi\` +2. Edit `appsettings.json`: + ```json + { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "TuneRipper.Api.Services.VideoService": "Information" + } + }, + "AllowedHosts": "tuneripper-api.vrba.one", + "ApiSettings": { + "BaseUrl": "https://tuneripper-api.vrba.one", + "HttpBaseUrl": "https://tuneripper-api.vrba.one", + "TimeoutSeconds": 300, + "EnableLogging": true, + "RetryAttempts": 3, + "RetryDelaySeconds": 2 + } + } + ``` + +### 7.2 Update CORS for Production Domains +1. Navigate to `C:\inetpub\wwwroot\TuneRipperApi\` +2. If you need to restrict CORS (optional), modify the API's `Program.cs`: + ```csharp + // Update CORS policy for production + builder.Services.AddCors(options => + { + options.AddPolicy("ProductionPolicy", policy => + { + policy.WithOrigins( + "https://tuneripper.vrba.one", + "https://tuneripper-api.vrba.one" + ) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + }); + + // Use the production policy + app.UseCors("ProductionPolicy"); + ``` + + **Note**: The current CORS configuration uses `AllowAnyOrigin()` which will work fine with your subdomains without changes. The above restriction is optional for enhanced security. + +### 7.3 Update Blazor App Configuration +1. Navigate to `C:\inetpub\wwwroot\TuneRipper\` +2. Update `appsettings.json`: + ```json + { + "ApiSettings": { + "BaseUrl": "https://tuneripper-api.vrba.one", + "HttpBaseUrl": "https://tuneripper-api.vrba.one", + "TimeoutSeconds": 300, + "EnableLogging": false, + "RetryAttempts": 3, + "RetryDelaySeconds": 2 + }, + "AppSettings": { + "AppName": "TuneRipper", + "Version": "1.0.0", + "Environment": "Production", + "EnableDetailedErrors": false + } + } + ``` + +### 7.4 Update API Root Endpoint URLs +1. Navigate to `C:\inetpub\wwwroot\TuneRipperApi\` +2. If needed, update the root endpoint in `Program.cs` to show production URLs: + ```csharp + urls = new + { + https = "https://tuneripper-api.vrba.one", + app = "https://tuneripper.vrba.one" + } + ``` + +--- + +## Step 8: Verify Web Configuration Files + +> **? Good News**: The `web.config` files are now included in both projects and will be automatically deployed during publish! + +### 8.1 API web.config (Auto-deployed) +The API project now includes a `web.config` file that will be automatically copied during publish. It includes: +- **HTTPS redirection** for production security +- **ASP.NET Core hosting** configuration for IIS +- **Security headers** for production +- **Environment variables** set to Production + +**Location after publish**: `C:\inetpub\wwwroot\TuneRipperApi\web.config` + +### 8.2 Blazor WebAssembly web.config (Auto-deployed) +The Blazor project now includes a `web.config` file that will be automatically copied during publish. It includes: +- **HTTPS redirection** for production security +- **SPA routing support** for client-side navigation +- **MIME type mappings** for .wasm and .dll files +- **Security headers** for production + +**Location after publish**: `C:\inetpub\wwwroot\TuneRipper\web.config` + +### 8.3 Manual Verification (Optional) +After deployment, you can verify the files are present: +1. Check API web.config: `C:\inetpub\wwwroot\TuneRipperApi\web.config` +2. Check Blazor web.config: `C:\inetpub\wwwroot\TuneRipper\web.config` + +> **Note**: These files are now version-controlled and automatically deployed. No manual configuration needed! + +--- + +## Step 9: Set Permissions + +### 9.1 Configure Folder Permissions +1. Right-click `C:\inetpub\wwwroot\TuneRipperApi\wwwroot\downloads` +2. Select **"Properties"** ? **"Security"** tab +3. Click **"Edit..."** ? **"Add..."** +4. Type: `IIS_IUSRS` and click **"Check Names"** ? **"OK"** +5. Select **IIS_IUSRS** and check: + - ? **Full Control** + - ? **Modify** + - ? **Read & Execute** + - ? **Write** +6. Click **"OK"** to save + +### 9.2 Set Application Pool Identity Permissions +1. Right-click `C:\inetpub\wwwroot\TuneRipperApi` +2. **Properties** ? **Security** ? **Edit** ? **Add** +3. Type: `IIS AppPool\TuneRipper API` ? **Check Names** ? **OK** +4. Grant **Read & Execute** permissions +5. Click **OK** + +--- + +## Step 10: Test Deployment + +### 10.1 Test .NET 10 Runtime in IIS +1. Start both websites in IIS Manager +2. Check Application Pool status - should be **"Started"** +3. If Application Pool keeps stopping, check Event Viewer for errors + +### 10.2 Test Production URLs +1. Open a web browser +2. Navigate to: `https://tuneripper-api.vrba.one/api/health` +3. You should see a JSON health check response +4. Test the root endpoint: `https://tuneripper-api.vrba.one/` +5. Verify the API information is displayed + +### 10.3 Test Blazor WebAssembly App +1. Navigate to: `https://tuneripper.vrba.one` +2. The TuneRipper application should load +3. Check browser developer tools (F12) for any loading errors +4. Test the YouTube URL input functionality + +### 10.4 Test End-to-End Functionality +1. In the Blazor app, enter a YouTube URL +2. Click **"Download MP3"** +3. Monitor the processing progress +4. Verify the file download works + +### 10.5 Test SSL Certificates +1. Check certificate validity in browser +2. Verify automatic HTTP to HTTPS redirection +3. Test certificate auto-renewal (win-acme sets up scheduled tasks) + +--- + +## Step 11: Troubleshooting + +### 11.1 Common .NET 10 Issues + +#### Application Pool Keeps Stopping +**Problem**: Application pool stops immediately after starting +**Solutions**: +1. Check Event Viewer: `Windows Logs` ? `Application` and `System` +2. Look for ASP.NET Core errors or .NET runtime issues +3. Verify .NET 10 Hosting Bundle is properly installed: + ```cmd + dotnet --list-runtimes + ``` +4. Ensure `web.config` has correct `processPath` and `arguments` +5. Check Application Pool settings: + - .NET CLR Version = "No Managed Code" + - Managed Pipeline Mode = "Integrated" + +#### SSL Certificate Issues +**Problem**: SSL certificate not working or expired +**Solutions**: +1. Check certificate binding in IIS Manager +2. Verify Let's Encrypt certificate renewal: + ```cmd + # For win-acme + wacs.exe --list + + # For certbot + certbot certificates + ``` +3. Check Windows Task Scheduler for renewal tasks +4. Manually renew if needed: + ```cmd + # For win-acme + wacs.exe --renew + + # For certbot + certbot renew + ``` + +#### CORS Errors +**Problem**: Cross-origin requests blocked +**Solutions**: +1. Verify CORS configuration in `Program.cs` +2. Current configuration uses `AllowAnyOrigin()` which should work +3. If you implemented production CORS restrictions, ensure domains are correctly specified +4. Check browser console for specific CORS error messages + +#### 500 Internal Server Error +**Problem**: HTTP 500 error when accessing API +**Solutions**: +1. Enable detailed errors in `web.config`: + ```xml + + + + + + ``` +2. Create `logs` folder in API directory +3. Check stdout logs for detailed error information +4. Verify all .NET 10 dependencies are published + +#### Blazor WebAssembly Loading Issues +**Problem**: Blazor app shows loading indefinitely +**Solutions**: +1. Check browser console (F12) for JavaScript errors +2. Verify all `.wasm` and `.dll` files are present in `_framework` folder +3. Check that `dotnet.js` and `blazor.webassembly.js` are loading +4. Ensure proper MIME types in `web.config` +5. Verify API base URL is correctly configured in `appsettings.json` + +### 11.2 Verification Commands +```cmd +# Check .NET installation (Hosting Bundle should show runtimes, SDK not required) +dotnet --list-runtimes + +# Check IIS status +iisreset /status + +# List IIS sites +%windir%\system32\inetsrv\appcmd.exe list sites + +# Check Application Pools +%windir%\system32\inetsrv\appcmd.exe list appPools + +# Verify ASP.NET Core Module (Critical for .NET 10) +%windir%\system32\inetsrv\appcmd.exe list modules | findstr AspNet + +# Check SSL certificates +certlm.msc + +# Test HTTPS connectivity +curl -I https://tuneripper-api.vrba.one/api/health +curl -I https://tuneripper.vrba.one +``` + +### 11.3 Log Locations +- **IIS Logs**: `C:\inetpub\logs\LogFiles\W3SVC1\` (and W3SVC2, etc.) +- **Windows Event Log**: Event Viewer ? Application and System logs +- **ASP.NET Core stdout logs**: `C:\inetpub\wwwroot\TuneRipperApi\logs\` (if enabled) +- **Application-specific logs**: Configure in `appsettings.json` +- **Let's Encrypt Logs**: + - win-acme: `C:\win-acme\logs\` + - certbot: `C:\Certbot\log\` + +--- + +## Step 12: Security Considerations + +### 12.1 Production Security +1. **SSL/TLS**: Certificates automatically managed by Let's Encrypt +2. **HTTPS Enforcement**: Configured in `web.config` for automatic redirection +3. **CORS**: Current configuration uses `AllowAnyOrigin()` (works with subdomains) +4. **Security Headers**: Added to `web.config` (X-Frame-Options, etc.) +5. **File Upload Limits**: Configure maximum file sizes if needed +6. **Rate Limiting**: Consider implementing rate limiting for API endpoints +7. **Update .NET Regularly**: Keep .NET 10 runtime updated via Hosting Bundle + +### 12.2 Firewall Configuration +1. Open Windows Defender Firewall +2. Create inbound rules for HTTP (80) and HTTPS (443) ports +3. Block development ports (7160, 8080) from external access +4. Configure network access as needed + +### 12.3 CORS Security Analysis +The current CORS configuration in your API uses: +```csharp +policy.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader(); +``` + +**? This will work perfectly with your subdomain setup** because: +- `AllowAnyOrigin()` permits requests from any domain +- Your Blazor app at `https://tuneripper.vrba.one` can call API at `https://tuneripper-api.vrba.one` +- No CORS configuration changes are required + +**For enhanced security (optional)**, you could restrict to specific domains as shown in Step 7.2. + +--- + +## Step 13: Maintenance + +### 13.1 Regular Tasks +- Monitor disk space in downloads folder +- Update yt-dlp.exe regularly for YouTube compatibility +- Check for .NET 10 updates and security patches +- Review and rotate log files +- Monitor application pool health +- **Monitor SSL certificate renewals** (should be automatic) + +### 13.2 SSL Certificate Maintenance +- **win-acme**: Automatic renewal via Windows Task Scheduler +- **certbot**: Set up automatic renewal: + ```cmd + # Add to Task Scheduler to run twice daily + certbot renew --quiet + ``` + +### 13.3 Updating .NET 10 +When new .NET 10 updates are released: +1. Download and install **new .NET 10 Hosting Bundle** (SDK not required) +2. Restart IIS: `iisreset` +3. Test application functionality +4. Update applications if needed (rebuild only if breaking changes) + +--- + +## Conclusion + +Your TuneRipper application should now be successfully deployed on IIS with Windows 11 using .NET 10, complete with production HTTPS via Let's Encrypt. + +**Production URLs:** +- **API**: `https://tuneripper-api.vrba.one` +- **Blazor App**: `https://tuneripper.vrba.one` + +**Key Production Features:** +- ? **Automatic HTTPS** with Let's Encrypt certificates +- ? **Automatic HTTP?HTTPS redirection** +- ? **CORS compatibility** with subdomain setup +- ? **Security headers** configured +- ? **Automatic certificate renewal** set up + +## CORS Compatibility Summary + +### ? **Current CORS Configuration Works Perfect** +Your existing API CORS setup using `AllowAnyOrigin()` will work seamlessly with: +- `https://tuneripper.vrba.one` ? `https://tuneripper-api.vrba.one` +- No code changes required +- Cross-subdomain requests allowed + +### ?? **Optional Security Enhancement** +For production, you can optionally restrict CORS to specific domains (see Step 7.2), but it's not required for functionality. + +## Quick Reference Commands + +```cmd +# Check .NET 10 runtime installation (production) +dotnet --list-runtimes + +# Restart IIS +iisreset + +# Verify FFmpeg +ffmpeg -version + +# Test production endpoints +curl https://tuneripper-api.vrba.one/api/health +curl -I https://tuneripper.vrba.one + +# Check SSL certificates +certlm.msc + +# View IIS processes +tasklist | findstr w3wp + +# Check Application Pool status +%windir%\system32\inetsrv\appcmd.exe list appPools /text:name,state + +# Renew SSL certificates manually +wacs.exe --renew +# or +certbot renew +``` + +--- + +*This guide includes production-ready HTTPS setup with Let's Encrypt for the subdomain configuration: `https://tuneripper.vrba.one` and `https://tuneripper-api.vrba.one`. The existing CORS configuration will work without modifications.* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a85c8a4 --- /dev/null +++ b/README.md @@ -0,0 +1,298 @@ +# TuneRipper - YouTube to MP3 Converter + +A modern Blazor WebAssembly application with ASP.NET Core API for converting YouTube videos to MP3 files using yt-dlp. + +## ?? Overview + +TuneRipper is a full-stack web application that allows users to convert YouTube videos to MP3 format. It features a responsive Blazor WebAssembly frontend and a robust ASP.NET Core API backend with real-time progress monitoring. + +## ??? Architecture + +### Projects Structure +``` +TuneRipper/ +??? TuneRipper/ # Blazor WebAssembly Client +??? TuneRipper.Api/ # ASP.NET Core API +??? TuneRipper.Shared/ # Shared Models & Configuration +??? DEPLOYMENT_GUIDE_IIS_Windows11.md +``` + +### Technology Stack +- **.NET 10** - Latest .NET framework +- **Blazor WebAssembly** - Modern SPA framework +- **ASP.NET Core API** - RESTful backend services +- **yt-dlp** - YouTube video processing +- **FFmpeg** - Audio conversion +- **IIS** - Production deployment platform + +## ?? Quick Start + +### Prerequisites +1. **.NET 10 SDK** installed +2. **yt-dlp.exe** (automatically placed in API wwwroot) +3. **FFmpeg** available in system PATH + +### Development Setup + +#### 1. Clone the Repository +```bash +git clone https://git.vrba.one/TuneRipper.git +cd TuneRipper +``` + +#### 2. Start the API +```bash +cd TuneRipper.Api +dotnet run +``` +API will be available at: +- **HTTPS**: https://localhost:7160 +- **HTTP**: http://localhost:5112 + +#### 3. Start the Blazor WebAssembly App +```bash +cd TuneRipper +dotnet run +``` +App will be available at: https://localhost:7070 + +### Quick Testing +1. Navigate to the Blazor app +2. Enter a YouTube URL +3. Click "Download MP3" +4. Monitor real-time progress +5. Download the converted file + +## ?? File Management System + +### GUID-Based Naming +Downloaded files use the format: **`{jobId}_{title}.mp3`** + +**Examples:** +- `550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3` +- `6ba7b810-9dad-11d1-80b4-00c04fd430c8_How_to_Build_a_Web_API.mp3` + +**Benefits:** +- ? **Unique Identification**: No filename conflicts +- ? **Direct Job Mapping**: Easy file lookup using GUID +- ? **User-Friendly Downloads**: Converted to readable names +- ? **Secure Access**: Job ID acts as access token + +### File Storage +- **Location**: `TuneRipper.Api/wwwroot/downloads/` +- **Access**: Via API endpoints or direct static file serving +- **Cleanup**: Automated cleanup by job ID pattern + +## ?? API Workflow + +### 1. Start Processing +```http +POST /api/video/process +Content-Type: application/json + +{ + "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "format": "mp3", + "quality": "128" +} +``` + +### 2. Monitor Progress +```http +GET /api/video/status/{jobId} +``` +Returns real-time progress with video details. + +### 3. Download Result +```http +GET /api/download/{jobId} +``` +Returns MP3 file with user-friendly filename. + +## ?? Progress Monitoring + +Real-time progress updates from yt-dlp processing: +- **5-15%**: Fetching video details +- **15-70%**: Downloading audio stream +- **70-85%**: Converting to MP3 format +- **85-95%**: Finalizing and cleanup +- **100%**: Ready for download + +## ??? Development + +### API Endpoints +- **Health Check**: `GET /api/health` +- **Process Video**: `POST /api/video/process` +- **Check Status**: `GET /api/video/status/{jobId}` +- **Get Result**: `GET /api/video/result/{jobId}` +- **Download File**: `GET /api/download/{jobId}` +- **List Jobs**: `GET /api/video/jobs` + +### Configuration +Update `appsettings.json` for environment-specific settings: +```json +{ + "ApiSettings": { + "BaseUrl": "https://localhost:7160", + "TimeoutSeconds": 300, + "EnableLogging": true + } +} +``` + +### Testing +Use the provided HTTP test file: +```bash +# Open TuneRipper.Api/api-tests.http in VS Code or Visual Studio +``` + +## ?? Deployment + +### IIS on Windows 11 (Recommended) +Follow the comprehensive deployment guide: +```bash +# See DEPLOYMENT_GUIDE_IIS_Windows11.md for detailed instructions +``` + +**Key Deployment Steps:** +1. Install .NET 10 Hosting Bundle for IIS +2. Enable IIS with ASP.NET Core support +3. Publish applications using Release configuration +4. Configure IIS sites and application pools +5. Set proper file permissions +6. Test end-to-end functionality + +### Docker (Alternative) +```dockerfile +# Dockerfile examples available for containerized deployment +``` + +## ?? Configuration Details + +### Required Tools +- **yt-dlp.exe**: Place in `TuneRipper.Api/wwwroot/` +- **FFmpeg**: Add to system PATH for audio conversion + +### Environment Variables +- `ASPNETCORE_ENVIRONMENT`: Development/Production +- `ASPNETCORE_URLS`: Custom binding URLs + +### CORS Configuration +API is configured to allow Blazor WebAssembly client access: +```csharp +builder.Services.AddCors(options => +{ + options.AddPolicy("BlazorPolicy", policy => + { + policy.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader(); + }); +}); +``` + +## ?? Troubleshooting + +### Common Issues + +#### API Not Starting +```bash +# Check .NET installation +dotnet --version + +# Trust development certificates +dotnet dev-certs https --trust +``` + +#### yt-dlp Not Found +- Verify `yt-dlp.exe` is in `TuneRipper.Api/wwwroot/` +- Check file permissions +- Ensure downloads directory exists + +#### FFmpeg Issues +```bash +# Verify FFmpeg installation +ffmpeg -version + +# Add to PATH if needed +``` + +#### CORS Errors +- Verify API base URL configuration in Blazor app +- Check CORS policy settings +- Ensure API is running on expected port + +### Debug Logging +Enable detailed logging in `appsettings.json`: +```json +{ + "Logging": { + "LogLevel": { + "TuneRipper.Api.Services.VideoService": "Debug" + } + } +} +``` + +## ?? Security Considerations + +### Production Deployment +- **HTTPS Only**: Configure SSL certificates +- **CORS Restrictions**: Limit allowed origins +- **Rate Limiting**: Implement API rate limiting +- **File Cleanup**: Set up automated cleanup jobs +- **Access Control**: Consider authentication for production + +### File Security +- Job IDs provide secure file access +- No directory traversal vulnerabilities +- Automatic cleanup prevents disk space issues + +## ?? Performance Optimization + +### Recommended Settings +- **Application Pool**: Configure for .NET 10 +- **File Storage**: Consider cloud storage for scale +- **Caching**: Implement response caching where appropriate +- **Monitoring**: Set up application insights + +### Scaling Considerations +- GUID-based naming supports distributed environments +- Stateless API design enables horizontal scaling +- Consider queue-based processing for high load + +## ?? Maintenance + +### Regular Tasks +- Update yt-dlp.exe for YouTube compatibility +- Monitor disk space in downloads directory +- Check for .NET 10 security updates +- Review and rotate log files + +### Monitoring +- Application pool health +- File system usage +- API response times +- Error rates and patterns + +## ?? Contributing + +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Test thoroughly +5. Submit a pull request + +## ?? License + +This project is licensed under the MIT License - see the LICENSE file for details. + +## ?? Related Files + +- **Deployment Guide**: `DEPLOYMENT_GUIDE_IIS_Windows11.md` +- **API Tests**: `TuneRipper.Api/api-tests.http` +- **Project Files**: `*.csproj` in each project directory + +--- + +**Built with ?? using .NET 10, Blazor WebAssembly, and modern web technologies.** \ No newline at end of file diff --git a/TuneRipper.Api/README.md b/TuneRipper.Api/README.md deleted file mode 100644 index 668d3f8..0000000 --- a/TuneRipper.Api/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# TuneRipper API - -## Quick Start - -### Starting the API - -**Option 1: Using the start script (Windows)** -```cmd -cd TuneRipper.Api -start-api.bat -``` - -**Option 2: Using the start script (Linux/Mac)** -```bash -cd TuneRipper.Api -chmod +x start-api.sh -./start-api.sh -``` - -**Option 3: Manual start** -```cmd -cd TuneRipper.Api -dotnet run -``` - -### API Endpoints - -Once running, the API will be available at: -- **HTTPS**: https://localhost:7160 -- **HTTP**: http://localhost:5112 - -### Testing the API - -1. **Start the API** using one of the methods above -2. **Open the HTTP test file**: `TuneRipper.Api/api-tests.http` -3. **Run the connectivity tests first** to verify the API is responding -4. **Use the main API tests** once connectivity is confirmed - -### Troubleshooting - -#### "This localhost page can't be found" errors: - -1. **Check if API is running**: - - Look for console output showing "Now listening on: https://localhost:7160" - - If not running, start it using the methods above - -2. **Try HTTP instead of HTTPS**: - - Use `http://localhost:5112` instead of `https://localhost:7160` - - Some development environments have HTTPS certificate issues - -3. **Trust development certificates** (for HTTPS): - ```cmd - dotnet dev-certs https --trust - ``` - -4. **Check port availability**: - - Make sure ports 7160 and 5112 aren't used by other applications - - You can change ports in `Properties/launchSettings.json` - -#### HTTP test file variables not working: - -1. **Copy job IDs manually**: - - Run a POST request to start processing - - Copy the `fileName` value from the response - - Use it in the manual test sections - -2. **Use the troubleshooting section**: - - Start with connectivity tests - - Use manual GUID replacements if variables fail - -### API Documentation - -When the API is running, you can access: -- **Root endpoint**: https://localhost:7160/ (lists available endpoints) -- **OpenAPI spec**: https://localhost:7160/openapi/v1.json -- **Health check**: https://localhost:7160/api/health - -### Development - -The API includes: -- Automatic reload on code changes (when using `dotnet run`) -- Detailed logging in the console -- CORS enabled for Blazor WebAssembly client -- OpenAPI/Swagger support for API documentation \ No newline at end of file diff --git a/TuneRipper.Api/README_UPDATED.md b/TuneRipper.Api/README_UPDATED.md deleted file mode 100644 index c7d2c84..0000000 --- a/TuneRipper.Api/README_UPDATED.md +++ /dev/null @@ -1,296 +0,0 @@ -# TuneRipper API - yt-dlp Integration - -## Overview - -The TuneRipper API has been updated to use `yt-dlp.exe` for real YouTube video processing with progress monitoring. Videos are downloaded and converted to MP3 files, stored in the `wwwroot/downloads` directory with a GUID-based filename format, and served directly through the API. - -## Setup - -### Prerequisites -1. **.NET 10** installed -2. **yt-dlp.exe** placed in `TuneRipper.Api/wwwroot/yt-dlp.exe` -3. **ffmpeg** available in PATH (required by yt-dlp for audio conversion) - -### File Structure -``` -TuneRipper.Api/ -??? wwwroot/ -? ??? yt-dlp.exe # YouTube downloader executable -? ??? downloads/ # Downloaded MP3 files (auto-created) -??? Controllers/ -??? Services/ -??? Program.cs -``` - -## Filename Format - -Downloaded files use the structured format: **`{jobId}_{title}.mp3`** - -### Format Breakdown: -- **`{jobId}`**: GUID identifier for the processing job (e.g., `550e8400-e29b-41d4-a716-446655440000`) -- **`_{title}`**: Sanitized video title with spaces replaced by underscores -- **`.mp3`**: Audio format extension - -### Examples: -- `550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3` -- `6ba7b810-9dad-11d1-80b4-00c04fd430c8_How_to_Build_a_Web_API.mp3` -- `6ba7b811-9dad-11d1-80b4-00c04fd430c8_Amazing_Guitar_Solo_Performance.mp3` - -### Benefits: -- **Unique Identification**: GUID ensures no filename conflicts -- **Direct Job Mapping**: Easy file lookup using job ID -- **Human Readable**: Title part provides context -- **System Friendly**: Sanitized for filesystem compatibility - -### Title Sanitization: -- Invalid filename characters are replaced with safe alternatives -- Spaces become underscores (`_`) -- Special characters: `< > | : * ? " /` are replaced with safe chars -- Maximum title length: 50 characters -- Fallback to "video" if title cannot be determined - -## Key Changes - -### 1. Program.cs Updates -- Added `UseStaticFiles()` middleware for serving downloaded files -- Added `AddHttpClient()` for VideoService HTTP requests -- Updated logging and endpoint information - -### 2. VideoService Updates -- **GUID-Based Filenames**: Uses job ID as primary identifier in filename -- **Title Sanitization**: Converts video titles to safe filenames -- **Direct Job Mapping**: Files can be found using `{jobId}_*.*` pattern -- **Real yt-dlp Integration**: Uses actual yt-dlp.exe with progress monitoring -- **Progress Parsing**: Real-time progress from yt-dlp output streams -- **Error Handling**: Comprehensive error handling with 5-minute timeout - -### 3. VideoController Updates -- Passes job ID to VideoService for filename generation -- Uses actual yt-dlp processing instead of simulation -- Stores downloaded file information with GUID-based naming -- Returns real download URLs for completed files - -### 4. DownloadController Updates -- **Precise Job Lookup**: Uses `{jobId}_*.*` pattern for exact file matching -- **User-Friendly Downloads**: Converts filenames back to readable format -- **Example**: `550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3` ? `Rick Astley Never Gonna Give You Up.mp3` -- **Reliable File Operations**: No ambiguity in file identification -- Serves actual MP3 files from `wwwroot/downloads/` -- Proper MIME type detection for audio files - -## API Workflow - -### 1. Start Processing -```http -POST /api/video/process -Content-Type: application/json - -{ - "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "format": "mp3", - "quality": "128" -} -``` - -**Response:** -```json -{ - "success": true, - "message": "Processing started", - "fileName": "550e8400-e29b-41d4-a716-446655440000", - "downloadUrl": null, - "videoDetails": null -} -``` - -### 2. Monitor Progress -```http -GET /api/video/status/550e8400-e29b-41d4-a716-446655440000 -``` - -**Response (Processing):** -```json -{ - "percentageComplete": 45, - "status": "Processing", - "message": "Downloading audio...", - "videoDetails": { - "id": "dQw4w9WgXcQ", - "title": "Rick Astley - Never Gonna Give You Up", - "thumbnailUrl": "https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" - } -} -``` - -### 3. Get Final Result -```http -GET /api/video/result/550e8400-e29b-41d4-a716-446655440000 -``` - -**Response:** -```json -{ - "success": true, - "message": "Video processed successfully", - "fileName": "550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3", - "downloadUrl": "/downloads/550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3", - "videoDetails": { ... } -} -``` - -### 4. Download File -```http -GET /api/download/550e8400-e29b-41d4-a716-446655440000 -``` -**Response:** Binary MP3 file download with user-friendly filename -**Download Name:** `Rick Astley Never Gonna Give You Up.mp3` - -**Alternative Static File Access:** -```http -GET /downloads/550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3 -``` - -## File Management - -### Download Directory -- **Location**: `wwwroot/downloads/` -- **Naming Pattern**: `{jobId}_{title}.ext` -- **Job Lookup**: Files found using `Directory.GetFiles(dir, "{jobId}_*.*")` -- **User Download**: Converted back to readable names -- **Cleanup**: Files can be deleted by job ID - -### File Serving Options -1. **API Download**: Controlled access via `/api/download/{jobId}` (recommended) - - Uses job ID for secure file lookup - - Returns user-friendly filename - - Proper error handling -2. **Static Files**: Direct access via `/downloads/{actual_filename}` - - Requires knowing the full filename - - Less secure but faster -3. **Content-Type**: Automatic detection based on file extension - -### File Operations by Job ID -- **Find**: `GET /api/download/info/{jobId}` - Get file metadata -- **Download**: `GET /api/download/{jobId}` - Download the file -- **Delete**: `DELETE /api/download/{jobId}` - Remove the file - -## Progress Monitoring - -The VideoService monitors yt-dlp output and translates it to progress updates: - -- **5-15%**: Fetching video details -- **15-70%**: Downloading audio (yt-dlp download progress × 0.7) -- **70-85%**: Converting to MP3 (ffmpeg processing) -- **85-95%**: Finalizing (cleanup) -- **100%**: Complete - -## Error Handling - -### Common Errors: -1. **yt-dlp.exe not found**: Ensure yt-dlp.exe is in wwwroot directory -2. **ffmpeg not available**: Install ffmpeg and add to PATH -3. **Invalid YouTube URL**: URL format validation -4. **Download timeout**: 5-minute timeout for processing -5. **File not found**: File may have been cleaned up or job ID invalid - -### Error Response Format: -```json -{ - "success": false, - "message": "Error description", - "fileName": null, - "downloadUrl": null, - "videoDetails": null -} -``` - -## Configuration - -### appsettings.json -```json -{ - "Logging": { - "LogLevel": { - "TuneRipper.Api.Services.VideoService": "Debug" - } - } -} -``` - -### yt-dlp Arguments Used: -- `--extract-audio`: Extract audio only -- `--audio-format mp3`: Convert to MP3 -- `--audio-quality 0`: Best quality -- `--no-playlist`: Single video only -- `--no-warnings`: Clean output -- `--newline`: Line-by-line progress -- `--output "{jobId}_{title}.%(ext)s"`: Uses job ID-based filename - -## Testing - -### Manual Testing: -1. Start the API: `dotnet run --project TuneRipper.Api` -2. Use API testing tools or the Blazor client -3. Check logs for yt-dlp progress -4. Verify files in `wwwroot/downloads/` with GUID-based naming - -### Example Test Files: -``` -wwwroot/downloads/ -??? 550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3 -??? 6ba7b810-9dad-11d1-80b4-00c04fd430c8_How_to_Build_a_Web_API.mp3 -??? 6ba7b811-9dad-11d1-80b4-00c04fd430c8_Amazing_Guitar_Solo_Performance.mp3 -``` - -### Health Check: -```http -GET /api/health -``` - -### Job Listing: -```http -GET /api/video/jobs -``` - -## Production Considerations - -1. **File Storage**: Consider cloud storage for production -2. **Cleanup Strategy**: Implement automatic file cleanup/retention using job completion timestamps -3. **Security**: Job IDs provide secure file access (no directory traversal) -4. **Performance**: Consider queue-based processing for high load -5. **Monitoring**: Add detailed logging and metrics -6. **Updates**: Keep yt-dlp.exe updated for compatibility -7. **Scalability**: GUID-based naming prevents conflicts in distributed systems - -## Troubleshooting - -### Common Issues: -1. **Permissions**: Ensure API can write to wwwroot/downloads -2. **Antivirus**: yt-dlp.exe may be flagged by antivirus -3. **Network**: YouTube may block requests from some IPs -4. **Format Support**: Some videos may not support audio extraction -5. **Long Titles**: Titles are truncated to 50 characters for filesystem compatibility - -### Debug Logging: -Enable debug logging for VideoService to see detailed yt-dlp output: -```json -{ - "Logging": { - "LogLevel": { - "TuneRipper.Api.Services.VideoService": "Debug" - } - } -``` - -### File Lookup Issues: -- Verify job ID matches the GUID format -- Check that files exist with the `{jobId}_` prefix -- Look at directory contents if files are not found -- Ensure proper case sensitivity on Linux systems - -### Advantages of GUID-Based Naming: -1. **Unique**: No filename conflicts possible -2. **Secure**: Job ID acts as access token -3. **Traceable**: Direct mapping from API calls to files -4. **Scalable**: Works in distributed environments -5. **Clean**: Easy cleanup by job ID pattern \ No newline at end of file diff --git a/TuneRipper.Api/web.config b/TuneRipper.Api/web.config new file mode 100644 index 0000000..6bbda9b --- /dev/null +++ b/TuneRipper.Api/web.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TuneRipper/web.config b/TuneRipper/web.config new file mode 100644 index 0000000..3d1a485 --- /dev/null +++ b/TuneRipper/web.config @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file