Developer Setup
The recommended development environment is a VS Code Dev Container (or GitHub Codespace). The .devcontainer/ configuration installs all required tooling automatically - no manual setup needed.
Opening the dev container
Section titled “Opening the dev container”- Open this repository in VS Code.
- When prompted “Reopen in Container”, click Reopen in Container.
- Or use the command palette:
Dev Containers: Reopen in Container.
- Or use the command palette:
- Wait for the container to build and the post-create/post-start scripts to finish.
The container is based on mcr.microsoft.com/devcontainers/typescript-node:22 and includes:
| Tool | Version | Purpose |
|---|---|---|
| Node.js | 22 LTS | JavaScript runtime |
| pnpm | 10.x | Package manager (workspaces) |
| Nx | 22.x | Monorepo task runner |
| Python | 3.12 | Pexip SDK and VM scripts |
| UV | latest | Python dependency management |
| Azure CLI | latest | Azure resource management |
| Azure Functions Core Tools | v4 | Local Function App development |
GitHub CLI (gh) | latest | PR and issue management |
| Azurite | latest | Local Azure Storage emulator |
Post-create: what happens automatically
Section titled “Post-create: what happens automatically”The setup.sh script runs once when the container is first created:
npm install -g nx pnpm azurite # Global CLI toolspip install uv # Python package managerpnpm install # Node dependenciesuv sync # Python dependenciesPost-start: authentication checks
Section titled “Post-start: authentication checks”Every time the container starts, post-start.sh runs and reports auth status:
==> GitHub CLI status gh is authenticated ✓
==> Azure CLI status az is authenticated ✓ (subscription: ...)If either is not authenticated, follow the prompts:
# GitHubgh auth login
# Azure (use device code flow in containers)az login --use-device-codeCommon commands
Section titled “Common commands”Nx is installed globally, so you do not need a pnpm prefix:
# Documentation sitenx run docs:dev # Dev server on :4321nx run docs:build # Production build
# Onboarding sitenx run onboarding:dev # Dev server on :4322
# Pexip SDK (Function App)nx run pexip-sdk:serve # Local Function App on :7071nx run pexip-sdk:test # Run Python testsnx run pexip-sdk:lint # Ruff linting
# VM Start/Stopnx run vm-start-stop:test
# Workspace-widenx graph # Dependency graph visualizationnx run-many -t lint # Lint all projectsnx run-many -t test # Test all projectsForwarded ports
Section titled “Forwarded ports”The dev container automatically forwards these ports:
| Port | Service |
|---|---|
| 4321 | Docs site |
| 4322 | Onboarding site |
| 7071 | Azure Functions (local) |
| 10000–10002 | Azurite (Blob, Queue, Table) |
Running the Function App locally
Section titled “Running the Function App locally”Before starting, ensure packages/pexip-sdk/local.settings.json exists and is complete (see below).
# From the repository rootnx run pexip-sdk:serveOnce running, the interactive OpenAPI docs (Swagger UI) are available at http://localhost:7071/docs.
This is auto-generated by FastAPI and reflects the current state of all endpoints, request/response schemas, and query parameters. Use it for:
- Exploring available endpoints without reading source code
- Testing API calls interactively with the “Try it out” feature
- Viewing the raw OpenAPI spec at
http://localhost:7071/openapi.json
Environment variables for local Function App
Section titled “Environment variables for local Function App”Create packages/pexip-sdk/local.settings.json (this file is git-ignored). All fields below are required — the Function App will fail to start if any are missing.
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage__accountName": "samaxconftest", "QUEUE_URL": "https://samaxconftest.queue.core.windows.net", "FUNCTIONS_WORKER_RUNTIME": "python", "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", "KEYVAULT_URL": "https://kvlt-maxconf-test.vault.azure.net/", "AZURE_TENANT_ID": "953fc14a-00c7-4452-a2fb-0a73070de7f3", "PEXIP_CLIENT_ID": "<fetch from Key Vault: pexip-client-id>", "PEXIP_JWT_KEY": "<fetch from Key Vault: pexip-jwt-base64-token>", "LOG_ANALYTICS_WORKSPACE_ID": "<fetch from Key Vault: log-analytics-workspace-id>", "LOG_ANALYTICS_WORKSPACE_KEY": "<fetch from Key Vault: log-analytics-workspace-key>" }}Fetching secrets from Key Vault
Section titled “Fetching secrets from Key Vault”With az login active, you can pull the required secrets directly:
az keyvault secret show --vault-name kvlt-maxconf-test --name pexip-client-id --query value -o tsvaz keyvault secret show --vault-name kvlt-maxconf-test --name pexip-jwt-base64-token --query value -o tsvaz keyvault secret show --vault-name kvlt-maxconf-test --name log-analytics-workspace-id --query value -o tsvaz keyvault secret show --vault-name kvlt-maxconf-test --name log-analytics-workspace-key --query value -o tsvPaste the output of each command into the corresponding field in local.settings.json.
Storage authentication
Section titled “Storage authentication”AzureWebJobsStorage__accountName uses DefaultAzureCredential — no connection string is required. The dev container’s az login session satisfies this automatically provided you have at least Storage Queue Data Contributor on samaxconftest.
When to remove AZURE_CLIENT_ID and AZURE_CLIENT_SECRET
Section titled “When to remove AZURE_CLIENT_ID and AZURE_CLIENT_SECRET”For local development in the dev container, these settings should usually be omitted.
Remove them when all of the following are true:
- You can run
az loginin the container. - Your signed-in identity has data-plane access to the required resources (at minimum Storage Queue access on
samaxconftest; Key Vault access if resolving secrets directly). - You are not trying to validate behavior for a specific service principal.
Keep (or add) them only when one of the following is true:
- You are running in a non-interactive environment where
az loginis not available. - You must explicitly test with a specific service principal identity.
If AZURE_CLIENT_ID/AZURE_CLIENT_SECRET are set and the secret is invalid, DefaultAzureCredential will prefer ClientSecretCredential, causing errors such as AADSTS7000215 and Unable to access AzureWebJobsStorage.
Managing Python dependency split safely
Section titled “Managing Python dependency split safely”nx run pexip-sdk:* uses uv resolution from packages/pexip-sdk/pyproject.toml + uv.lock. Deployment paths may still consume packages/pexip-sdk/requirements.txt. Keep both in sync to avoid local-vs-deployed behavior drift.
Recommended workflow for dependency changes:
- Update
packages/pexip-sdk/pyproject.tomlfirst. - Run
uv lockfrom the repository root and commituv.lock. - Mirror runtime-sensitive pins in
packages/pexip-sdk/requirements.txt(for exampleauthlib). - Validate the resolved local version with
uv run python -c "import authlib; print(authlib.__version__)".
For this repository, authlib is pinned to 1.5.2 in both dependency files to avoid JWT key handling differences between local and deployed execution paths.
VS Code extensions
Section titled “VS Code extensions”The dev container pre-installs these extensions:
- Nx Console - Task explorer and project graph
- ESLint + Prettier - JavaScript/TypeScript formatting
- Ruff - Python linting and formatting
- Astro -
.astroand.mdxfile support - Azure Functions - Local debugging and deployment
- Azurite - Storage emulator management
- GitHub Copilot - AI pair programming