Skip to content
Hoody.com

A container moves between states through HTTP endpoints: start, stop, force-stop, restart, pause, and resume. Every transition is recorded in a status log you can read back.

This page covers the lifecycle operations available once you have created a container.


This page explains the concepts behind container operations. The endpoint reference carries the full request and response schemas.

Lifecycle operations:

Status tracking:

Related:


The lifecycle operations move a container between these 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, stop, force-stop
creatingBeing provisioned (automatic)(wait for completion)
failedOperation faileddelete
copyingBeing duplicated(wait for completion)

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

Response:

{
"statusCode": 200,
"message": "Container operation completed successfully",
"data": {
"error": false,
"operation": "start",
"container_id": "890abcdef12345678901cdef",
"project_id": "012cdef123456789abcdef01",
"message": "Container started successfully",
"status": "running"
}
}

What happens:

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

Start usually completes in seconds. Heavier containers take longer.

A container starts automatically when it is:

  • Just created (if not autostart: false)
  • On the server’s boot (if autostart: true)
  • Restored from snapshot

Start it manually when:

  • The container was previously stopped
  • Maintenance or updates have finished
  • You keep containers stopped when not in use to save cost

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.

Terminate every process immediately:

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

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: one graceful stop plus one start, back to back.


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: one to two 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
  • Already-running processes keep the environment they started with; they see updated variables only after they re-exec
  • Snapshots cannot be created while paused; resume or stop first. Snapshots capture filesystem state only, not RAM

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:

  • Configured services start from a clean runtime state; stop/start does not automatically make systemd services inherit the container’s environment variables
  • Can create snapshots
  • Zero RAM usage
  • Clean state on restart

Best for: Maintenance, updates

Choose pause and resume for temporary suspension. Choose stop and start when you need a clean runtime state, or when configured services have to restart. Environment-variable changes generally do not require a restart: after a successful live sync, new exec and console processes see the updated values immediately, and dedicated containers env writes reach new SSH and console logins. Systemd services do not automatically inherit the container’s environment variables after a stop and start.


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.com
# https://{project}-{container}-display-1.{server}.containers.hoody.com
# Evening: Pause (resumes in seconds tomorrow)
hoody containers manage $DEV_ID pause

Why pause instead of stop:

  • Resume takes one to two seconds, against a full stop and start cycle
  • Terminal sessions are preserved
  • Open editors stay open
  • No in-memory state is 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.com/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.com/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
# If the container is unresponsive, try a 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

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": {
"command": "start"
}
},
{
"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:

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

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.com/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.com/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.com/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.com/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.com/api/v1/containers/${id}/restart`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }
})
)
);
console.log('All containers restarted');

Autostart controls whether a container starts by itself when its server boots.

Terminal window
# Enable autostart
hoody containers update $CONTAINER_ID --autostart

The container then starts automatically when:

  • The server reboots
  • Server maintenance completes
  • The server recovers from a power failure

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.com/api/v1/containers/${containerId}/stop`,
{ method: 'POST', headers }
);
// 2. Wait for stopped
await waitForStatus(containerId, 'stopped');
// 3. Update resources
await fetch(
`https://api.hoody.com/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.com/api/v1/containers/${containerId}/start`,
{ method: 'POST', headers }
);
// 5. Verify running
const status = await fetch(
`https://api.hoody.com/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

Result: Paused containers consume no CPU on your server. Their frozen state stays in RAM until you resume them.

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 "http" --port 3000 --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

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.com/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.com/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
# (The API has no comment field on operations, so record the reason elsewhere)
# In your automation scripts:
// Stopping container for scheduled backup - see RUNBOOK.md section 4.2
await stopContainer(prodId);

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, so you can start 100 containers in parallel:

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

What happens to service URLs when a container is stopped?

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

Every service URL returns a connection error or 503 Service Unavailable. The URLs still exist; the services behind them are not running. After a restart, the same URLs work again.

Can I pause a container, then update its configuration?

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

Yes for most fields. PATCH /api/v1/containers/{id} accepts the name, autostart, environment variables, and SSH key in any state, including paused. Two limits apply: narrowing ramdisk_scope is rejected while the container is running, and snapshots cannot be created while it is paused.

Environment-variable changes generally do not require a restart. After a successful live sync, new exec and console processes see the updated values immediately, and the dedicated containers env endpoints also rewrite /etc/environment so new SSH and console logins pick them up. Already-running processes see the new values only after they re-exec.

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 once the server is back online.

Can I be notified when operations complete?

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

Not directly via the API. Poll the container status or status-logs endpoints, or run the hoody-notifications service inside the container to send an alert when an operation finishes.

What if I stop a container someone is using?

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

Every connection terminates immediately: terminal sessions close, displays disconnect, and in-flight file operations fail. Coordinate with other users before stopping a shared container, and consider the multiplayer implications.

Do paused containers count toward resource quotas?

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

A paused container keeps its frozen state in the server’s RAM and its disk usage unchanged, and it still counts toward any container-count limit. Only its CPU goes quiet.

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 a convenience endpoint that does the stop and the start in one call: same total time, same result, one request instead of two.


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 and 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)

Problem: Valid operation returns 400 error

Check operation validity:

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

The API’s own gate is coarse: the container must be in running, stopped, or paused to be managed at all. Finer refusals (starting an already-running container, for instance) come from the host.

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

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

Container operations:

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

Operational topics:

What this page covered:

  • Containers transition between states via HTTP operations
  • Stop and start give a clean runtime state or restart configured services; they are not a general environment-variable propagation mechanism
  • Pause and resume handle quick suspension
  • Force-stop belongs to emergencies only
  • Status logs record every transition
  • Autostart controls boot behavior

Test container operations 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)