# Managing Containers

**Page:** foundation/containers/managing

[Download Raw Markdown](./foundation/containers/managing.md)

---

# Managing Containers

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

After [creating containers](/foundation/containers/create-edit-delete/), you need to **manage their lifecycle** through various operational states.

---

## API Endpoints Summary

**Official Technical Reference:**

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

**Lifecycle Operations:**
- **[POST /api/v1/containers/\{id\}/start](/api/container-operations/)** - Start stopped container
- **[POST /api/v1/containers/\{id\}/stop](/api/container-operations/)** - Gracefully stop container
- **[POST /api/v1/containers/\{id\}/force-stop](/api/container-operations/)** - Immediately terminate
- **[POST /api/v1/containers/\{id\}/restart](/api/container-operations/)** - Stop then start
- **[POST /api/v1/containers/\{id\}/pause](/api/container-operations/)** - Suspend container
- **[POST /api/v1/containers/\{id\}/resume](/api/container-operations/)** - Resume suspended container

**Status Tracking:**
- **[GET /api/v1/containers/\{id\}/status-logs](/api/container-operations/)** - View state transition history

**Related:**
- **[GET /api/v1/containers/\{id\}](/api/containers/)** - Get current container status

---

## Container States

**Containers exist in distinct operational states:**

```
          start
stopped ────────→ running
   ↑                 ↓
   │                 │ pause
   │                 ↓
   │              paused
   │                 ↓
   │                 │ resume
   │                 ↓
   └────── stop ── running
```

### State Descriptions

| State | Description | Available Operations |
|-------|-------------|---------------------|
| `running` | Container is active, all services available | stop, force-stop, restart, pause |
| `stopped` | Container is halted, no processes running | start, restart, delete |
| `paused` | Container suspended, state frozen in RAM | resume |
| `creating` | Being provisioned (automatic) | (wait for completion) |
| `failed` | Operation failed | delete, diagnose |
| `copying` | Being duplicated | (wait for completion) |

---

## Starting Containers

**Bring a stopped container back to life.**

### Basic Start



**Response:**

```json
{
  "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

### When to Start

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

---

## Stopping Containers

**Gracefully shut down a running container.**

### Graceful Stop



**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.

### Force Stop

**Immediately terminate all processes:**



**What happens:**
- SIGKILL sent immediately (no graceful shutdown)
- All processes terminated instantly
- No cleanup time given


**Force-stop can cause data corruption** if processes are writing to disk. Use only when graceful stop hangs or in emergency situations.


**When to force-stop:**
- Graceful stop hangs or times out
- Emergency situations (runaway process)
- Container is unresponsive

---

## Restarting Containers

**Stop then start in one operation.**

### Basic Restart



**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

---

## Pausing & Resuming

**Suspend container without full shutdown.**

### Pause (Suspend)



**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

### Resume



**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 vs Stop

<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin: 1.5rem 0;">

<div style="padding: 1.25rem; background: #f8f8f8; border: 1px solid #ddd; border-radius: 4px;">

**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

</div>

<div style="padding: 1.25rem; background: #f8f8f8; border: 1px solid #ddd; border-radius: 4px;">

**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

</div>

</div>

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

---

## Operation Patterns

### Pattern 1: Daily Development Workflow


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // Morning: Start your dev container
    await client.api.containers.manage(DEV_ID, 'start');

    // Work all day via container URLs...

    // Evening: Pause (instant resume tomorrow)
    await client.api.containers.manage(DEV_ID, 'pause');
    ```
  
  
    ```bash
    # Morning: Start your dev container
    curl -X POST "https://api.hoody.icu/api/v1/containers/{dev_id}/start" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # 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)
    curl -X POST "https://api.hoody.icu/api/v1/containers/{dev_id}/pause" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


**Why pause instead of stop:**
- Resume in 1-2 seconds (vs 15 seconds restart)
- Terminal sessions preserved
- Open editors maintained
- No state lost

### Pattern 2: Maintenance Window


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // 1. Stop container gracefully
    await client.api.containers.manage(PROD_ID, 'stop');

    // 2. Update configuration
    await client.api.containers.update(PROD_ID, {
      environment_vars: { CONFIG_VERSION: '2.0' }
    });

    // 3. Restart with new config
    await client.api.containers.manage(PROD_ID, 'start');
    ```
  
  
    ```bash
    # 1. Stop container gracefully
    curl -X POST "https://api.hoody.icu/api/v1/containers/{prod_id}/stop" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # 2. Update configuration
    curl -X PATCH "https://api.hoody.icu/api/v1/containers/{prod_id}" \
      -H "Authorization: Bearer $HOODY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"environment_vars": {"CONFIG_VERSION": "2.0"}}'

    # 3. Restart with new config
    curl -X POST "https://api.hoody.icu/api/v1/containers/{prod_id}/start" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


### Pattern 3: Resource Optimization

**Stop containers when not in use:**

```javascript
// 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.

