Skip to content

Containers are HTTP computers you spawn on demand. Create them in 1-5 seconds, configure them exactly how you need, and delete them when you’re done.

After understanding Projects & Containers, you need to know how to actually create and manage individual containers.


Official Technical Reference:

This Foundation page explains container CRUD concepts and workflows. For complete endpoint documentation:

Container Creation:

Container Modification:

Container Deletion:

Related Operations:


Every container you create becomes a complete HTTP computer with the full Hoody Kit service stack.

POST Create a new container
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request

Within 1-5 seconds:

  • Container is running (prespawn) or creating (regular)
  • The full Hoody Kit HTTP stack is live
  • URLs automatically generated

Startup timing:

  • With prespawn: Sub-second (claimed from warm pool)
  • Without prespawn: 1-5 seconds (created on demand)

Response includes container details:

{
"statusCode": 201,
"message": "Container created successfully",
"data": {
"id": "890abcdef12345678901cdef",
"project_id": "67e89abc123def456789abcd",
"server_id": "63f8b0e5c9a1b2d3e4f5a6b7",
"server_name": "node-us",
"name": "dev-environment",
"status": "creating",
"hoody_kit": true,
"dev_kit": true
}
}

Your container URLs are now live:

Terminal: https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-us.containers.hoody.icu
Display: https://67e89abc123def456789abcd-890abcdef12345678901cdef-display-1.node-us.containers.hoody.icu
Files: https://67e89abc123def456789abcd-890abcdef12345678901cdef-files-1.node-us.containers.hoody.icu
Exec: https://67e89abc123def456789abcd-890abcdef12345678901cdef-exec-1.node-us.containers.hoody.icu
SQLite: https://67e89abc123def456789abcd-890abcdef12345678901cdef-sqlite-1.node-us.containers.hoody.icu
+ the rest of the 18 Kit services...

When creating a container, you can customize every aspect:

{
"name": "my-container"
}
  • 3-100 characters
  • Alphanumeric + hyphens/underscores
  • Unique within project
  • Use "rand" or omit for auto-generated name

Choose your operating system:

{
"container_image": "debian/13"
}

Available images:

  • debian/13 - Debian 13 Trixie ⭐ (recommended default)
  • debian/12 - Debian 12 Bookworm
  • ubuntu/24.04 - Ubuntu 24.04 LTS
  • ubuntu/22.04 - Ubuntu 22.04 LTS
  • alpine/3.19 - Alpine Linux (minimal)
  • fedora/<release> - Fedora (pick an available release from GET /api/v1/images/public?os=fedora)

Default: If omitted or null, the system default image is used — currently debian/13 (Debian 13 Trixie). You can override it with any image from the marketplace.

See: Container Images for complete marketplace and OS options.

Assign container to specific realms for API-level isolation:

{
"realm_ids": ["64a2c4e9f3d5e2b6a8c7d8e1", "65b3d5f0a4e6f3c7b9d8e9f2"]
}

Important: Realms are NOT private networks. They segregate the Hoody API:

  • Different realms use different API endpoints: https://{realmId}.api.hoody.icu
  • AI agents in one realm can’t discover containers in another
  • Auth tokens can be scoped to specific realms
  • Production/staging/development separated at API level

When creating from a realm-scoped host:

  • The target project must already include that realm.
  • The scoped realm is merged into container realm_ids.
  • Realm-restricted auth tokens are forced to the active scoped realm only.

See: Realms for complete API segregation details.

Set environment variables for your application:

{
"environment_vars": {
"NODE_ENV": "production",
"DATABASE_URL": "postgresql://...",
"API_KEY": "your-secret-key"
}
}

These are available in the container immediately.

Provide your SSH public key:

{
"ssh_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGx..."
}

Critical SSH Key Rules:

Generate unique keys for each container:

Terminal window
# Generate new key pair for each container
ssh-keygen -t ed25519 -f ~/.ssh/hoody-container-1 -N ""
ssh-keygen -t ed25519 -f ~/.ssh/hoody-container-2 -N ""
# Use different public keys
container_1: {"ssh_public_key": "ssh-ed25519 AAAA... (from container-1.pub)"}
container_2: {"ssh_public_key": "ssh-ed25519 AAAA... (from container-2.pub)"}

Why unique keys matter: Hoody’s SSH Proxy identifies containers by public key. Reusing a key breaks routing - multiple containers can’t share the same SSH identity.

See: SSH Access for SSH configuration.

Qubes-inspired color coding for instant visual identification:

{
"color": "#3498db" // HEX color (with or without #)
}

Why colors matter (inspired by Qubes OS):

