A production-ready API built with Hono.js designed for deployment to Azure Container Apps using GitHub Container Registry.
- β‘ Hono.js - Ultra-fast web framework
- π³ Docker - Multi-stage builds for optimal image size
- π¦ GitHub Container Registry - Free private container registry
- βοΈ Azure Container Apps - Serverless container hosting with auto-scaling
- π CORS & Logger - Built-in middleware
- πͺ TypeScript - Full type safety
- Node.js 20+
- Docker Desktop
- Azure CLI or Azure PowerShell module
- GitHub account
npm installnpm run devThe API will be available at http://localhost:3000
- Health Check:
http://localhost:3000/health - Chat:
POST http://localhost:3000/api/chat - User Profile:
GET/POST http://localhost:3000/api/user/profile - Studio:
POST http://localhost:3000/api/studio/generate - Scripts:
GET http://localhost:3000/api/scripts/list - Script Processing:
POST http://localhost:3000/api/script/process
Create a .env file with the following variables:
PORT=3000
DATABASE_URL=postgres://user:pass@host:port/db
# For Azure Foundry / model-specific keys, set one of the following depending on your deployment:
# AZURE_FOUNDRY_KEY=your_foundry_key
# AZURE_FOUNDRY_CONTENT_ENDPOINT=https://<your-foundry-endpoint>/openai/deployments/gpt-4o-mini
# OR
# MISTRAL_API_KEY=your_mistral_key
# MISTRAL_ENDPOINT=https://<your-mistral-endpoint>
AZURE_STORAGE_CONNECTION_STRING=your_storage_connection_string
AZURE_TTS_KEY=your_tts_key
AZURE_TTS_REGION=swedencentral
FIREBASE_PROJECT_ID=your_project_id
FIREBASE_CLIENT_EMAIL=your_client_email
FIREBASE_PRIVATE_KEY=your_private_keynpm run docker:buildnpm run docker:runOn every push to master, the workflow in .github/workflows/build-and-push-ghcr.yml will:
- Build and push the Docker image to GHCR
- Deploy the newly built image to Azure Container Apps
Add these in GitHub β Settings β Secrets and variables β Actions:
Azure auth (Option A)
AZURE_CREDENTIALS(service principal JSON)
GHCR
GHCR_PAT(must have at leastread:packages; used both for pushing and for Azure pulls)
Notes:
- The workflow deploys the immutable tag
${GITHUB_SHA}(and also publishes:latest). - This removes the need to paste a PAT on every manual deploy.
-
Create a GitHub Personal Access Token:
- Go to https://github.com/settings/tokens/new
- Select scope:
write:packages - Generate token and save it
-
Login to GitHub Container Registry:
$env:CR_PAT = "your_token_here"
echo $env:CR_PAT | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdinEdit both build-and-push.ps1 and deploy-to-azure.ps1:
$GITHUB_USERNAME = "your-github-username" # Replace with your GitHub username.\build-and-push.ps1This will:
- Build the Docker image
- Push it to GitHub Container Registry
First, ensure you're logged in to Azure:
Connect-AzAccountThen deploy:
.\deploy-to-azure.ps1This will:
- Create an Azure Container Apps environment (if needed)
- Deploy your container
- Configure ingress and scaling
- Output your application URL
GET /- API informationGET /health- Health check
GET /api/hello?name=World- Hello endpointPOST /api/echo- Echo JSON bodyGET /api/profile- Protected endpoint (requires Authorization header)
The /api/profile endpoint demonstrates authentication. To add real authentication:
- Firebase Auth: Add
firebase-adminand validate tokens - Azure AD: Use Azure Easy Auth configuration
- Custom JWT: Validate tokens in middleware
Example with Authorization header:
curl -H "Authorization: Bearer your-token" https://your-app.azurewebsites.net/api/profilefraza-hono-api/
βββ src/
β βββ index.ts # Main API file
βββ Dockerfile # Multi-stage Docker build
βββ .dockerignore # Docker ignore patterns
βββ package.json # Dependencies and scripts
βββ tsconfig.json # TypeScript configuration
βββ build-and-push.ps1 # Build and push to GHCR
βββ deploy-to-azure.ps1 # Deploy to Azure Container Apps
- Auto-scaling: Scales from 0 to 10 replicas based on load
- Zero to Scale: Reduces costs by scaling to zero when idle
- HTTPS: Automatic SSL certificates
- Health Checks: Built-in health monitoring
- Rolling Updates: Zero-downtime deployments
Set in Azure Container Apps:
az containerapp update \
--name fraza-hono-api \
--resource-group fraza_dev \
--set-env-vars "NODE_ENV=production" "API_KEY=secret"Make sure your package is public:
- Go to https://github.com/users/YOUR_USERNAME/packages
- Select your package
- Click "Package settings" β "Change visibility" β "Public"
Use Azure PowerShell module instead:
Install-Module -Name Az -Repository PSGallery -Force
Connect-AzAccountCheck logs:
az containerapp logs show \
--name fraza-hono-api \
--resource-group fraza_dev \
--followMIT