Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In this tutorial, you use the Azure Cosmos DB Linux emulator as a local development database, build a TypeScript application, and then migrate to Azure Cosmos DB by swapping your credentials.
In this tutorial, you:
- Start the Azure Cosmos DB emulator in a Docker container
- Create a TypeScript application
- Connect the application to the local emulator
- Create an Azure Cosmos DB account
- Deploy the application to Azure Cosmos DB
Prerequisites
- Node.js 22 or newer
- Docker Desktop
- Azure CLI
- An Azure subscription. If you don't have an Azure subscription, create a free account before you begin.
Start the emulator
Use the Docker container image for the Linux-based Azure Cosmos DB emulator to create a local development database.
Pull the emulator container image.
docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-previewStart the emulator container.
docker run --detach --publish 8081:8081 --publish 1234:1234 --name cosmos-db mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-previewVerify the container is running.
docker ps --filter "name=cosmos-db"Important
The emulator gateway endpoint is available at
https://localhost:8081and the data explorer is available athttp://localhost:1234. The emulator uses a well-known authentication key:AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;Setting Value Endpoint https://localhost:8081Key C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==
Create the application
Create a Next.js application and connect it to the local emulator.
Create a new Next.js application in an empty folder. Accept any default settings.
npx create-next-app .Install the Node.js client library for Azure Cosmos DB.
npm install --save @azure/cosmosCreate a new file named
app/data.tsxwith the following code. This file contains the server actions that interact with the database."use server"; import { CosmosClient } from "@azure/cosmos"; import { revalidatePath } from "next/cache"; const connectionString = "<cosmos-db-connection-string>"; const client = new CosmosClient(connectionString); const { database } = await client.databases.createIfNotExists({ id: "work-management" }); const { container } = await database.containers.createIfNotExists({ id: "tasks", partitionKey: "/id" }); export type Todo = { id: string; title: string; completed: boolean; }; export async function getTodos(): Promise<Todo[]> { const { resources } = await container.items .query("SELECT * FROM c ORDER BY c._ts DESC") .fetchAll(); return resources.map((doc) => ({ id: doc.id, title: doc.title, completed: doc.completed, })); } export async function addTodo(formData: FormData) { const title = formData.get("title") as string; if (!title?.trim()) return; await container.items.create({ title: title.trim(), completed: false, }); revalidatePath("/"); } export async function toggleTodo(formData: FormData) { const id = formData.get("id") as string; const { resource: doc } = await container.item(id, id).read(); if (doc) { await container.item(id, id).replace({ ...doc, completed: !doc.completed, }); } revalidatePath("/"); } export async function deleteTodo(formData: FormData) { const id = formData.get("id") as string; await container.item(id, id).delete(); revalidatePath("/"); }Important
Replace the connection string placeholder with the credentials specified earlier in this tutorial when starting the container.
Delete the existing
app/page.tsxfile and replace it with the following code.import { getTodos, addTodo, toggleTodo, deleteTodo } from "./data"; export default async function Home() { const todos = await getTodos(); return ( <div className="min-h-screen bg-black text-zinc-50 font-sans"> <main className="max-w-lg mx-auto py-16 px-8"> <h1 className="text-2xl font-semibold tracking-tight mb-8">Todo App</h1> <form action={addTodo} className="flex gap-2 mb-8"> <input name="title" placeholder="Add a todo..." required className="flex-1 rounded-md border border-zinc-700 bg-zinc-900 px-3 py-2 text-sm text-zinc-100 placeholder:text-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-600" /> <button type="submit" className="rounded-md bg-zinc-100 px-4 py-2 text-sm font-medium text-zinc-900 hover:bg-zinc-300 transition-colors"> Add </button> </form> <ul className="space-y-2"> {todos.map((todo) => ( <li key={todo.id} className="flex items-center gap-3 rounded-md border border-zinc-800 bg-zinc-900 px-3 py-2"> <form action={toggleTodo}> <input type="hidden" name="id" value={todo.id} /> <button type="submit" className="text-lg leading-none">{todo.completed ? "✅" : "⬜"}</button> </form> <span className={`flex-1 text-sm ${todo.completed ? "line-through text-zinc-500" : "text-zinc-100"}`}>{todo.title}</span> <form action={deleteTodo}> <input type="hidden" name="id" value={todo.id} /> <button type="submit" className="text-sm text-red-400 hover:text-red-300 transition-colors">✕</button> </form> </li> ))} </ul> {todos.length === 0 && <p className="text-center text-sm text-zinc-500 mt-4">No todos yet.</p>} </main> </div> ); }Run the application locally.
npm run devOpen
http://localhost:3000in your browser to verify the application is running and connected to the emulator.Tip
You can review the data this application creates in the Azure Cosmos DB Emulator Data Explorer at
http://localhost:1234. You can also use the Azure Cosmos DB extension for Visual Studio Code The database is namedwork-managementand the container is namedtasks.Stop the application.
Create an Azure Cosmos DB account
Create an Azure Cosmos DB account to host your application data in the cloud.
Create variables for the account name and target resource group name.
RESOURCE_GROUP_NAME="<resource-group-name>" ACCOUNT_NAME="<account-name>"Important
Replace
<resource-group-name>and<account-name>with your own values. The account name must be globally unique.Create an Azure Cosmos DB account.
az cosmosdb create \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACCOUNT_NAMEGet the connection string for the account.
az cosmosdb keys list \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACCOUNT_NAME \ --type connection-strings \ --query "connectionStrings[0].connectionString" \ --output tsvRecord the connection string value. You use it in the next step.
Connect the application to Azure Cosmos DB
Update the application to connect to Azure Cosmos DB instead of the local emulator.
In
app/data.tsx, replace the emulator connection string with the Azure Cosmos DB connection string.const connectionString = "<azure-cosmos-db-connection-string>";Important
Replace
<azure-cosmos-db-connection-string>with the connection string you recorded in the previous step.Start the application again.
npm run devOpen
http://localhost:3000in your browser. The application now reads and writes data to your Azure Cosmos DB account.
Clean up resources
When you no longer need the resources created in this tutorial, delete them to avoid incurring charges.
Delete the Azure Cosmos DB account.
az cosmosdb delete \ --resource-group $RESOURCE_GROUP_NAME \ --name $ACCOUNT_NAME \ --yesStop and remove the emulator container.
docker stop cosmos-db docker rm cosmos-db