Getting Started
Create and manage your first local Cardano devnet cluster
Getting Started with Devnet
This guide walks through creating, starting, and managing a local Cardano development network. You'll learn cluster lifecycle operations, container management, and how to integrate Kupo and Ogmios for full blockchain access.
Installation
Install the devnet package alongside the Evolution SDK:
pnpm add @evolution-sdk/devnet @evolution-sdk/evolutionThe package requires Docker to be running. Verify Docker is available:
docker --versionBasic Cluster Creation
A devnet cluster is the foundation of your local blockchain environment. The cluster consists of a cardano-node container that produces blocks and validates transactions.
Creating a minimal cluster requires only a name and port configuration. The SDK handles Docker image pulling, container creation, volume management, and genesis file generation automatically.
import { } from "@evolution-sdk/devnet";
// Create a basic devnet cluster
const = await .({
: "my-first-devnet",
: { : 3001, : 3002 }
});
.("Cluster created:", ..);The make function returns a cluster configuration containing container references. The cardano-node will bind to port 3001 for peer connections and port 3002 for transaction submission.
Starting the Cluster
Once created, start the cluster to begin block production:
import { } from "@evolution-sdk/devnet";
const = await .()
// Start all containers in the cluster
await .();
.("Devnet is now producing blocks");
// Wait for the node to fully initialize
await new ( => (, 3000));The node begins producing blocks immediately using the default genesis configuration. Initial startup takes a few seconds as the node processes the genesis block and establishes its database.
Checking Container Status
Monitor individual container states to verify the cluster is running correctly:
import { , } from "@evolution-sdk/devnet";
const = await .()
// Get detailed container status
const = await .(.);
.("Container state:", ?..); // "running"
.("Container health:", ?..?.); // "healthy"The status object includes full Docker inspect output: state, network settings, mounts, resource usage, and health check results.
Stopping and Removing
Clean up resources when testing is complete:
import { } from "@evolution-sdk/devnet";
const = await .()
// Stop all containers gracefully
await .();
.("Cluster stopped");
// Remove containers and networks
await .();
.("Cluster removed");Stopping containers preserves blockchain state in Docker volumes. Removing deletes containers but keeps named volumes by default. To completely reset state, manually remove volumes using Docker commands.
Adding Kupo and Ogmios
Most applications need more than just a cardano-node. Kupo provides fast UTxO indexing, while Ogmios exposes JSON-RPC and WebSocket APIs for blockchain queries.
Enable both services when creating the cluster:
import { , } from "@evolution-sdk/devnet";
const = await .({
: "full-stack-devnet",
: { : 3001, : 3002 },
: {
: true,
: 1442,
: "Info"
},
: {
: true,
: 1337,
: "info"
}
});
// Start all three containers
await .();
// Wait for services to initialize
await new ( => (, 5000));
// Check Kupo status
if (.) {
const = await .(.);
.("Kupo status:", ?..);
}
// Check Ogmios status
if (.) {
const = await .(.);
.("Ogmios status:", ?..);
}Kupo and Ogmios containers share the node's socket via a Docker volume. They automatically detect the custom network configuration and begin syncing from genesis.
The log levels control output verbosity:
- Kupo:
Debug,Info,Warning,Error - Ogmios:
debug,info,notice,warning,error
Individual Container Operations
Fine-grained control over containers enables testing failure scenarios and resource management:
import { , } from "@evolution-sdk/devnet";
const = await .()
// Stop just the cardano-node
await .(.);
.("Node stopped, Kupo and Ogmios still running");
// Check stopped status
const = await .(.);
.("Status:", ?..); // "exited"
// Restart the node
await .(.);
await new ( => (, 2000));
// Verify running again
const = await .(.);
.("Status:", ?..); // "running"Individual operations work on any container in the cluster. Kupo and Ogmios depend on the cardano-node socket, so stopping the node will cause queries to fail until it restarts.
Complete Workflow Example
Putting it all together, here's a typical development session:
import { , } from "@evolution-sdk/devnet";
async function () {
// Create cluster with full stack
const = await .({
: "dev-session",
: { : 3001, : 3002 },
: { : true, : 1442 },
: { : true, : 1337 }
});
try {
// Start the environment
await .();
.("✓ Devnet started");
// Wait for initialization
await new ( => (, 5000));
// Verify all services are healthy
const = await .(.);
const = .
? await .(.)
: null;
const = .
? await .(.)
: null;
.("✓ Node:", ?..);
.("✓ Kupo:", ?..);
.("✓ Ogmios:", ?..);
// Your development work happens here
.("\n🚀 Devnet ready for development");
.(" Ogmios: http://localhost:1337");
.(" Kupo: http://localhost:1442");
// Keep running for development
// In real usage, this would be your test suite or app runtime
await new ( => (, 10000));
} finally {
// Always clean up
await .();
await .();
.("\n✓ Devnet stopped and removed");
}
}
().(.);This pattern ensures resources are properly cleaned up even if errors occur during development.
Next Steps
Now that you can create and manage devnet clusters, learn how to:
- Configuration: Customize genesis parameters, fund addresses, and modify protocol settings
- Integration: Use the Evolution SDK client to query the blockchain and submit transactions
Troubleshooting
Port conflicts: If ports are already in use, choose different values:
ports: { node: 4001, submit: 4002 }Slow startup: Initial Docker image pulls can take several minutes. Subsequent starts are fast. The SDK automatically pulls missing images.
Container won't start: Check Docker daemon is running and you have sufficient disk space for blockchain data.
Network errors: Ensure no firewall rules block localhost ports. The containers bind to 127.0.0.1 by default.