Like Qubes OS uses colors to visually distinguish security domains (red = untrusted, green = trusted), Hoody lets you color-code containers for instant recognition.

Especially useful for:

  • 🖥️ WebOS builders - Color-code different workspaces/applications
  • 🔐 Security zones - Red = public-facing, green = internal, blue = database
  • 👥 Multi-user teams - Each user/team gets distinct colors
  • 🎯 Environment types - Yellow = dev, orange = staging, green = production

Visual scanning beats text - spot your production database instantly in 50 containers.

{
"comment": "Development environment for Project X",
"autostart": true, // Auto-start when host reboots (default: true)
"ai": true, // Enable AI features (default: true)
"cache": true, // Use cached images (faster creation)
"prespawn": false, // Create as prespawn cache
"ramdisk": true // enabled by default, set false to disable
}

About autostart (default: true):

  • When true: Container automatically starts when host machine reboots
  • When false: Container stays stopped after host reboot (manual start required)
  • Default behavior: Containers auto-start to ensure services remain available after server maintenance/restarts

About ramdisk (default: enabled):

  • /ramdisk available by default for ultra-fast temporary storage in RAM
  • Set ramdisk: false to disable if you don’t need it
  • Zero RAM consumed when empty - RAM allocated on-demand as you store files
  • Data persists through container restarts (unique Hoody feature!)
  • Data lost only when HOST machine reboots (not when container restarts)
  • Perfect for cache, build artifacts, temporary processing that needs speed
  • See: /ramdisk for usage patterns and memory balancing

Full-featured development environment:

POST Create a development container
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request

Use case: Your daily driver - full resources, all services, auto-starts.

Optimized for running APIs:

POST Create a production API container
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request

Then configure:

  1. Create proxy alias for clean URL
  2. Set proxy permissions for authentication
  3. Configure firewall rules for security

Lightweight container for specific tasks:

POST Create a minimal utility container
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request

Use case: Run occasionally for backups, minimal resource footprint.

Dedicated container for AI orchestration:

POST Create an AI agent container
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request

With hoody-agent service:

https://67e89abc123def456789abcd-890abcdef12345678901cdef-workspaces-1.node-us.containers.hoody.icu

Update container configuration via the API.

Important: Most updates require the container to be stopped.

Terminal window
# 1. Stop container
hoody containers manage $CONTAINER_ID stop
# 2. Update configuration
hoody containers update $CONTAINER_ID \
--name "renamed-container" \
--environment-vars NODE_ENV=staging
# 3. Restart container
hoody containers manage $CONTAINER_ID start

Container metadata:

  • name - Rename container
  • color - Change UI color
  • comment - Update description

Configuration:

  • environment_vars - Add/modify/remove env variables
  • ssh_public_key - Change SSH access key
  • realm_ids - Update API realm membership (realm-restricted tokens cannot modify this)
  • autostart - Enable/disable auto-start
  • ai - Enable/disable AI features
  • ramdisk - Enable/disable ramdisk mount

What you CANNOT change:

  • container_image - OS is permanent (create new container instead)
  • hoody_kit - Service installation is permanent
  • server_id - Cannot move servers (use copy instead)

Example 1: Change Environment

Terminal window
# Switch from staging to production
PATCH /api/v1/containers/{id}
{
"environment_vars": {
"NODE_ENV": "production",
"API_BASE_URL": "https://api.mycompany.com"
}
}

Example 2: Move to Different Realm

Terminal window
# Isolate to production network
PATCH /api/v1/containers/{id}
{
"realm_ids": ["64a2c4e9f3d5e2b6a8c7d8e1"]
}

Permanent deletion of a container and all its data.

DELETE Delete a container permanently
/api/v1/containers/{container_id}
Click "Run" to execute the request

What gets deleted:

  • ✅ Container filesystem and all data
  • ✅ Environment variables
  • ✅ Network configuration
  • ✅ Firewall rules
  • ✅ All service URLs become inaccessible
  • Snapshots are preserved (until you delete them)
  • Existing copies keep running (they are independent containers, but can no longer be synced — the source link is broken)
Terminal window
# 1. Create final snapshot
hoody snapshots create --container $CONTAINER_ID --alias "before-deletion-2025-11-09"
# 2. Stop running container
hoody containers manage $CONTAINER_ID stop
# 3. Permanent deletion
hoody containers delete $CONTAINER_ID
# 4. Cleanup (optional) - delete proxy aliases
hoody proxy delete $ALIAS_ID

Best practice: Keep snapshots of production containers for disaster recovery.


When you set hoody_kit: true, your container gets the full Hoody Kit HTTP stack:

Interact & Visualize:

Data & State:

Automate & Orchestrate:

