Deployment Subsystem¶
The deployment subsystem packages HoloDeck agents as container images and deploys them to cloud providers. It covers three concerns: Dockerfile generation, Docker image building, and cloud deployment with state tracking.
Optional dependency
ContainerBuilder and BuildResult require the docker Python package.
Install it with pip install holodeck-ai[deploy]. The symbols are lazily
imported so the rest of the library works without Docker installed.
Package entry point¶
deploy
¶
HoloDeck deployment engine.
This package provides the deployment functionality for HoloDeck agents, including Dockerfile generation, container building, and cloud deployment.
Note: ContainerBuilder and BuildResult require the 'docker' optional dependency (pip install holodeck-ai[deploy]). They are lazily imported to avoid ImportError when docker is not installed.
generate_dockerfile(agent_name, port, protocol, *, base_image='ghcr.io/justinbarias/holodeck-base:latest', version='0.0.0', source_url='', instruction_files=None, data_directories=None, environment=None, needs_nodejs=False)
¶
Generate a Dockerfile for a HoloDeck agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the agent for labeling |
required |
port
|
int
|
Port to expose |
required |
protocol
|
str
|
Protocol type (rest, ag-ui, both) |
required |
base_image
|
str
|
Base Docker image to use |
'ghcr.io/justinbarias/holodeck-base:latest'
|
version
|
str
|
Version for OCI label |
'0.0.0'
|
source_url
|
str
|
Source URL for OCI label |
''
|
instruction_files
|
list[str] | None
|
List of instruction file paths to copy |
None
|
data_directories
|
list[str] | None
|
List of data directories to copy |
None
|
environment
|
dict[str, str] | None
|
Environment variables to set |
None
|
needs_nodejs
|
bool
|
Whether to install Node.js (required for Claude Agent SDK) |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Generated Dockerfile content as a string |
Example
dockerfile = generate_dockerfile( ... agent_name="my-agent", ... port=8080, ... protocol="rest", ... instruction_files=["instructions.md"], ... ) print(dockerfile[:50])
HoloDeck Agent Container¶
Auto-generated Doc...¶
Source code in src/holodeck/deploy/dockerfile.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
generate_tag(strategy, custom_tag=None)
¶
Generate an image tag based on the specified strategy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strategy
|
TagStrategy
|
Tag generation strategy (git_sha, git_tag, latest, custom) |
required |
custom_tag
|
str | None
|
Custom tag value when strategy is CUSTOM |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Generated tag string |
Raises:
| Type | Description |
|---|---|
ValueError
|
If custom strategy is used without providing custom_tag |
DeploymentError
|
If git commands fail (not in repo, no tags, etc.) |
Example
generate_tag(TagStrategy.LATEST) 'latest' generate_tag(TagStrategy.CUSTOM, custom_tag="v1.0.0") 'v1.0.0'
Source code in src/holodeck/deploy/builder.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
get_oci_labels(agent_name, version, source_sha=None)
¶
Generate OCI-compliant container image labels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the agent for image title |
required |
version
|
str
|
Version string for the image |
required |
source_sha
|
str | None
|
Optional git SHA for source tracking |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dictionary of OCI labels |
Example
labels = get_oci_labels("my-agent", "v1.0.0") labels["org.opencontainers.image.title"] 'my-agent'
Source code in src/holodeck/deploy/builder.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
holodeck.deploy.dockerfile -- Dockerfile generation¶
Generates Dockerfiles from Jinja2 templates, embedding OCI labels, environment variables, instruction files, and optional Node.js installation for Claude agents.
generate_dockerfile(agent_name, port, protocol, *, base_image='ghcr.io/justinbarias/holodeck-base:latest', version='0.0.0', source_url='', instruction_files=None, data_directories=None, environment=None, needs_nodejs=False)
¶
Generate a Dockerfile for a HoloDeck agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the agent for labeling |
required |
port
|
int
|
Port to expose |
required |
protocol
|
str
|
Protocol type (rest, ag-ui, both) |
required |
base_image
|
str
|
Base Docker image to use |
'ghcr.io/justinbarias/holodeck-base:latest'
|
version
|
str
|
Version for OCI label |
'0.0.0'
|
source_url
|
str
|
Source URL for OCI label |
''
|
instruction_files
|
list[str] | None
|
List of instruction file paths to copy |
None
|
data_directories
|
list[str] | None
|
List of data directories to copy |
None
|
environment
|
dict[str, str] | None
|
Environment variables to set |
None
|
needs_nodejs
|
bool
|
Whether to install Node.js (required for Claude Agent SDK) |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Generated Dockerfile content as a string |
Example
dockerfile = generate_dockerfile( ... agent_name="my-agent", ... port=8080, ... protocol="rest", ... instruction_files=["instructions.md"], ... ) print(dockerfile[:50])
HoloDeck Agent Container¶
Auto-generated Doc...¶
Source code in src/holodeck/deploy/dockerfile.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
holodeck.deploy.builder -- Container image building¶
Builds Docker images via the Docker SDK and provides helpers for tag generation and OCI label creation.
BuildResult¶
BuildResult(image_id, image_name, tag, full_name, log_lines=list())
dataclass
¶
Result of a container image build operation.
Attributes:
| Name | Type | Description |
|---|---|---|
image_id |
str
|
The SHA256 ID of the built image |
image_name |
str
|
The repository/image name |
tag |
str
|
The image tag |
full_name |
str
|
Full image reference (name:tag) |
log_lines |
list[str]
|
Build log output lines |
from_image(image, image_name, tag, log_lines=None)
classmethod
¶
Create BuildResult from a Docker image object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
Image
|
Docker image object from build |
required |
image_name
|
str
|
Repository/image name |
required |
tag
|
str
|
Image tag |
required |
log_lines
|
list[str] | None
|
Optional build log lines |
None
|
Returns:
| Type | Description |
|---|---|
BuildResult
|
BuildResult instance |
Source code in src/holodeck/deploy/builder.py
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
ContainerBuilder¶
ContainerBuilder()
¶
Builder for HoloDeck agent container images.
Uses the Docker SDK to build container images from agent configurations. Handles Docker daemon connection, build execution, and error handling.
Example
builder = ContainerBuilder() result = builder.build( ... build_context="./build", ... image_name="my-org/my-agent", ... tag="v1.0.0", ... ) print(result.full_name) 'my-org/my-agent:v1.0.0'
Initialize the container builder.
Connects to the Docker daemon using the environment configuration.
Raises:
| Type | Description |
|---|---|
DockerNotAvailableError
|
If Docker daemon is not available |
Source code in src/holodeck/deploy/builder.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | |
build(build_context, image_name, tag, labels=None, dockerfile='Dockerfile', platform='linux/amd64', **build_kwargs)
¶
Build a container image from the specified context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
build_context
|
str
|
Path to the build context directory |
required |
image_name
|
str
|
Repository/image name for the built image |
required |
tag
|
str
|
Tag for the built image |
required |
labels
|
dict[str, str] | None
|
Optional OCI labels to apply |
None
|
dockerfile
|
str
|
Path to Dockerfile relative to context |
'Dockerfile'
|
platform
|
str
|
Target platform for the image (default: linux/amd64) |
'linux/amd64'
|
**build_kwargs
|
Any
|
Additional arguments passed to Docker build |
{}
|
Returns:
| Type | Description |
|---|---|
BuildResult
|
BuildResult with image details and build logs |
Raises:
| Type | Description |
|---|---|
DeploymentError
|
If build context doesn't exist or build fails |
Source code in src/holodeck/deploy/builder.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | |
generate_tag¶
generate_tag(strategy, custom_tag=None)
¶
Generate an image tag based on the specified strategy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
strategy
|
TagStrategy
|
Tag generation strategy (git_sha, git_tag, latest, custom) |
required |
custom_tag
|
str | None
|
Custom tag value when strategy is CUSTOM |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Generated tag string |
Raises:
| Type | Description |
|---|---|
ValueError
|
If custom strategy is used without providing custom_tag |
DeploymentError
|
If git commands fail (not in repo, no tags, etc.) |
Example
generate_tag(TagStrategy.LATEST) 'latest' generate_tag(TagStrategy.CUSTOM, custom_tag="v1.0.0") 'v1.0.0'
Source code in src/holodeck/deploy/builder.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
get_oci_labels¶
get_oci_labels(agent_name, version, source_sha=None)
¶
Generate OCI-compliant container image labels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the agent for image title |
required |
version
|
str
|
Version string for the image |
required |
source_sha
|
str | None
|
Optional git SHA for source tracking |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dictionary of OCI labels |
Example
labels = get_oci_labels("my-agent", "v1.0.0") labels["org.opencontainers.image.title"] 'my-agent'
Source code in src/holodeck/deploy/builder.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
holodeck.deploy.state -- Deployment state tracking¶
Persists deployment records to a JSON file under .holodeck/deployments.json
next to the agent configuration. Tracks creation and update timestamps and
computes deterministic config hashes for drift detection.
get_state_path¶
get_state_path(agent_path)
¶
Return the deployment state file path for an agent config.
Source code in src/holodeck/deploy/state.py
19 20 21 | |
compute_config_hash¶
compute_config_hash(config)
¶
Compute a deterministic hash for the deployment configuration.
Source code in src/holodeck/deploy/state.py
24 25 26 27 28 29 30 31 | |
load_state¶
load_state(state_path)
¶
Load deployment state data from disk.
Source code in src/holodeck/deploy/state.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |
save_state¶
save_state(state_path, state)
¶
Persist deployment state data to disk.
Source code in src/holodeck/deploy/state.py
62 63 64 65 66 67 68 69 70 71 72 | |
get_deployment_record¶
get_deployment_record(state_path, agent_name)
¶
Return a deployment record for a specific agent.
Source code in src/holodeck/deploy/state.py
75 76 77 78 | |
update_deployment_record¶
update_deployment_record(state_path, agent_name, record)
¶
Update deployment record for an agent and persist it.
Source code in src/holodeck/deploy/state.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | |
holodeck.deploy.deployers -- Cloud deployers¶
Factory module that instantiates the correct deployer based on cloud provider.
create_deployer¶
create_deployer(target)
¶
Create a cloud deployer based on the target configuration.
Source code in src/holodeck/deploy/deployers/__init__.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
holodeck.deploy.deployers.base -- Base deployer interface¶
BaseDeployer¶
BaseDeployer
¶
Bases: ABC
Abstract base class for cloud deployers.
deploy(*, service_name, image_uri, port, env_vars, health_check_path='/health', **kwargs)
abstractmethod
¶
Deploy a containerized service and return deployment details.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service_name
|
str
|
Name for the deployed service. |
required |
image_uri
|
str
|
Full container image URI including tag. |
required |
port
|
int
|
Container port to expose. |
required |
env_vars
|
dict[str, str]
|
Environment variables to set in the container. |
required |
health_check_path
|
str
|
HTTP path for health checks (default: /health). |
'/health'
|
**kwargs
|
Any
|
Provider-specific deployment options. |
{}
|
Returns:
| Type | Description |
|---|---|
DeployResult
|
DeployResult containing service_id, service_name, url, and status. |
Raises:
| Type | Description |
|---|---|
DeploymentError
|
If deployment fails. |
Source code in src/holodeck/deploy/deployers/base.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | |
get_status(service_id)
abstractmethod
¶
Retrieve deployment status and URL by service identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service_id
|
str
|
Unique identifier for the deployed service. |
required |
Returns:
| Type | Description |
|---|---|
StatusResult
|
StatusResult containing current status and URL. |
Raises:
| Type | Description |
|---|---|
DeploymentError
|
If status check fails. |
Source code in src/holodeck/deploy/deployers/base.py
43 44 45 46 47 48 49 50 51 52 53 54 55 | |
destroy(service_id)
abstractmethod
¶
Destroy a deployed service by identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service_id
|
str
|
Unique identifier for the deployed service. |
required |
Raises:
| Type | Description |
|---|---|
DeploymentError
|
If destroy operation fails. |
Source code in src/holodeck/deploy/deployers/base.py
57 58 59 60 61 62 63 64 65 66 | |
stream_logs(service_id)
abstractmethod
¶
Stream deployment logs for a service identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
service_id
|
str
|
Unique identifier for the deployed service. |
required |
Returns:
| Type | Description |
|---|---|
Iterable[str]
|
Iterable of log lines. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
When log streaming is not supported by the provider. |
DeploymentError
|
If log streaming fails. |
Source code in src/holodeck/deploy/deployers/base.py
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | |
holodeck.deploy.deployers.azure_containerapps -- Azure Container Apps¶
AzureContainerAppsDeployer¶
AzureContainerAppsDeployer(config)
¶
Bases: BaseDeployer
Deploy HoloDeck agents to Azure Container Apps.
Initialize Azure Container Apps deployer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
AzureContainerAppsConfig
|
Azure Container Apps configuration |
required |
Raises:
| Type | Description |
|---|---|
DeploymentError
|
If configuration is missing required values |
CloudSDKNotInstalledError
|
If Azure SDK dependencies are missing |
Source code in src/holodeck/deploy/deployers/azure_containerapps.py
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
deploy(*, service_name, image_uri, port, env_vars, health_check_path='/health', **kwargs)
¶
Deploy a container to Azure Container Apps.
Source code in src/holodeck/deploy/deployers/azure_containerapps.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | |
get_status(service_id)
¶
Get status for an Azure Container App.
Source code in src/holodeck/deploy/deployers/azure_containerapps.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | |
destroy(service_id)
¶
Destroy an Azure Container App deployment.
Source code in src/holodeck/deploy/deployers/azure_containerapps.py
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | |
stream_logs(service_id)
¶
Stream logs for Azure Container Apps (not implemented).
Source code in src/holodeck/deploy/deployers/azure_containerapps.py
307 308 309 310 311 | |