Here’s a quick thing about how much I like using Make.
When working with Umbraco and Astro, I found myself lazily hating having to start separate consoles for both Umbraco and Astro, and remembering to start Umbraco before Astro and so on.
I’ve started using Make to automate this and it’s honestly been a joy.
Here’s the script I use for my local dev. It starts Umbraco, waits for it to be ready, runs the Orval typescript generator (just in case I’ve done some new Umbraco stuff) and then runs the Astro front-end.
While the default is to run all the commands, you can also just run each part separately.
# Port configurationBACKEND_HTTP_PORT = 48006BACKEND_HTTPS_PORT = 44385FRONTEND_PORT = 4321HEALTH_CHECK_ENDPOINT = umbraco/swagger
.PHONY: dev backend frontend wait-for-backend kill-backend-ports clean help
# Default target - start both backend and frontenddev: kill-backend-ports backend wait-for-backend orval frontend
# Kill any processes using backend portskill-backend-ports: @echo "Checking for processes on backend ports ($(BACKEND_HTTP_PORT), $(BACKEND_HTTPS_PORT))..." @powershell -Command "\ $$ports = @($(BACKEND_HTTP_PORT), $(BACKEND_HTTPS_PORT)); \ $$killed = $$false; \ foreach ($$port in $$ports) { \ $$connections = Get-NetTCPConnection -LocalPort $$port -ErrorAction SilentlyContinue; \ if ($$connections) { \ foreach ($$conn in $$connections) { \ $$processId = $$conn.OwningProcess; \ $$process = Get-Process -Id $$processId -ErrorAction SilentlyContinue; \ if ($$process) { \ Write-Host \"Killing process $$($$process.ProcessName) (PID: $$processId) on port $$port\"; \ Stop-Process -Id $$processId -Force -ErrorAction SilentlyContinue; \ $$killed = $$true; \ } \ } \ } \ } \ if (-not $$killed) { \ Write-Host 'No processes found on backend ports.'; \ } else { \ Write-Host 'Ports cleared. Waiting for cleanup...'; \ Start-Sleep -Seconds 2; \ } \ "
# Start the backend Umbraco applicationbackend: @echo "Starting Umbraco backend..." @powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd Backend; dotnet run --project DeveloperBlog.Umbraco/DeveloperBlog.Umbraco.csproj'"
# Wait for backend to respond at the Umbraco health check endpointwait-for-backend: @echo "Waiting for backend to be ready..." @powershell -Command "\ $$healthUrl = 'http://localhost:$(BACKEND_HTTP_PORT)/$(HEALTH_CHECK_ENDPOINT)'; \ $$maxAttempts = 60; \ $$attempt = 0; \ while ($$attempt -lt $$maxAttempts) { \ try { \ $$response = Invoke-WebRequest -Uri $$healthUrl -UseBasicParsing -TimeoutSec 2 -ErrorAction Stop; \ if ($$response.StatusCode -eq 200) { \ Write-Host 'Backend is ready (health check passed)!'; \ exit 0; \ } \ } catch { \ Write-Verbose \"Waiting for backend to respond...\"; \ } \ $$attempt++; \ if ($$attempt -lt $$maxAttempts) { \ Write-Host \"Attempt $$attempt/$$maxAttempts - waiting for backend health check...\"; \ Start-Sleep -Seconds 2; \ } else { \ Write-Host 'ERROR: Timeout waiting for backend after $$($$maxAttempts * 2) seconds'; \ exit 1; \ } \ }"
# Call the Orval client to generate the TS clientorval: @echo "Calling Orval..." @powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd Frontend; pnpm run umb-ts-generate'"
# Start the frontend Astro applicationfrontend: @echo "Starting Astro frontend..." @powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd Frontend; pnpm run dev'"
# Clean up - kill both backend and frontend processesclean: @echo "Stopping all backend and frontend processes..." @powershell -Command "\ $$ports = @($(BACKEND_HTTP_PORT), $(BACKEND_HTTPS_PORT), $(FRONTEND_PORT)); \ foreach ($$port in $$ports) { \ $$connections = Get-NetTCPConnection -LocalPort $$port -ErrorAction SilentlyContinue; \ if ($$connections) { \ foreach ($$conn in $$connections) { \ $$processId = $$conn.OwningProcess; \ $$process = Get-Process -Id $$processId -ErrorAction SilentlyContinue; \ if ($$process) { \ Write-Host \"Stopping $$($$process.ProcessName) (PID: $$processId) on port $$port\"; \ Stop-Process -Id $$processId -Force -ErrorAction SilentlyContinue; \ } \ } \ } \ } \ Write-Host 'All processes stopped.'; \ "
# Show available commandshelp: @echo "Available commands:" @echo " make dev - Start backend, wait for it, then start frontend" @echo " make backend - Start only the backend Umbraco application" @echo " make frontend - Start only the frontend Astro application" @echo " make kill-backend-ports - Kill processes on backend ports ($(BACKEND_HTTP_PORT), $(BACKEND_HTTPS_PORT))" @echo " make clean - Stop all backend and frontend processes" @echo " make help - Show this help message"Enjoy!