# Volume

The `Volume` resource allows you to create and manage persistent Docker volumes using Alchemy.

## Usage

```typescript
import * as docker from "alchemy/docker";

const myVolume = await docker.Volume("data-volume", {
  name: "app-data",
  driver: "local"
});
```

## Properties

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `name` | `string` | Yes | Docker volume name |
| `driver` | `string` | No | Volume driver to use (defaults to "local") |
| `driverOpts` | `Record<string, string>` | No | Driver-specific options |
| `labels` | `VolumeLabel[] \| Record<string, string>` | No | Custom metadata labels for the volume |

The `VolumeLabel` interface has the following structure:
```typescript
interface VolumeLabel {
  name: string;   // Label name
  value: string;  // Label value
}
```

## Outputs

| Name | Type | Description |
|------|------|-------------|
| `id` | `string` | Volume ID (same as name for Docker volumes) |
| `mountpoint` | `string` | Volume mountpoint path on the host |
| `createdAt` | `number` | Time when the volume was created |

## Example

```typescript
import * as docker from "alchemy/docker";

// Create a simple Docker volume for persistent data
const dataVolume = await docker.Volume("data-volume", {
  name: "postgres-data"
});

// Create a Docker volume with custom driver options
const dbVolume = await docker.Volume("db-data", {
  name: "mysql-data",
  driver: "local",
  driverOpts: {
    "type": "nfs",
    "o": "addr=10.0.0.1,rw",
    "device": ":/path/to/dir"
  }
});

// Create a volume with labels (array format)
const logsVolume = await docker.Volume("logs-volume", {
  name: "app-logs",
  labels: [
    { name: "com.example.environment", value: "production" },
    { name: "com.example.created-by", value: "alchemy" }
  ]
});

// Create a volume with labels (record format)
const configVolume = await docker.Volume("config-volume", {
  name: "app-config",
  labels: {
    "com.example.environment": "staging",
    "com.example.created-by": "alchemy"
  }
});

// Use volumes with a container
const dbContainer = await docker.Container("database", {
  image: "postgres:14",
  name: "postgres",
  volumes: [
    {
      hostPath: dataVolume.name,    // Reference the volume by name
      containerPath: "/var/lib/postgresql/data"
    },
    {
      hostPath: logsVolume.name,
      containerPath: "/var/log/postgresql",
      readOnly: false
    }
  ],
  environment: {
    POSTGRES_PASSWORD: "secret"
  },
  restart: "always",
  start: true
});
```

## Using Docker Volumes for Persistence

Docker volumes are the preferred mechanism for persisting data generated by and used by Docker containers. Their benefits include:

1. **Data Persistence**: Data stored in volumes persists even when containers are stopped or removed
2. **Performance**: Better performance than bind mounts, especially on Windows and macOS
3. **Portability**: Volumes can be easily backed up, restored, and migrated
4. **Driver Support**: Support for various storage backends through volume drivers

When using Docker volumes with Alchemy, it's a common pattern to:
1. Create volumes with meaningful names
2. Assign metadata using labels
3. Reference volumes in containers by name
4. Configure volume permissions with the `readOnly` flag when mounting