### Pattern 4: Emergency Recovery


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // Try graceful stop first
    await client.api.containers.manage(CONTAINER_ID, 'stop');

    // If that hangs or fails, force it
    await client.api.containers.manage(CONTAINER_ID, 'force-stop');

    // Restart clean
    await client.api.containers.manage(CONTAINER_ID, 'start');
    ```
  
  
    ```bash
    # Unresponsive container? Try graceful stop first
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/stop" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # If that hangs or fails, force it
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/force-stop" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # Restart clean
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/start" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


---

## Status Logging

**Track every state transition with detailed logs.**

### Get Status Logs



**Response:**

```json
{
  "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

### Use Cases for Status Logs

**1. Debugging Issues:**
```bash
# 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:**
```bash
# Analyze startup times
GET /api/v1/containers/{id}/status-logs

# Check duration_ms for "stopped → running" transitions
# Optimize if consistently slow
```

**3. Audit Trail:**
```bash
# Who stopped the production container?
GET /api/v1/containers/{prod_id}/status-logs

# Check triggered_by field for user/automation identification
```

---

## Operation Timing

**Understanding how long operations take:**

| Operation | Typical Duration | What Happens |
|-----------|------------------|--------------|
| **Start** | 5-15 seconds | Boot processes, start services |
| **Stop** | 5-10 seconds | Graceful shutdown, cleanup |
| **Force-Stop** | `<1 second` | Immediate kill |
| **Restart** | 10-25 seconds | Stop + Start |
| **Pause** | ~1 second | Freeze all processes |
| **Resume** | 1-2 seconds | Unfreeze, continue execution |

**Factors affecting timing:**
- Container image complexity
- Number of running processes
- Allocated resources
- Hoody Kit services (more services = slightly longer)
- Server load

---

## Managing Multiple Containers

### Bulk Operations

**Start all project containers:**

