This repository provides a complete, automated infrastructure-as-code solution for hosting Umami, a privacy-focused, open-source web analytics platform, in Microsoft Azure. Designed as a modern alternative to Google Analytics, this setup prioritizes data privacy, security, and full organizational control over analytics data.
The entire deployment is orchestrated using Azure Bicep templates, ensuring reproducible, maintainable, and scalable infrastructure provisioning.
- π§ Infrastructure as Code: All resources defined using Azure Bicep for maintainable, version-controlled infrastructure
- π³ Containerized Deployment: Umami runs on Azure App Service with Linux containers for optimal performance and scalability
- π Network Security: Isolated deployment using Azure Virtual Networks with private DNS and secure connectivity
- π Hybrid Connectivity: Point-to-Site VPN Gateway with Azure AD authentication for secure on-premises access
- π DNS Resolution: Azure DNS Private Resolver for seamless name resolution between on-premises and Azure resources
- π Custom Domain Support: Automated custom domain configuration with SSL certificates and DNS management
- π Privacy-First Analytics: Complete data ownership with GDPR-compliant analytics platform
This solution is perfect for organizations seeking enterprise-grade analytics without compromising on data privacy or control.
- Azure CLI installed and configured
- Active Azure subscription with appropriate permissions
-
Authenticate with Azure
az login
-
Deploy the Networking Infrastructure
az deployment sub create --location <your-azure-region> -f ./deployNetwork.bicep -p ./parameters/network/local.bicepparam
Replace
<your-azure-region>with your preferred Azure region (e.g.,swedencentral) -
Deploy the Azure Key Vault
az deployment sub create --location <your-azure-region> -f ./deployKeyVault.bicep -p ./parameters/keyvault/local.bicepparam
-
Upload Secrets to Azure Key Vault
After Key Vault is deployed, upload your secrets before deploying the application infrastructure:
./sync-keyvault-secrets.sh <your-keyvault-name> [.env.keyvault]
Fill in
.env.keyvaultwith your secret values before running the script. -
Deploy the Application Infrastructure
az deployment sub create --location <your-azure-region> -f ./deployApplication.bicep -p ./parameters/application/local.bicepparam
-
Configure Custom Domain (Optional)
If you want to use a custom domain instead of the default Azure App Service URL:
# Deploy custom domain configuration az deployment group create --resource-group <your-resource-group> -f ./deployCustomDomains.bicep --parameters umamiAppServiceName=<your-app-service-name> customDomainName=<your-domain.com>
For Cloudflare DNS management, see the Custom Domain Setup section below.
-
Resource Provisioning
The deployments will provision:
- Azure Virtual Network with private endpoints and DNS Private Resolver
- Point-to-Site VPN Gateway with Azure AD authentication
- Azure Key Vault for secure secret management
- Azure App Service with Linux container (secrets injected from Key Vault)
- PostgreSQL Flexible Server database
- Supporting networking infrastructure
β οΈ Environment Notice: This configuration currently deploys a local/development environment. Production and staging environments will be supported in future releases.
For local development and testing, you can run Umami using Docker Compose. The Docker Compose configuration is based on the official Umami repository with minor modifications for increased reusability and flexibility.
- Docker and Docker Compose installed
- Git for cloning the repository
-
Clone the repository
git clone https://github.com/Physer/umami-setup cd umami-setup -
Configure environment variables
cp .env.example .env
Edit the
.envfile with your configuration:- Set database credentials
- Configure application settings
- Adjust any other environment-specific variables
-
Start the services
docker compose up -d
-
Access Umami
Once started, Umami will be available at
http://localhost:3000 -
Stop the services
docker compose down
This project integrates Azure Key Vault for secure, centralized management of application secrets and sensitive configuration values. The Key Vault is protected by a private endpoint, restricting access to only resources and users on the private network.
Secrets are not stored in source control or parameter files, but are managed directly in Azure Key Vault and injected into the application at runtime.
- Secrets required by Umami (such as database credentials, API keys, etc.) are stored in Azure Key Vault.
- The infrastructure and App Service are configured to reference these secrets securely using managed identity.
- A helper script,
sync-keyvault-secrets.sh, is provided to automate uploading secrets from a local file to your Azure Key Vault.
You can quickly sync secrets from a local .env.keyvault file to your Azure Key Vault using the provided script.
Note: Because the Key Vault is protected by a private endpoint, you must run the script from a machine with network access to the private subnet (e.g., via VPN or a VM in the same network). This is especially useful for initial setup or when rotating secrets.
Copy the provided .env.keyvault.example file to .env.keyvault in the project root. Each line should be in KEY=VALUE format. The example file lists all required secret keysβfill in the values for your environment.
Make sure you are logged in to Azure CLI and have access to the target Key Vault:
az loginThen run the script, specifying your Key Vault name (and optionally the env file):
./sync-keyvault-secrets.sh <your-keyvault-name> [.env.keyvault]Example:
./sync-keyvault-secrets.sh my-keyvault-devThe script will upload each secret to the specified Key Vault. It will report any failures and a summary at the end.
Note: The script requires Bash (Linux/macOS or WSL on Windows) and Azure CLI installed.
The Bicep templates are designed to reference secrets from Key Vault using the @Microsoft.KeyVault syntax in parameter files, or by configuring App Service to use Key Vault references for environment variables.
Example parameter reference:
param umamiAppSecret string = '@Microsoft.KeyVault(SecretUri=https://<your-keyvault-name>.vault.azure.net/secrets/umamiAppSecret/)'No secrets are stored in source control or plain text parameter files.
The infrastructure includes a Point-to-Site VPN Gateway that enables secure connectivity from on-premises machines to the Azure Virtual Network. This allows direct access to private resources and seamless integration with existing corporate networks.
- π Azure AD Authentication: Secure authentication using your organization's Azure Active Directory
- π OpenVPN Protocol: Modern, secure VPN protocol with cross-platform client support
- π DNS Resolution: Integrated DNS Private Resolver for seamless name resolution between on-premises and Azure
- π± Multi-Platform Support: Compatible with Windows, macOS, iOS, and Android devices
-
Download VPN Client Configuration
After deployment, download the VPN client configuration from the Azure portal:
# Get the VPN client configuration URL az network vnet-gateway vpn-client generate --name <gateway-name> --resource-group <resource-group> --authentication-method EAPTLS
-
Install VPN Client
- Windows/macOS/Linux: Use the Azure VPN Client or OpenVPN client
- Mobile: Use the Azure VPN Client app from your device's app store
-
Import Configuration
Import the downloaded configuration file into your VPN client and connect using your Azure AD credentials.
The DNS Private Resolver automatically handles name resolution for:
- Azure private endpoints (PostgreSQL, App Service)
- On-premises resources (forwarded to your corporate DNS)
- Cross-network connectivity scenarios
π‘ Note: VPN connectivity is particularly useful for development teams, database administration, and secure access to private Azure resources without exposing them to the public internet.
The infrastructure supports custom domain configuration with automated SSL certificate provisioning through Azure App Service Managed Certificates. This allows you to access your Umami instance using your own domain name with HTTPS encryption.
- π Automatic SSL Certificates: Azure-managed SSL certificates with automatic renewal
- π DNS Integration: Automated Cloudflare DNS record management scripts
- π§ Bicep Automation: Infrastructure-as-code approach for domain configuration
- β‘ Easy Deployment: Simple command-line deployment of custom domain resources
-
Verify Domain Ownership
Before deploying, ensure you have administrative access to your domain's DNS settings.
-
Deploy Custom Domain Infrastructure
az deployment group create --resource-group <your-resource-group> -f ./deployCustomDomains.bicep --parameters umamiAppServiceName=<your-app-service-name> customDomainName=<your-domain.com>
-
Configure DNS Records
For Cloudflare users, automated scripts are provided to manage DNS records:
# Create .env.cloudflare from the example template cp .env.cloudflare.example .env.cloudflare # Edit .env.cloudflare with your Cloudflare API token and Zone ID # Create/update DNS record pointing to your App Service ./create-cloudflare-dns-records.sh <your-domain.com> CNAME <your-app-service>.azurewebsites.net # Enable Cloudflare proxy (optional) ./proxy-cloudflare-dns-records.sh <your-domain.com> on
The project includes specialized scripts for Cloudflare DNS management:
- Cloudflare API Token: Create an API token with
Zone:Editpermissions for your domain - Zone ID: Your Cloudflare Zone ID for the target domain
- jq: JSON processor tool for parsing API responses
create-cloudflare-dns-records.sh: Creates or updates DNS records (CNAME, A, etc.)proxy-cloudflare-dns-records.sh: Toggles Cloudflare proxy status for enhanced security and performance
-
Create Cloudflare Configuration
cp .env.cloudflare.example .env.cloudflare
-
Edit Configuration File
Add your Cloudflare credentials:
CLOUDFLARE_API_TOKEN=your_api_token_here ZONE_ID=your_zone_id_here
-
Use the Scripts
# Create a CNAME record ./create-cloudflare-dns-records.sh subdomain.yourdomain.com CNAME your-app-service.azurewebsites.net # Enable Cloudflare proxy for additional security ./proxy-cloudflare-dns-records.sh subdomain.yourdomain.com on
π‘ Best Practice: Enable Cloudflare proxy after DNS propagation for additional DDoS protection, CDN benefits, and enhanced security features.
- β Automated Infrastructure Provisioning β Complete resource deployment using Bicep templates
- β Azure Key Vault Integration β Centralized, secure management of all application secrets and sensitive configuration values
- β Secret Automation Script β Easily sync secrets from local files to Azure Key Vault using the provided script
- β Azure CLI Integration β Streamlined deployment via command-line interface with parameter files
- β Virtual Network Security β Isolated network architecture with private endpoint connectivity
- β Hybrid Connectivity β Point-to-Site VPN Gateway with Azure AD authentication for secure on-premises access
- β DNS Resolution β Azure DNS Private Resolver for seamless name resolution between networks
- β Custom Domain Support β Automated custom domain configuration with Azure-managed SSL certificates
- β Cloudflare Integration β Specialized scripts for automated Cloudflare DNS record management
- β Container-Based Hosting β Modern Linux container deployment on Azure App Service, with secrets injected securely from Key Vault
- β Local Development Setup β Docker Compose configuration for streamlined local development and testing
- β Application Monitoring β Azure Application Insights integration for comprehensive observability
The following enhancements are planned to expand and improve the platform:
- π CI/CD Automation β Automated deployment pipelines for staging and production environments
- β Secrets Management β Azure Key Vault integration for secure credential handling (Completed)
- β Custom Domains β Support for custom domain configuration via Bicep automation (Completed)
- β Cloudflare DNS Management β Automated DNS record creation and proxy configuration (Completed)
- π‘οΈ Access Control β IP whitelisting and Entra ID managed identity integration
- π Site-to-Site VPN β Extension to support site-to-site VPN connections for branch offices
- π‘ ExpressRoute Integration β Support for dedicated network connections via Azure ExpressRoute
- π Secret Rotation Automation β Automated workflows for rotating and syncing secrets between environments
- β‘ Zero-Downtime Updates β Sidecar deployment pattern implementation
- π Enhanced Security β Advanced network isolation and access restrictions
For questions, issues, or contributions, please open an issue in this repository.
This project is open-source. Please review the license file for details.