Operate & Monitor:

Installation time: Added to container creation (no extra wait).

See: The Hoody Kit for complete service documentation.


Containers progress through these states:

creating → running → (paused) → stopped → deleted
↓ ↑
(can pause) (can restart)
StateDescriptionTransitions Available
creatingContainer being provisionedrunning (automatic)
runningContainer is activestopped, paused
pausedContainer suspendedrunning (resume)
stoppedContainer is stoppedrunning (start)
failedCreation or operation faileddeleted (cleanup)
copyingBeing copied to another locationrunning (when complete)
deletedMarked for deletion(final state)

Get current state:

GET Get container status
/api/v1/containers/{container_id}
Click "Run" to execute the request

See: Managing Containers for state transitions.


Find containers across all projects:

GET List all containers for your account
/api/v1/containers
Click "Run" to execute the request
GET List containers in a specific project
/api/v1/projects/{project_id}/containers
Click "Run" to execute the request
GET Filter and paginate containers
/api/v1/containers
Click "Run" to execute the request

Get live service status:

GET Get container with runtime information
/api/v1/containers/{container_id}
Click "Run" to execute the request

Response includes:

  • Active terminal sessions
  • Display connections
  • Running services (with PIDs)
  • Network services and ports
  • Command history

Use this to verify services are running before using their URLs.


From project creation to running container:

Terminal window
# 1. Create a project
hoody projects create --alias "client-acme" --color "#e74c3c"
# 2. Check your servers
hoody servers list
# 3. Create a container
hoody containers create --project $PROJECT_ID \
--server-id $SERVER_ID \
--name "acme-frontend" \
--hoody-kit \
--ssh-public-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA..."
# 4. Verify it's running
hoody containers get $CONTAINER_ID
# 5. Container URLs are live:
# https://{project_id}-{container_id}-terminal-1.{server_name}.containers.hoody.icu
# https://{project_id}-{container_id}-display-1.{server_name}.containers.hoody.icu

Configure prespawn templates for production containers to eliminate startup delays. Sub-second availability means faster auto-scaling, instant failover, and better user experience.

Never reuse SSH keys. Generate a new ed25519 key pair for each container to ensure proper routing via Hoody’s SSH Proxy.

Terminal window
ssh-keygen -t ed25519 -f ~/.ssh/container-{name} -N ""

When using AI agents, isolate containers in different realms to prevent accidents. An agent in realm A cannot discover or manage containers in realm B - complete API-level separation ensures safety.

Use Qubes-style color coding: red for public-facing, green for internal services, blue for databases, yellow for development. Visual identification beats reading labels.

Always create a snapshot before permanently deleting important containers. The snapshot preserves all data for recovery if needed.

Critical services: autostart: true (ensures availability after host reboots). Development containers: autostart: false (saves resources).

Unless you have specific requirements, stick with debian/13 for excellent stability, security, and package availability.

ramdisk is enabled by default—use it for ultra-fast temporary storage (caches, build artifacts, temporary processing). Remember: empty ramdisk consumes zero RAM.


Can I change the OS after creating a container?

Section titled “Can I change the OS after creating a container?”

No. The container_image is permanent. To use a different OS:

  1. Snapshot your data
  2. Create new container with desired image
  3. Transfer data via storage shares or manual copy
  4. Delete old container

Optionally limited by the max_containers quota on your project (unset by default, so there’s no per-project cap unless you set one). Get the current quota via GET /api/v1/projects/{id}. Free servers cap at 10 containers each. No platform-wide limit—create as many projects as needed.

Status becomes failed. Check error via GET /api/v1/containers/{id}. Common causes:

  • Server out of capacity
  • Invalid image name
  • Resource quota exceeded
  • Network issues

Delete the failed container and try again.

Can I create containers without hoody_kit?

Section titled “Can I create containers without hoody_kit?”

Yes! Set hoody_kit: false for plain Linux containers. Important limitations:

  • No Hoody Proxy - Container services won’t be accessible via HTTP
  • No Hoody Kit HTTP stack - No terminal, display, files, exec, etc.
  • SSH access only - But ONLY if you provide ssh_public_key (defaults to null otherwise)
  • ⚠️ No web access at all - Without hoody_kit AND without SSH key, container is completely inaccessible

Use when: You need minimal overhead, custom service installations, or are managing everything via SSH yourself.

Recommendation: Almost always use hoody_kit: true. The HTTP services are what make Hoody powerful.

Storage charges apply to stopped containers (they still occupy disk space). CPU/RAM charges stop when container is stopped. Minimize cost: delete unused containers or use minimal storage allocation.

Can I create containers on multiple servers simultaneously?