```javascript
// 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}`);
  }
}
```

### Conditional Operations

**Stop containers based on criteria:**

```javascript
// 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}` }
    }
  );
}
```

### Parallel Operations

**Restart multiple containers simultaneously:**

```javascript
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');
```

---

## Autostart Configuration

**Control whether containers start automatically on server boot.**

### Enable Autostart


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // Stop container first
    await client.api.containers.manage(CONTAINER_ID, 'stop');

    // Enable autostart
    await client.api.containers.update(CONTAINER_ID, {
      autostart: true
    });

    // Restart container
    await client.api.containers.manage(CONTAINER_ID, 'start');
    ```
  
  
    ```bash
    # Stop container first
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/stop" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # Enable autostart
    curl -X PATCH "https://api.hoody.icu/api/v1/containers/{id}" \
      -H "Authorization: Bearer $HOODY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"autostart": true}'

    # Restart container
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/start" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


**Now this container auto-starts when:**
- Server reboots
- Server maintenance completes
- After power failure recovery

### When to Use Autostart

**✅ 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

---

## Real-World Scenarios

### Scenario 1: Deploy New Code


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // 1. Snapshot current state (safety)
    await client.api.containers.createSnapshot(CONTAINER_ID, {
      alias: 'pre-deploy-2025-11-09'
    });

    // 2. Deploy code via terminal...

    // 3. Restart container for clean state
    await client.api.containers.manage(CONTAINER_ID, 'restart');

    // 4. Verify services are running
    const status = await client.api.containers.get(CONTAINER_ID, { runtime: 'true' });
    console.log(status.data);
    ```
  
  
    ```bash
    # 1. Snapshot current state (safety)
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/snapshots" \
      -H "Authorization: Bearer $HOODY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{"alias": "pre-deploy-2025-11-09"}'

    # 2. Access terminal to deploy
    # https://{project}-{container}-terminal-1.{server}.containers.hoody.icu

    # 3. Restart container for clean state
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/restart" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # 4. Verify services are running
    curl "https://api.hoody.icu/api/v1/containers/{id}?runtime=true" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


**If deployment fails:** Restore snapshot to roll back.

### Scenario 2: Scheduled Maintenance

```javascript
// 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');
```

### Scenario 3: Resource Conservation

**Pause containers during low-usage periods:**


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // List running containers
    const running = await client.api.containers.list();

    // Pause non-critical containers
    for (const c of running.data.containers) {
      if (c.status === 'running' && !critical.includes(c.name)) {
        await client.api.containers.manage(c.id, 'pause');
      }
    }

    // Morning: Resume all paused
    const paused = await client.api.containers.list();
    for (const c of paused.data.containers) {
      if (c.status === 'paused') {
        await client.api.containers.manage(c.id, 'resume');
      }
    }
    ```
  
  
    ```bash
    # List all containers (no server-side status filter; filter client-side)
    curl "https://api.hoody.icu/api/v1/containers" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # Pause each non-critical container
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/pause" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # Morning: list again, filter client-side for status == "paused"
    curl "https://api.hoody.icu/api/v1/containers" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # Resume each
    curl -X POST "https://api.hoody.icu/api/v1/containers/{id}/resume" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


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

### Scenario 4: Blue-Green Deployment


  
    ```bash
    # 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
    ```
  
  
    ```typescript
    // 1. Start green container
    await client.api.containers.manage(GREEN_ID, 'start');

    // 2. Verify green is healthy
    const green = await client.api.containers.get(GREEN_ID, { runtime: 'true' });
    console.log(green.data.status); // 'running'

    // 3. Re-point alias to green (delete + recreate — container_id is immutable)
    await client.api.proxyAliases.delete(ALIAS_ID);
    await client.api.proxyAliases.create({
      container_id: GREEN_ID,
      alias: 'prod',
      program: 'web',
      index: 1,
      target_path: '/'
    });

    // 4. After verification, stop blue
    await client.api.containers.manage(BLUE_ID, 'stop');
    ```
  
  
    ```bash
    # 1. Start green container
    curl -X POST "https://api.hoody.icu/api/v1/containers/{green_id}/start" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # 2. Verify green is healthy
    curl "https://api.hoody.icu/api/v1/containers/{green_id}?runtime=true" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    # 3. Re-point alias to green (delete + recreate — container_id is immutable)
    curl -X DELETE "https://api.hoody.icu/api/v1/proxy/aliases/{alias_id}" \
      -H "Authorization: Bearer $HOODY_TOKEN"

    curl -X POST "https://api.hoody.icu/api/v1/proxy/aliases" \
      -H "Authorization: Bearer $HOODY_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "container_id": "{green_id}",
        "alias": "prod",
        "program": "web",
        "index": 1,
        "target_path": "/"
      }'

    # 4. After verification, stop blue
    curl -X POST "https://api.hoody.icu/api/v1/containers/{blue_id}/stop" \
      -H "Authorization: Bearer $HOODY_TOKEN"
    ```
  


---

## Monitoring Container Operations

### Check Current Status



**Key fields:**
- `status`: Current state (running, stopped, paused)
- `updated_at`: Last modification time

### Get Runtime Information



**Shows:**
- Active terminal sessions
- Display connections
- Running services (PIDs, ports)
- Network services
- Memory/CPU usage

### Track Operations Over Time



**Analyze:**
- Frequency of restarts (stability indicator)
- Downtime duration
- Who triggered changes
- Operation timing patterns

---

## Best Practices

### 1. Always Snapshot Before Risky Operations

```bash
# Before forcing stop or major changes
POST /api/v1/containers/{id}/snapshots
{"alias": "before-maintenance"}
```

### 2. Use Graceful Stop, Not Force-Stop

```bash
# ✅ 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
```

### 3. Verify Operations Complete

```bash
# 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');
}
```

### 4. Document Operation Triggers

```bash
# 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

