In my previous post, I introduced Dependency-Track and explained why we chose it to manage our software supply chain security. Now it's time to get practical. In this post, I'll walk you through how we deployed Dependency-Track on Azure Container Apps, including our architecture decisions, configuration choices, and lessons learned along the way.
Why Azure Container Apps?
Before diving into the setup, let me explain why we chose Azure Container Apps for hosting Dependency-Track. We evaluated several deployment options including Azure Kubernetes Service (AKS), Azure Container Instances (ACI), and App Service, but Container Apps emerged as the best fit for our needs:
Simplified Management: Container Apps abstracts away much of the complexity of Kubernetes while still providing container orchestration capabilities. We don't need to manage nodes, clusters, or complex networking configurations.
Cost-Effective: With built-in autoscaling and the ability to scale to zero for non-production environments, Container Apps helps us optimize costs without sacrificing performance.
Azure Integration: Integration with Azure services like Azure Database for PostgreSQL, Key Vault, and Azure Monitor made our deployment more secure and observable.
HTTPS Out of the Box: Automatic HTTPS certificate provisioning and management eliminated the need for additional ingress configuration.
Architecture Overview
Our Dependency-Track deployment on Azure Container Apps consists of three main components:
- API Server Container App: Runs the Dependency-Track API server, which handles all business logic, vulnerability processing, and API requests
- Frontend Container App: Serves the web UI(only static assets) as a separate container
- Azure Database for PostgreSQL: Managed database service that stores all Dependency-Track data
We also use:
- Azure Key Vault: For storing sensitive configuration like database credentials and API keys
- Docker Hub: For consuming the Dependency Track container images
- Azure Monitor: For logging and monitoring
- Azure Storage Account: For persistent storage of vulnerability data mirrors
Prerequisites
Before starting, ensure you have:
- An Azure subscription with appropriate permissions
- Azure CLI installed and configured
- A resource group created for your deployment
Remark: I’ll share a simplied version of our real setup as we don’t expose our Dependency Track externally and use a VNET to expose the tool internally
Step 1: Create the PostgreSQL Database
Dependency-Track requires PostgreSQL 11 or later. We'll use Azure Database for PostgreSQL Flexible Server:
Important: Store the database password securely. We'll add it to Key Vault in the next step.
Step 2: Set Up Azure Key Vault Store sensitive configuration in Key Vault:
Step 3: Create Container Apps Environment
The Container Apps Environment is a secure boundary around our container apps:
Step 4: Create Storage for Vulnerability Data
Dependency-Track mirrors vulnerability databases. We'll use Azure Files for persistent storage
Step 5: Deploy the API Server
Now we'll deploy the Dependency-Track API server container app:
Step 6: Deploy the Frontend
The frontend serves the web UI and communicates with the API server:
Step 7: Initial Configuration
After deployment, access the Dependency-Track UI:
- Get the frontend URL:
- Log in with default credentials:
- Username:
admin - Password:
admin
- Immediately change the admin password via the UI (Administration → Access Management → Users):
- Configure vulnerability data sources (Administration → Vulnerability Sources):
- Enable NVD mirroring:
- Optionally also enable GitHub Advisories (requires a GitHub PAT):
- Configure analyzers
- Enable SonaType OSS Index analyzer (requires API token from sonatype.com):
Configuration Best Practices
Based on our experience, here are some configuration recommendations:
Performance Tuning
For the API server, adjust these environment variables based on your load:
ALPINE_WORKER_THREADS: Set to 2-4 for typical workloadsALPINE_WORKER_THREAD_MULTIPLIER: Set to 4-8 depending on CPU coresALPINE_DATABASE_POOL_MAX_SIZE: Start with 20 and adjust based on connection metrics
Security Hardening
- Enable Azure AD Authentication: Configure OIDC integration with Azure AD for centralized identity management (I’ll leave that for the next post)
- Use Private Endpoints: As I mentioned for production, use VNet integration and private endpoints to keep traffic internal
What's next?
Now that you have Dependency-Track up and running on Azure Container Apps, the next step is integrating it into your CI/CD pipelines. In the final post of this series, I'll show you how to:
- Generate SBOMs automatically in your build pipelines
- Upload SBOMs to Dependency-Track via the API
- Implement policy checks that can fail builds
- Set up automated notifications for new vulnerabilities




