# How to: Use Azurite as a service container in Codespaces or Devcontainers

https://blog.cynexia.com/how-to-use-azurite-as-a-service-container-in-codespaces-or-devcontainers

Author: [Rob Aleck](https://blog.cynexia.com/pages/about) · https://github.com/mnbf9rca · https://www.linkedin.com/in/robertaleck/ · https://family-foqos.app/

Published: 2024-09-30
Categories: How-to


When developing with Azure Storage, it can significantly speed up your development process if you can use a local development environment, rather than constantly connecting directly to storage in Azure itself. This is where [Azurite](<https://github.com/Azure/Azurite>) comes in - Azurite is a local storage emulator for Azure Storage, mimicing blob/container, queue and table storage. While there are lots of ways to get it running (e.g. from binary, manually using Docker etc.), I wanted to set it up as a service container in my devcontainer configuration which provides a few benefits:

- consistency - every time i rebuild my devcontainer i know i'm resetting Azurite back to a known, clean state
- Isolation - running it in a separate container means i avoid any potential side effects which might arise if it's running in my main development container
- Portability - it works consistently on Github codespaces, local devcontainer setups etc.

This guide provides a basic outline for setting up Azurite as a service container in a devcontainer configuration.

## Create `docker-compose.yml` to define the services

Using a [docker compose file inside your devcontainer definition](<https://containers.dev/guide/dockerfile#docker-compose>) lets you define multiple 'services' which all work together.  In my case, i've set up the `devcontainer` service which is the main development environment based on the Microsoft [Python devcontainer image](<https://github.com/devcontainers/images/tree/main/src/python>), and `azurite` which contains azurite. Of course you could add whatever you need - PostgreSQL, Mongo, whatever you need. Here's my `docker-compose` file:

```
services:
  devcontainer:
    image: mcr.microsoft.com/devcontainers/python:1-3.11-bullseye
    platform: linux/amd64
    volumes:
      - ..:/workspace:delegated
    ports:
      - "5000:5000"
    environment:
      - POETRY_VIRTUALENVS_IN_PROJECT=true
    command: /bin/sh -c "while sleep 1000; do :; done"
    network_mode: "host"
  azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    ports:
      - "127.0.0.1:10000:10000"
      - "127.0.0.1:10001:10001"
      - "127.0.0.1:10002:10002"
    command: >
      azurite
      --blobHost 0.0.0.0
      --queueHost 0.0.0.0
      --tableHost 0.0.0.0
```

## Create `devcontainer.json`

After defining your services, you need to create a `devcontainer.json` file. This configures the development environment, and its in the `dockerComposeFile` attribute that you point to your docker-compose file, and defining the `service` which represents the actual devcontainer. I've added a bunch of features which . In my configuration, i've also disabled some extensions which are recommended by the base image or other feature extensions by prefixing their names with `-`. Finally, i included a `postCreateCommand` which marks the `/workspace` folder as safe, and installs dependencies using Poetry, although you may want to skip this last step.

```
{
	"name": "Python 3",
	"dockerComposeFile": ["docker-compose.yml"],
	"workspaceFolder": "/workspace",
	"service": "devcontainer",
	"features": {
		"ghcr.io/devcontainers-contrib/features/poetry:2": {"version": "1.8.3"},
		"ghcr.io/devcontainers/features/github-cli:1": {},
		"ghcr.io/devcontainers/features/node:1": {},
		"ghcr.io/devcontainers/features/azure-cli:1": {},
		"ghcr.io/flexwie/devcontainer-features/pulumi:1": {},
		"ghcr.io/prulloac/devcontainer-features/pre-commit:1": {},
		"ghcr.io/jlaundry/devcontainer-features/azure-functions-core-tools:1": {},
		"ghcr.io/devcontainers/features/rust:1": {}, // for cryptography package
		"ghcr.io/devcontainers/features/docker-outside-of-docker": {}
	},
	"customizations": {
		"vscode": {
			"extensions": [
				"-vadimcn.vscode-lldb",
				"-rust-lang.rust-analyzer",
				"-tamasfe.even-better-toml",
				"-dbaeumer.vscode-eslint"
			]
		}
	},
	"forwardPorts": [10000, 10001, 10002],
  "postCreateCommand": "git config --global --add safe.directory /workspace && poetry self add poetry-plugin-export && poetry config warnings.export false && poetry config virtualenvs.in-project true --local && poetry install --with dev --no-interaction --sync --no-root"
}
```

## Next steps

You can connect to the locally emulated storage using a connection string based on a [well-known account and key](<https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio%2Cblob-storage#well-known-storage-account-and-key>) baked in to Azurite:

```
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;
```

You might choose to add more advanced configuration, such as persistent storage, or enabling OAuth (to allow the use of the [`DefaultAzureCredential`](<https://learn.microsoft.com/en-us/python/api/azure-identity/azure.identity.defaultazurecredential?view=azure-python>)).

Finally, you can add additional services, such as PostgreSQL or Mongo, to aid your development process.