**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](/vision/multiplayer/) for collaboration context.

---

## Useful Questions

### Can I start multiple containers simultaneously?

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

```javascript
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?

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?

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

### 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?

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

### 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](/vision/multiplayer/).

### 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?

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?

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

---

## Troubleshooting

### Container Won't Start

**Problem:** Start operation fails or container stuck in "creating"

**Solutions:**

1. **Check status logs:**
   ```bash
   GET /api/v1/containers/{id}/status-logs?limit=5&sort_order=desc
   
   # Look for error messages in metadata
   ```

2. **Verify server is available:**
   ```bash
   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](/foundation/containers/copy-sync/)

4. **Look for image issues:**
   ```bash
   GET /api/v1/containers/{id}
   # Check container_image is valid
   ```

### Graceful Stop Hangs

**Problem:** Stop operation doesn't complete

**Cause:** Container processes not responding to SIGTERM

**Solutions:**

1. **Retry the graceful stop:**
   ```bash
   POST /api/v1/containers/{id}/stop
   ```

2. **Force stop if necessary:**
   ```bash
   POST /api/v1/containers/{id}/force-stop
   ```

3. **Check what's running:**
   ```bash
   # SSH or terminal into container
   ps aux
   # Identify stuck processes
   ```

### Resume Fails After Pause

**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

### Operations Return 400 (Bad Request)

**Problem:** Valid operation returns 400 error

**Check operation validity:**

| Current State | Valid Operations |
|---------------|------------------|
| `running` | stop, force-stop, restart, pause |
| `stopped` | start, restart, delete |
| `paused` | resume |
| `creating` | (none - wait for completion) |
| `failed` | delete |

**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:

```bash
GET /api/v1/containers/{id}
# Verify status before operation
```

### 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:**
   ```bash
   GET /api/v1/containers/{id}?runtime=true
   
   # Verify services appear in runtime_info.services
   # Check for "active" status
   ```

3. **Verify hoody_kit is enabled:**
   ```bash
   GET /api/v1/containers/{id}
   # Check: "hoody_kit": true
   ```

4. **Check specific service:**
   ```bash
   # SSH or terminal into container
   systemctl status hoody-terminal
   systemctl status hoody-display
   # etc.
   ```

### Container Automatically Restarting

**Problem:** Container restarts unexpectedly

**Check causes:**

1. **Autostart enabled + server rebooted:**
   ```bash
   GET /api/v1/containers/{id}
   # Check: "autostart": true
   ```

2. **Check status logs for pattern:**
   ```bash
   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](/kit/notifications/)

---

## What's Next

**Master container operations:**

1. **[Snapshots →](./snapshots/)** - Capture state before operations, restore if needed
2. **[Copy & Sync →](./copy-sync/)** - Duplicate containers for redundancy
3. **[Images →](./images/)** - Choose optimal OS for your workload

**Operational topics:**
- **[Network Configuration →](/foundation/networking/network/)** - Route through proxies
- **[Firewall →](/foundation/networking/firewall/)** - Control traffic
- **[Hoody Kit Services →](/kit/)** - Use the HTTP services

**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.**

## Try It Out

Test container operations directly from your browser: