
I’m really enjoying developing with Aspire. Aspire is microsoft’s new development environment for developing Cloud based applications.
However, when dealing with components which use services like Azure Storage or Service Bus, it can get a little complex if you have some kind of interface swap so you can run storage-like or queue-like services locally.
This is where Azurite comes in. It’s a first class (as in recognised by microsoft and its tooling) simulator for Azure Storage services, including queue, storage and table.
My favourite way of using Azurite currently involves using DevContainer technology through visual studio code. DevContainers utilise Docker Desktop to run your project within a container. A word of caution though, unless you have a fairly beefy PC (8 core, 32GB) you may find there’s a bit of slow down. I’ve never skimped on Development workstations, so I’m usually ok.
To run Aspire within DevContainer you need to use the dotnet9.0-bookworm (at time of writing) and the docker within docker features.
Our devcontainer will install azurite in a onCreate script then run multiple azurite instances by means of a postCreate script.
{
"name": ".NET Aspire",
"image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/powershell:1": {},
"ghcr.io/devcontainers/features/node:1":{},
"ghcr.io/devcontainers/features/dotnet:2":{}
},
"hostRequirements": {
"cpus": 8,
"memory": "32gb",
"storage": "64gb"
},
"forwardPorts": [5000, 5001],
"portsAttributes": {
"5001": {
"protocol": "https"
}
},
"postCreateCommand": "bash .devcontainer/postCreate.sh",
"onCreateCommand": "bash .devcontainer/onCreate.sh",
"postStartCommand": "dotnet dev-certs https --trust",
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.csdevkit",
"ms-dotnettools.vscode-dotnet-pack",
"GitHub.copilot-chat",
"GitHub.copilot"
]
}
},
"remoteEnv": {
"AZURITE_ACCOUNTS":"account1:a2V5MQ==:a2V5Mg==;account2:a2V5MQ==:a2V5Mg=="
},
"remoteUser": "root"
}
I add the above code in the .devcontainer/devcontainer.json file in the root of my project.
Then I add the shell scripts to the .devcontainer folder.
Starting with onCreate.sh
#!/bin/bash
apt update -y
curl -sSL https://aspire.dev/install.sh | bash
npm install -g azurite
Then I also add postCreate.sh to the .devcontainer folder
#!/bin/bash
set -eux
# a2V5MQ== is key1
# a2V5Mg== is key2
# Set up Azurite in npm
mkdir /azurite
#set AZURITE_ACCOUNTS="account1:a2V5MQ==:a2V5Mg==;account2:a2V5MQ==:a2V5Mg=="
bash -c "azurite --silent --location /azurite --debug /azurite/debug.log & disown"
I’ve commented out the set as I added the environment variables in the devcontainer.json configuration.
Azurite will be running with two accounts, with keys set to “key1” and “key2” as per base64 encoded values.
I can now connect to the appropriate instance using a 127.0.0.1 connection string.
DefaultEndpointsProtocol=http;AccountName=account1;AccountKey=a2V5Mg==;BlobEndpoint=http://127.0.0.1:10000/account1;QueueEndpoint=http://127.0.0.1:10001/account1;TableEndpoint=http://127.0.0.1:10002/account1;
And for account2;
DefaultEndpointsProtocol=http;AccountName=account2;AccountKey=a2V5Mg==;BlobEndpoint=http://127.0.0.1:10000/account2;QueueEndpoint=http://127.0.0.1:10001/account2;TableEndpoint=http://127.0.0.1:10002/account2;
Now I can reference them in my aspire setup in program.cs
if (builder.Environment.IsDevelopment())
{
var connString= "DefaultEndpointsProtocol=http;AccountName=account1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/account1;QueueEndpoint=http://127.0.0.1:10001/account1;TableEndpoint=http://127.0.0.1:10002/account1;";
storage = builder.AddConnectionString("storage", connString);
}
else
{
storage = builder.AddAzureStorage("storage");
}
Now storage will be available within your Aspire solution.
Troubleshooting
If Azurite is not started in your container, start a terminal session and run the Azurite command.
azurite --silent --location /azurite --debug /azurite/debug.log