# How to Force Kill a Container in Apple's Open Source Framework

> Force kill a container instantly using the container kill command. Learn how to bypass graceful shutdowns and terminate processes directly via the kernel.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-28

---

**To force kill a container immediately, use the `container kill` command which sends SIGKILL by default, bypassing graceful shutdown mechanisms and terminating the process directly through the kernel.**

The Apple `container` repository provides a specialized kill subcommand that targets running containers with POSIX signals. Unlike a standard stop operation that allows cleanup time, the force kill mechanism guarantees immediate termination by transmitting SIGKILL to the container's init process. This functionality is implemented across four distinct architectural layers, from CLI parsing to low-level runtime execution inside the virtual machine.

## Basic Force Kill Commands

The simplest way to force kill a container uses the default `KILL` signal:

```bash

# Force kill a specific container by name or ID

container kill my-container

```

Because the default signal is `KILL` (SIGKILL), this command immediately terminates the container without allowing the process to catch or ignore the signal.

To kill all running containers simultaneously:

```bash

# Force kill every running container

container kill --all

```

This expands internally to target all active container IDs before dispatching individual kill requests.

## Implementation Architecture

The force kill operation flows through four specific layers in the codebase, ensuring the signal reaches the correct process inside the virtualized environment.

### CLI Layer: ContainerKill.swift

The entry point resides in [`Sources/ContainerCommands/Container/ContainerKill.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerKill.swift). This file parses command-line arguments including `--signal` and `--all`, then iterates over the target container list.

```swift
let client = ContainerClient()
for container in containers {
    try await client.kill(id: container, signal: signal)
}

```

The implementation (lines 55-73) validates the signal type and expands the `--all` flag into an array of running container identifiers before invoking the client API.

### Client Communication: ContainerClient.swift

The `ContainerClient` class in [`Sources/Services/ContainerAPIService/Client/ContainerClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/ContainerClient.swift) encodes the kill request into an XPC message. The `kill(id:signal:)` method forwards the request to the container-side API server using a gRPC-style interface.

### Server Handling: ContainersService.swift

The server implementation in [`Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift) receives the request and resolves the target's runtime client. At lines 69-100, the service executes `client.kill(processID, signal:)` after looking up the appropriate runtime connection.

When the signal equals `KILL` and the `processID` matches the container's init process ID, the server additionally triggers `handleContainerExit` to perform standard cleanup operations typically associated with a graceful stop.

### Runtime Execution: RuntimeService.swift

The final signal delivery occurs in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift). Here, the runtime service executes the actual `proc.kill(signal)` call inside the VM. When the signal is `SIGKILL` (lines 62-98), the service blocks until the VM reports the container's exit, ensuring synchronous termination confirmation.

## Advanced Usage Examples

### Specifying Alternative Signals

While the default `KILL` signal provides immediate termination, you can send other POSIX signals for different termination behaviors:

```bash

# Send SIGTERM for graceful shutdown attempt

container kill --signal TERM web-app

# Send SIGINT (equivalent to Ctrl+C)

container kill --signal INT web-app

```

### Programmatic Force Kill in Swift

For applications integrating directly with the framework:

```swift
import ContainerAPIClient

let client = ContainerClient()

// Force kill by container ID
try await client.kill(id: "my-container-id", signal: "KILL")

```

This bypasses the CLI entirely and uses the same XPC communication channel that underlies the command-line tool.

## Summary

- **`container kill`** is the primary command for force killing containers, defaulting to SIGKILL.
- The **`--all`** flag targets every running container simultaneously.
- The implementation spans four layers: CLI parsing ([`ContainerKill.swift`](https://github.com/apple/container/blob/main/ContainerKill.swift)), client messaging ([`ContainerClient.swift`](https://github.com/apple/container/blob/main/ContainerClient.swift)), server coordination ([`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift)), and runtime execution ([`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)).
- When killing the init process with SIGKILL, the system still executes cleanup routines via `handleContainerExit` to maintain state consistency.
- The runtime blocks on SIGKILL operations until the VM confirms the container has exited, providing reliable termination status.

## Frequently Asked Questions

### What is the difference between `container stop` and `container kill`?

`container stop` attempts a graceful shutdown by sending SIGTERM and allowing a timeout period for the container to exit cleanly. `container kill` sends SIGKILL immediately by default, which the kernel handles directly without allowing the process to intercept or delay termination. According to the source code, `container kill` is the only method that guarantees immediate termination when a container is unresponsive.

### Can a container process ignore the `container kill` command?

No. When using the default `KILL` signal (or explicitly specifying `SIGKILL`), the signal cannot be caught, blocked, or ignored by the target process. The kernel terminates the process immediately, making this the most reliable method for stopping stuck or zombie containers.

### Why does the force kill command block until the container exits?

In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), when the signal is `KILL`, the runtime service waits for the VM to report the container's exit before returning. This ensures the caller receives accurate status confirmation and prevents race conditions where subsequent commands might attempt to interact with a container that is still in the process of terminating.

### Does killing a container require root privileges?

The `container` framework uses XPC communication between the client and server components. While the CLI itself may not require root if the user has appropriate container permissions, the actual signal delivery at the runtime layer executes with the necessary privileges to terminate processes within the virtualized environment. The framework handles privilege escalation internally through its service architecture.