Section titled “Can I create containers on multiple servers simultaneously?”

Yes. Each container creation is independent. Spawn 100 containers across 10 servers in parallel—all via standard HTTP requests. Common pattern for auto-scaling or testing.

What’s the fastest way to create a container?

Section titled “What’s the fastest way to create a container?”

Use prespawn templates - pre-created container pools that are claimed in milliseconds (sub-second). Regular creation: 1-5 seconds.

Can I automate container creation with CI/CD?

Section titled “Can I automate container creation with CI/CD?”

Absolutely. Create auth token, store as GitHub Secret, use curl in workflows. Container creation is just an HTTP POST—works in any CI/CD system.

How do I know which services are running in my container?

Section titled “How do I know which services are running in my container?”

Query with runtime=true parameter:

Terminal window
GET /api/v1/containers/{id}?runtime=true

Response shows active services with PIDs, ports, and connection status.


Problem: Container status remains “creating” for longer than expected

Typical creation time: 1-5 seconds (prespawn: sub-second)

If longer than 2 minutes:

  1. Check server status:

    Terminal window
    curl "https://api.hoody.icu/api/v1/servers/{server_id}" \
    -H "Authorization: Bearer $HOODY_TOKEN"
    # Verify server is "ready", not "maintenance"
  2. Check server capacity:

    • Server may be at capacity
    • Try different server_id
  3. Wait and re-check:

    • Complex images take longer
    • First creation on server takes longer (image pull)
    • Hoody Kit installation adds ~10-15 seconds
  4. If stuck >5 minutes:

    • Delete and recreate
    • Or contact support with container_id

Problem: Update request returns 400 Bad Request

Common causes:

  1. Container is running:

    Terminal window
    # Stop first
    POST /api/v1/containers/{id}/stop
    # Then update
    PATCH /api/v1/containers/{id}
  2. Invalid values:

    • Name must be unique in project
    • Color must be valid HEX format
    • SSH public key must be unique (can’t reuse across containers)
    • realm_ids must be array of valid realm IDs
  3. Immutable fields:

    • Cannot change container_image
    • Cannot change hoody_kit
    • Cannot change server_id

Problem: Response shows status: "failed" immediately

Check error details:

Terminal window
curl "https://api.hoody.icu/api/v1/containers/{failed_container_id}" \
-H "Authorization: Bearer $HOODY_TOKEN"
# Look for error message in response

Common issues:

  1. Invalid image name:

    Terminal window
    # ❌ Wrong: "ubuntu:22.04" or "ubuntu-22.04"
    # ✅ Correct: "ubuntu/24.04" or "debian/13"
  2. Server quota exceeded:

    • Server out of CPU/RAM
    • Choose different server
  3. Project quota:

    Terminal window
    # Check project limits
    GET /api/v1/projects/{id}
    # Look at: max_containers

Problem: Delete operation fails

Solutions:

  1. Stop container first:

    Terminal window
    POST /api/v1/containers/{id}/stop
    # Wait for stopped status
    GET /api/v1/containers/{id}
    # Then delete
    DELETE /api/v1/containers/{id}
  2. Remove proxy aliases:

    Terminal window
    # List aliases for container
    GET /api/v1/proxy/aliases?container_id={id}
    # Delete each alias
    DELETE /api/v1/proxy/aliases/{alias_id}
    # Then delete container
  3. Check permissions:

    • Verify you own the container
    • Check you’re using correct auth token

Problem: Container created but service URLs return errors

Debug steps:

  1. Verify container is running:

    Terminal window
    GET /api/v1/containers/{id}
    # Check: "status": "running"
  2. Wait for services to start:

    • Container may be running but services still initializing
    • Wait 30-60 seconds after status: "running"
  3. Check runtime information:

    Terminal window
    GET /api/v1/containers/{id}?runtime=true
    # Verify services are listed in runtime_info
  4. Verify hoody_kit was enabled:

    Terminal window
    GET /api/v1/containers/{id}
    # Check: "hoody_kit": true

Your container is running:

  1. Managing Containers → - Start, stop, pause, resume operations
  2. Snapshots → - Backup and restore your container state
  3. Copy & Sync → - Duplicate containers across projects/servers

Configure access and networking:

Understanding gained:

  • ✅ Containers are created via HTTP POST
  • ✅ Hoody Kit provides the full HTTP service stack automatically
  • ✅ Container configuration can be updated (when stopped)
  • ✅ Deletion is permanent (snapshot first!)
  • ✅ Service URLs follow predictable pattern

Spawn containers like you spawn URLs.
Configure them via HTTP.
Delete them when you’re done.
This is the foundation of infinite computers.