Makefile for Umbraco v17 and Astro

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 configuration
BACKEND_HTTP_PORT = 48006
BACKEND_HTTPS_PORT = 44385
FRONTEND_PORT = 4321
HEALTH_CHECK_ENDPOINT = umbraco/swagger
.PHONY: dev backend frontend wait-for-backend kill-backend-ports clean help
# Default target - start both backend and frontend
dev: kill-backend-ports backend wait-for-backend orval frontend
# Kill any processes using backend ports
kill-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 application
backend:
@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 endpoint
wait-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 client
orval:
@echo "Calling Orval..."
@powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd Frontend; pnpm run umb-ts-generate'"
# Start the frontend Astro application
frontend:
@echo "Starting Astro frontend..."
@powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd Frontend; pnpm run dev'"
# Clean up - kill both backend and frontend processes
clean:
@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 commands
help:
@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!