Container Stop vs Container Kill: Understanding Graceful and Immediate Termination
The difference between container stop and container kill is that stop initiates a graceful shutdown by sending a configurable stop signal (SIGTERM by default) and waiting for a user-specified timeout before escalating to SIGKILL, while kill sends SIGKILL immediately without allowing the container to clean up resources.
In the apple/container repository, managing container lifecycle requires understanding how different termination commands affect running processes. Whether you're flushing logs or forcing a stuck container to exit, knowing when to use container stop versus container kill ensures you maintain data integrity and system stability.
How container stop Implements Graceful Termination
Signal Handling and Timeout Mechanics
The container stop command is designed for graceful shutdowns. According to docs/command-reference.md, it sends a configurable stop signal (defaulting to SIGTERM) and waits for a specified duration before forcefully terminating the container. After the user-defined timeout expires, the command escalates to SIGKILL if the container is still running.
This approach allows the container's init process to catch the signal, clean up resources, flush logs, and exit cleanly. Because the container can run cleanup code, dependent resources such as mounted volumes are usually left in a consistent state.
Implementation in Source Code
In Tests/CLITests/Subcommands/Containers/TestCLIStop.swift, the test suite verifies that containers reach the stopped state and that the stop signal can be omitted, resulting in inspect.configuration.stopSignal == nil. This confirms the default SIGTERM behavior when no custom signal is configured. The tests also validate that the --time parameter correctly controls the wait duration before forceful termination.
How container kill Executes Immediate Termination
Direct SIGKILL Execution
Unlike the graceful approach of stop, the container kill command sends SIGKILL directly to the container process. This immediate termination prevents the container's init process from catching the signal or running cleanup code, which may leave temporary files or incomplete operations. While you can specify an alternative signal using the --signal flag, the command executes immediately without any grace period or timeout mechanism.
Machine State Updates
The machine-level tests in Tests/CLITests/Subcommands/Machine/TestCLIMachine.swift (lines 1120-1123) demonstrate that killing the backing container updates the machine's state to stopped without a graceful shutdown phase. This validates the immediate nature of the kill command as implemented in Sources/Services/MachineAPIService/Server/MachinesService.swift, where handling covers scenarios where a backing container "stops (e.g., VM crash, kill, etc.)".
Key Differences Between Container Stop and Container Kill
| Aspect | container stop |
container kill |
|---|---|---|
| Default signal | SIGTERM (configurable) | SIGKILL (configurable via --signal) |
| Graceful shutdown | Yes – allows cleanup and resource flushing | No – immediate termination |
| Timeout control | --time or -t option specifies wait duration |
No timeout; immediate execution |
| Resource consistency | Leaves volumes in consistent state | May leave volumes in intermediate state |
| Use case | Normal shutdowns, service maintenance | Emergency termination of stuck containers |
Practical Usage Examples
# Graceful stop with default 10-second timeout
container stop my-container
# Graceful stop with custom 5-second timeout
container stop --time 5 my-container
# Immediate kill (SIGKILL)
container kill my-container
# Kill with alternative signal
container kill --signal SIGINT my-container
Typical Workflow
# Attempt graceful shutdown first
container stop my-container
# If container refuses to stop, force termination
container kill my-container
When to Use Each Command
Use container stop when you need to ensure the container's init process can catch the signal and clean up resources. This is essential when persisting state or shutting down services where data integrity matters. As noted in Sources/ContainerResource/Container/ContainerCreateOptions.swift, containers can be configured with removal on stop (--rm), making graceful shutdowns critical for proper cleanup.
Use container kill when a container refuses to stop gracefully or when you need an immediate break. This is useful for forcing stuck containers to terminate, though be aware that immediate termination can leave dependent resources in an inconsistent state.
Summary
container stopsends a configurable stop signal (default SIGTERM) and waits for a user-defined timeout before escalating to SIGKILL, enabling graceful shutdowns with proper resource cleanup.container killsends SIGKILL immediately (or an alternative specified signal) without timeout or cleanup opportunities, terminating the container forcibly.- The
--timeflag only works withstop, notkill, providing control over the grace period. - Source code in
TestCLIStop.swiftandTestCLIMachine.swiftconfirms these behavioral differences in the apple/container implementation. - Always prefer
stopfor normal operations to ensure data consistency; reservekillfor emergency scenarios.
Frequently Asked Questions
What signal does container stop send by default?
By default, container stop sends SIGTERM to the container's init process. This default is configurable, and if omitted, results in inspect.configuration.stopSignal == nil as verified in Tests/CLITests/Subcommands/Containers/TestCLIStop.swift. After the timeout period expires, it escalates to SIGKILL.
How does the --time flag affect container stop?
The --time (or -t) flag specifies how long the command waits after sending the initial stop signal before forcibly killing the container with SIGKILL. This timeout is only available with container stop; container kill executes immediately without any waiting period.
Can container kill send signals other than SIGKILL?
While container kill defaults to SIGKILL for immediate termination, the command accepts a --signal flag allowing you to specify alternative signals such as SIGINT. However, unlike stop, it does not implement a timeout or grace period mechanism, regardless of which signal you specify.
Why should I avoid container kill for routine shutdowns?
You should avoid container kill for routine shutdowns because it terminates the process immediately without allowing the container to run cleanup code. This can leave temporary files, incomplete operations, and dependent resources like mounted volumes in an inconsistent state, whereas container stop ensures proper resource cleanup according to the implementation in Sources/ContainerResource/Container/ContainerCreateOptions.swift.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →