Skip to content

Containers transition between states via HTTP endpoints. Start them when needed, pause for efficiency, stop for maintenance, resume instantly.

After creating containers, you need to manage their lifecycle through various operational states.


Official Technical Reference:

This Foundation page explains container operation concepts and patterns. For complete endpoint documentation:

Lifecycle Operations:

Status Tracking:

Related:


Containers exist in distinct operational states:

start
stopped ────────→ running
↑ ↓
│ │ pause
│ ↓
│ paused
│ ↓
│ │ resume
│ ↓
└────── stop ── running
StateDescriptionAvailable Operations
runningContainer is active, all services availablestop, force-stop, restart, pause
stoppedContainer is halted, no processes runningstart, restart, delete
pausedContainer suspended, state frozen in RAMresume
creatingBeing provisioned (automatic)(wait for completion)
failedOperation faileddelete, diagnose
copyingBeing duplicated(wait for completion)

Bring a stopped container back to life.

POST Start a stopped container
/api/v1/containers/{container_id}/start
Click "Run" to execute the request

Response:

{
"statusCode": 200,
"message": "Container started successfully",
"data": {
"operation": "start",
"container_id": "890abcdef12345678901cdef",
"status": "running"
}
}

What happens:

  1. Container processes initialize
  2. Hoody Kit services start (if enabled)
  3. Network connectivity established
  4. Service URLs become accessible

Typical start time: 5-15 seconds

Containers start automatically when:

  • Just created (if not autostart: false)
  • Server boots (if autostart: true)
  • Restored from snapshot

Manual start needed when:

  • Container was previously stopped
  • After maintenance/updates
  • For cost optimization (keep containers stopped when not in use)

Gracefully shut down a running container.

POST Gracefully stop a running container
/api/v1/containers/{container_id}/stop
Click "Run" to execute the request

What happens:

  1. SIGTERM sent to all processes
  2. Processes given time to clean up
  3. If they do not exit, SIGKILL is sent (forced termination)
  4. Container status changes to stopped

Use case: Normal shutdown before updates, maintenance, or resource conservation.

Immediately terminate all processes:

POST Force stop a container immediately
/api/v1/containers/{container_id}/force-stop
Click "Run" to execute the request

What happens:

  • SIGKILL sent immediately (no graceful shutdown)
  • All processes terminated instantly
  • No cleanup time given

When to force-stop:

  • Graceful stop hangs or times out
  • Emergency situations (runaway process)
  • Container is unresponsive

Stop then start in one operation.

POST Restart a container
/api/v1/containers/{container_id}/restart
Click "Run" to execute the request

Equivalent to:

  1. Graceful stop
  2. Wait for stopped state
  3. Start

Use cases:

  • Apply configuration changes
  • Clear in-memory state
  • Recover from issues
  • Regular maintenance restarts

Restart time: Stop (5-10s) + Start (5-15s) = 10-25 seconds total


Suspend container without full shutdown.

POST Pause a running container
/api/v1/containers/{container_id}/pause
Click "Run" to execute the request

What happens:

  • All container processes frozen
  • State saved in RAM
  • No CPU usage
  • Minimal memory usage
  • Service URLs return errors

Use cases:

  • Temporary suspension during resource constraints
  • Freeze state for debugging
  • Quick pause/resume cycles
POST Resume a paused container
/api/v1/containers/{container_id}/resume
Click "Run" to execute the request

What happens:

  • Processes unfrozen
  • Execution continues exactly where paused
  • All state preserved (open files, network connections, terminal sessions)
  • Service URLs become accessible again

Resume time: Nearly instant (1-2 seconds)

Pause/Resume

Speed:

  • Pause: ~1 second
  • Resume: ~1-2 seconds

State:

  • ✅ All processes frozen
  • ✅ RAM state preserved
  • ✅ Network connections maintained
  • ✅ Open files preserved

Limitations:

  • Requires RAM for state
  • Cannot update configuration
  • Cannot snapshot while paused

Best for: Quick suspension

Stop/Start

Speed:

  • Stop: ~5-10 seconds
  • Start: ~5-15 seconds

State:

  • ❌ All processes terminated
  • ❌ RAM state lost
  • ❌ Network connections closed
  • ✅ Filesystem preserved

Benefits:

  • Can update configuration
  • Can create snapshots
  • Zero RAM usage
  • Clean state on restart

Best for: Maintenance, updates

Choose pause/resume for temporary suspension. Choose stop/start for configuration changes or clean state.


Terminal window
# Morning: Start your dev container
hoody containers manage $DEV_ID start
# Work all day via container URLs
# https://{project}-{container}-terminal-1.{server}.containers.hoody.icu
# https://{project}-{container}-display-1.{server}.containers.hoody.icu
# Evening: Pause (instant resume tomorrow)
hoody containers manage $DEV_ID pause

Why pause instead of stop:

  • Resume in 1-2 seconds (vs 15 seconds restart)
  • Terminal sessions preserved
  • Open editors maintained
  • No state lost
Terminal window
# 1. Stop container gracefully
hoody containers manage $PROD_ID stop
# 2. Update configuration
hoody containers update $PROD_ID --environment-vars CONFIG_VERSION=2.0
# 3. Restart with new config
hoody containers manage $PROD_ID start

Stop containers when not in use:

// Stop non-critical containers during off-hours.
// `/api/v1/containers` returns all your containers — filter client-side by name.
const nonCritical = ['staging-api', 'test-db', 'dev-frontend'];
const { data: all } = await fetch(
'https://api.hoody.icu/api/v1/containers',
{ headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }}
).then(r => r.json());
const targets = all.containers.filter(
c => nonCritical.includes(c.name) && c.status === 'running'
);
for (const c of targets) {
await fetch(
`https://api.hoody.icu/api/v1/containers/${c.id}/stop`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }
}
);
}

Automate with cron: Schedule stops at 6 PM, starts at 8 AM.

Terminal window
# Unresponsive container? Try graceful stop first
hoody containers manage $CONTAINER_ID stop
# If that hangs or fails, force it
hoody containers manage $CONTAINER_ID force-stop
# Restart clean
hoody containers manage $CONTAINER_ID start

Track every state transition with detailed logs.

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

Response:

{
"statusCode": 200,
"message": "Status logs retrieved successfully",
"data": {
"logs": [
{
"id": "63f8b0e5c9a1b2d3e4f5a6b7",
"container_id": "890abcdef12345678901cdef",
"from_status": "stopped",
"to_status": "running",
"transition_time": "2025-11-09T14:30:00.000Z",
"duration_ms": 12450,
"triggered_by": "user_abc123",
"metadata": {
"operation": "start",
"server_name": "node-us"
}
},
{
"from_status": "running",
"to_status": "stopped",
"transition_time": "2025-11-09T10:15:00.000Z",
"duration_ms": 8320,
"triggered_by": "automation_script"
}
],
"pagination": {
"total": 47,
"page": 1,
"limit": 10,
"totalPages": 5
}
}
}

What you learn:

  • When states changed
  • How long transitions took
  • Who/what triggered the change
  • Complete audit trail

1. Debugging Issues:

Terminal window
# Check if container had recent failures
GET /api/v1/containers/{id}/status-logs?sort_order=desc&limit=20
# Look for: failed states, unexpected stops, slow starts

2. Performance Analysis:

Terminal window
# Analyze startup times
GET /api/v1/containers/{id}/status-logs
# Check duration_ms for "stopped → running" transitions
# Optimize if consistently slow

3. Audit Trail:

Terminal window
# Who stopped the production container?
GET /api/v1/containers/{prod_id}/status-logs
# Check triggered_by field for user/automation identification

Understanding how long operations take:

OperationTypical DurationWhat Happens
Start5-15 secondsBoot processes, start services
Stop5-10 secondsGraceful shutdown, cleanup
Force-Stop<1 secondImmediate kill
Restart10-25 secondsStop + Start
Pause~1 secondFreeze all processes
Resume1-2 secondsUnfreeze, continue execution

Factors affecting timing:

  • Container image complexity
  • Number of running processes
  • Allocated resources
  • Hoody Kit services (more services = slightly longer)
  • Server load

Start all project containers:

// Get all containers in project
const response = await fetch(
`https://api.hoody.icu/api/v1/projects/${projectId}/containers`,
{ headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }}
);
const containers = await response.json();
// Start all stopped containers
for (const container of containers.data.containers) {
if (container.status === 'stopped') {
await fetch(
`https://api.hoody.icu/api/v1/containers/${container.id}/start`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }
}
);
console.log(`Started: ${container.name}`);
}
}

Stop containers based on criteria:

// Stop all paused containers (free up RAM).
// The list endpoint takes no status filter — filter client-side on the returned array.
const { data } = await fetch(
'https://api.hoody.icu/api/v1/containers',
{ headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }}
).then(r => r.json());
const paused = data.containers.filter(c => c.status === 'paused');
for (const container of paused) {
await fetch(
`https://api.hoody.icu/api/v1/containers/${container.id}/stop`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }
}
);
}

Restart multiple containers simultaneously:

const containerIds = [
'890abcdef12345678901cdef',
'901bcdef12345678901cdefa',
'012cdef123456789abcdef01'
];
// Restart all in parallel
await Promise.all(
containerIds.map(id =>
fetch(`https://api.hoody.icu/api/v1/containers/${id}/restart`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }
})
)
);
console.log('All containers restarted');

Control whether containers start automatically on server boot.

Terminal window
# Stop container first
hoody containers manage $CONTAINER_ID stop
# Enable autostart
hoody containers update $CONTAINER_ID --autostart
# Restart container
hoody containers manage $CONTAINER_ID start

Now this container auto-starts when:

  • Server reboots
  • Server maintenance completes
  • After power failure recovery

✅ Enable autostart for:

  • Production services (must be always available)
  • Critical infrastructure (databases, APIs)
  • Monitoring containers (must run continuously)
  • Automation containers (CI/CD, cron jobs)

❌ Disable autostart for:

  • Development environments (start manually when needed)
  • Testing containers (ephemeral)
  • Resource-intensive containers (start on-demand)
  • Temporary/experimental containers

Terminal window
# 1. Snapshot current state (safety)
hoody snapshots create --container $CONTAINER_ID --alias "pre-deploy-2025-11-09"
# 2. Access terminal to deploy, then deploy code
# 3. Restart container for clean state
hoody containers manage $CONTAINER_ID restart
# 4. Verify services are running
hoody containers get $CONTAINER_ID --runtime true

If deployment fails: Restore snapshot to roll back.

// Automated maintenance script
async function performMaintenance(containerId) {
const token = process.env.HOODY_TOKEN;
const headers = { 'Authorization': `Bearer ${token}` };
// 1. Stop container
await fetch(
`https://api.hoody.icu/api/v1/containers/${containerId}/stop`,
{ method: 'POST', headers }
);
// 2. Wait for stopped
await waitForStatus(containerId, 'stopped');
// 3. Update resources
await fetch(
`https://api.hoody.icu/api/v1/containers/${containerId}`,
{
method: 'PATCH',
headers: {
...headers,
'Content-Type': 'application/json'
},
body: JSON.stringify({
environment_vars: {
"UPDATED": "true"
}
})
}
);
// 4. Restart
await fetch(
`https://api.hoody.icu/api/v1/containers/${containerId}/start`,
{ method: 'POST', headers }
);
// 5. Verify running
const status = await fetch(
`https://api.hoody.icu/api/v1/containers/${containerId}`,
{ headers }
).then(r => r.json());
return status.data.status === 'running';
}
// Run at 2 AM via cron
performMaintenance('890abcdef12345678901cdef');

Pause containers during low-usage periods:

Terminal window
# List containers (filter by status client-side)
hoody containers list
# Pause each non-critical container
hoody containers manage $CONTAINER_ID pause
# Morning: Resume all paused
hoody containers list
hoody containers manage $CONTAINER_ID resume

Cost savings: CPU hours not charged while paused (minimal RAM charge).

Terminal window
# 1. Start green container
hoody containers manage $GREEN_ID start
# 2. Verify green is healthy
hoody containers get $GREEN_ID --runtime true
# 3. Re-point alias to green (delete + recreate — container_id is immutable)
hoody proxy delete $ALIAS_ID
hoody proxy create --container-id $GREEN_ID \
--alias "prod" --program "web" --index 1 --target-path "/"
# 4. Monitor green in production
# 5. After verification, stop blue
hoody containers manage $BLUE_ID stop

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

Key fields:

  • status: Current state (running, stopped, paused)
  • updated_at: Last modification time
GET Get container with live service data
/api/v1/containers/{container_id}
Click "Run" to execute the request

Shows:

  • Active terminal sessions
  • Display connections
  • Running services (PIDs, ports)
  • Network services
  • Memory/CPU usage
GET Get status history
/api/v1/containers/{container_id}/status-logs
Click "Run" to execute the request

Analyze:

  • Frequency of restarts (stability indicator)
  • Downtime duration
  • Who triggered changes
  • Operation timing patterns

1. Always Snapshot Before Risky Operations

Section titled “1. Always Snapshot Before Risky Operations”
Terminal window
# Before forcing stop or major changes
POST /api/v1/containers/{id}/snapshots
{"alias": "before-maintenance"}
Terminal window
# ✅ Preferred (gives processes time to cleanup)
POST /api/v1/containers/{id}/stop
# ❌ Last resort only (can corrupt data)
POST /api/v1/containers/{id}/force-stop
Terminal window
# Don't assume success - verify
async function stopContainer(id) {
await fetch(`https://api.hoody.icu/api/v1/containers/${id}/stop`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
});
// Poll until stopped
let attempts = 0;
while (attempts < 30) {
const status = await fetch(
`https://api.hoody.icu/api/v1/containers/${id}`,
{ headers: { 'Authorization': `Bearer ${token}` }}
).then(r => r.json());
if (status.data.status === 'stopped') {
return true;
}
await new Promise(r => setTimeout(r, 1000));
attempts++;
}
throw new Error('Container did not stop in time');
}
Terminal window
# Add context to operations via comments
# (Though API doesn't accept comment on operations, document externally)
# In your automation scripts:
// Stopping container for scheduled backup - see RUNBOOK.md section 4.2
await stopContainer(prodId);

5. Coordinate with Team for Shared Containers

Section titled “5. Coordinate with Team for Shared Containers”

Before stopping shared containers:

  • Notify team via chat/email
  • Check who’s connected: GET /api/v1/containers/{id}?runtime=true
  • Look at runtime_info.displays.connected_clients and runtime_info.terminals
  • Schedule during off-hours when possible

See: Multiplayer by Default for collaboration context.


Can I start multiple containers simultaneously?

Section titled “Can I start multiple containers simultaneously?”

Yes! Operations are independent HTTP requests. Start 100 containers in parallel:

await Promise.all(
containerIds.map(id =>
fetch(`https://api.hoody.icu/api/v1/containers/${id}/start`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` }
})
)
);

What happens to service URLs when container is stopped?

Section titled “What happens to service URLs when container is stopped?”

All service URLs return connection errors or 503 Service Unavailable. The URLs exist but services aren’t running. On restart, same URLs become accessible again.

Can I pause a container, then update its configuration?

Section titled “Can I pause a container, then update its configuration?”

No. Configuration updates require stopped status, not paused. Workflow: resume → stop → update → start.

Does autostart work across server reboots?

Section titled “Does autostart work across server reboots?”

Yes. When your server restarts (maintenance, updates, power cycle), all containers with autostart: true start automatically. Typically within 1-2 minutes of server being back online.

Can I be notified when operations complete?

Section titled “Can I be notified when operations complete?”

Not directly via the API. Poll container status or status-logs endpoints. Or use hoody-notifications service within containers to send alerts when operations complete.

What happens if I stop a container while someone is using it?

Section titled “What happens if I stop a container while someone is using it?”

All connections terminate immediately. Active terminal sessions close. Display disconnects. File operations fail. Always coordinate with users before stopping shared containers. Consider multiplayer implications.

Do paused containers count toward resource quotas?

Section titled “Do paused containers count toward resource quotas?”

Yes for RAM (state is in memory). No for CPU (processes frozen). Storage always counts. Pausing doesn’t free up resource quotas.

Can containers auto-restart if they crash?

Section titled “Can containers auto-restart if they crash?”

Not automatically via the API. Implement monitoring that checks status and restarts if needed. Or use systemd inside containers for process-level auto-restart. Or configure autostart: true for server boot recovery.

What’s the difference between restart and stop+start?

Section titled “What’s the difference between restart and stop+start?”

Functionally identical. restart is convenience endpoint that does stop then start in one call. Same total time, same result, less API calls.


Problem: Start operation fails or container stuck in “creating”

Solutions:

  1. Check status logs:

    Terminal window
    GET /api/v1/containers/{id}/status-logs?limit=5&sort_order=desc
    # Look for error messages in metadata
  2. Verify server is available:

    Terminal window
    GET /api/v1/servers/{server_id}
    # Check: status should be "ready", not "maintenance"
  3. Check resource availability:

    • Server may be at capacity
    • Try reducing allocated resources
    • Or move to different server via copy
  4. Look for image issues:

    Terminal window
    GET /api/v1/containers/{id}
    # Check container_image is valid

Problem: Stop operation doesn’t complete

Cause: Container processes not responding to SIGTERM

Solutions:

  1. Retry the graceful stop:

    Terminal window
    POST /api/v1/containers/{id}/stop
  2. Force stop if necessary:

    Terminal window
    POST /api/v1/containers/{id}/force-stop
  3. Check what’s running:

    Terminal window
    # SSH or terminal into container
    ps aux
    # Identify stuck processes

Problem: Resume operation returns error

Causes & Solutions:

  1. Server rebooted during pause:

    • Paused state is lost on server reboot
    • Solution: Start container instead of resume
  2. RAM pressure:

    • Server may have deallocated paused container memory
    • Solution: Start fresh (state lost)
  3. Container was modified while paused:

    • Cannot modify paused containers
    • Solution: Resume, then make changes, then re-pause

Problem: Valid operation returns 400 error

Check operation validity:

Current StateValid Operations
runningstop, force-stop, restart, pause
stoppedstart, restart, delete
pausedresume
creating(none - wait for completion)
faileddelete

Common mistakes:

  • ❌ Starting an already running container
  • ❌ Stopping an already stopped container
  • ❌ Pausing a stopped container
  • ❌ Resuming a running container

Solution: Check current status first:

Terminal window
GET /api/v1/containers/{id}
# Verify status before operation

Service URLs Still Not Working After Start

Section titled “Service URLs Still Not Working After Start”

Problem: Container status shows “running” but service URLs fail

Debug steps:

  1. Wait for services to initialize:

    • Status changes to “running” before all services are ready
    • Wait 30-60 seconds after start
  2. Check runtime info:

    Terminal window
    GET /api/v1/containers/{id}?runtime=true
    # Verify services appear in runtime_info.services
    # Check for "active" status
  3. Verify hoody_kit is enabled:

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

    Terminal window
    # SSH or terminal into container
    systemctl status hoody-terminal
    systemctl status hoody-display
    # etc.

Problem: Container restarts unexpectedly

Check causes:

  1. Autostart enabled + server rebooted:

    Terminal window
    GET /api/v1/containers/{id}
    # Check: "autostart": true
  2. Check status logs for pattern:

    Terminal window
    GET /api/v1/containers/{id}/status-logs?limit=20
    # Look for frequent "stopped → running" transitions
    # Check triggered_by field
  3. Process-level crashes:

    • Container OS auto-restarts
    • Check logs inside container
    • Or configure alerting via hoody-notifications

Master container operations:

  1. Snapshots → - Capture state before operations, restore if needed
  2. Copy & Sync → - Duplicate containers for redundancy
  3. Images → - Choose optimal OS for your workload

Operational topics:

Understanding gained:

  • ✅ Containers transition via HTTP operations
  • ✅ Start/stop for configuration changes
  • ✅ Pause/resume for quick suspension
  • ✅ Force-stop only in emergencies
  • ✅ Status logs track all transitions
  • ✅ Autostart controls boot behavior

Start containers when needed.
Pause for quick suspension.
Stop for maintenance.
Resume instantly.
All via HTTP endpoints. All in seconds.

Test container operations directly from your browser:

Manage container lifecycle - set operation to: start, stop, force-stop, restart, pause, or resume

Path Parameters

Authentication

🔒 Not Authenticated

Use the authentication widget in the header to login or set an API token

Authentication: Authorization: Bearer header (auto-attached for trusted domains)

Custom Headers

Request Body (JSON)