Skip to content

Store uploads in Azure Blob Storage - #8

Merged
MomoSolaris8 merged 3 commits into
mainfrom
azure-blob-storage
Oct 30, 2026
Merged

MomoSolaris8 merged 3 commits into
mainfrom
azure-blob-storage

Conversation

@MomoSolaris8

@MomoSolaris8 MomoSolaris8 commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

This PR adds Azure Blob Storage as a file storage backend, so uploaded images survive restarts of the backend.

Why

  • The Azure Container App runs with FILE_STORAGE_PROVIDER=local, so uploads are written to the container's filesystem.
  • That filesystem is temporary. When the app scales to zero or restarts, every uploaded file is lost, but the uploaded_files rows still point to them.

What changed

  • New AzureBlobObjectStorage in storage/service.py, selected with FILE_STORAGE_PROVIDER=azure
  • Two ways to sign in:
    • Local development and tests use Azurite through AZURE_STORAGE_CONNECTION_STRING.
    • In Azure, the app signs in as its managed identity through DefaultAzureCredential, so there is no storage key anywhere.
  • Uploading to an existing key overwrites it, the same as the Supabase backend
  • Azurite added to docker-compose.yml for local development
  • New dependencies: azure-storage-blob, azure-identity

Testing

  • 5 integration tests against Azurite:
    • an upload can be read back
    • the content type is stored
    • uploading to the same key overwrites it
    • reading a missing key raises ResourceNotFoundError
    • get_storage("azure") returns the new backend
  • CI now runs the storage integration tests and only skips the Supabase one, which needs real credentials.
  • CI starts Azurite with docker run rather than as a service container, because services can't take --skipApiVersionCheck. Without that flag, Azurite 3.34.0 rejects the API version used by azure-storage-blob 12.31.

Deployment

Already created in rg-supportagent-dev:

  • Storage account stsupportagentdev in Sweden Central: no public blob access, TLS 1.2, shared key access disabled
  • Container uploads
  • The Storage Blob Data Contributor role for the app's identity id-supportagent-dev, scoped to the uploads container only

After this PR is merged and deployed, set these on the Container App:

  • FILE_STORAGE_PROVIDER=azure
  • AZURE_STORAGE_ACCOUNT_URL=https://stsupportagentdev.blob.core.windows.net
  • AZURE_STORAGE_CONTAINER=uploads
  • AZURE_CLIENT_ID = the client ID of id-supportagent-dev. The app uses a user-assigned identity, so DefaultAzureCredential needs to be told which one to use.

Deploy the code before changing the config. The running code doesn't know the azure provider, so switching the config first would make every upload fail.

There are no existing files to copy, because uploaded_files is empty in the dev database.

Follow-ups (not in this PR)

  • Remove SupabaseObjectStorage and its test once Supabase is gone for good
  • upload_image is an async endpoint but makes blocking storage, LLM and database calls

@vercel

vercel Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
support-agent-one-coyl Ready Ready Preview Oct 30, 2026 1:03pm UTC

@MomoSolaris8
MomoSolaris8 marked this pull request as ready for review October 30, 2026 13:13
@MomoSolaris8
MomoSolaris8 merged commit 377b4eb into main Oct 30, 2026
6 checks passed
@MomoSolaris8
MomoSolaris8 deleted the azure-blob-storage branch October 30, 2026 13:14

This branch was successfully deployed

1 active deployment
Preview — 14bf9a31 Deployed Oct 30, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant