containerd / containerd/nerdctl

`nerdctl container commit` has a hardcoded 1-hour lease that causes failure for large container diffs?what about make it as flag

Open
#5,107 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
10.4k
Forks
826
Avg merge
1d 23h
Merged PRs (30d)
44

Description

## Summary

The `nerdctl container commit` command hardcodes a **1-hour lease expiration** via `leases.WithExpiration(1*time.Hour)`. When committing a container with a large filesystem delta (e.g., many packages installed), the `diff.Compare` operation can exceed 1 hour, causing the containerd GC to clean up the expired lease and its associated ingest data. This results in a `context deadline exceeded` error.

## Evidence

### 1. The hardcoded 1-hour lease in nerdctl

**File:** `pkg/imgutil/commit/commit.go:177-178`

```go
// Don't gc me and clean the dirty data after 1 hour!
ctx, done, err := client.WithLease(ctx, leases.WithRandomID(), leases.WithExpiration(1*time.Hour))
```

This `ctx` with the 1-hour lease is then passed to `createDiff()` at line 190, which calls containerd's `rootfs.CreateDiff()` → `diff.Compare()`.

### 2. The call chain

```
nerdctl container commit
→ commit.Commit() [commit.go:80]
→ client.WithLease(ctx, leases.WithExpiration(1h)) [commit.go:178] ← 1-hour lease!
→ createDiff(ctx, ...) [commit.go:190]
→ rootfs.CreateDiff(ctx, ...) [commit.go:423]
→ differ.Compare(ctx, lower, upper) [containerd rootfs/diff.go:66]
→ archive.WriteDiff(ctx, ...) [containerd walking/differ.go:151]
```

### 3. No timeout override in the CLI

**File:** `pkg/cmd/container/commit.go`

The `commitOptions()` function (line 57) does not expose any timeout or lease expiration flag. The CLI command definition has no `--timeout` flag. Users cannot increase the lease expiration.

### 4. How it fails

1. Containerd's GC periodically scans for expired leases and removes their associated resources (content store ingest data, snapshots).
2. When `diff.Compare` is still running and the 1-hour lease expires, the GC deletes the in-progress ingest data.
3. The next write to the content writer fails or the commit step fails, producing a `context deadline exceeded` error.

## Impact

- Users with containers that have large filesystem changes (e.g., installing many packages, large data writes) cannot reliably commit them.
- The 1-hour limit is not documented in the CLI help or the `nerdctl commit` documentation.
- There is no way to override this limit from the CLI.

## Proposed Fix

1. **Add a `--timeout` flag** to `nerdctl container commit` that allows users to set the lease expiration duration.
2. **Increase the default lease expiration** from 1 hour to a more reasonable value (e.g., 24 hours, matching containerd's own default in `client/lease.go`).
3. **Document** the timeout behavior and the new flag.

## Related Code Locations

| Location | Description |
|----------|-------------|
| `pkg/imgutil/commit/commit.go:177-178` | Hardcoded `leases.WithExpiration(1*time.Hour)` |
| `pkg/cmd/container/commit.go:57` | `commitOptions()` — no timeout flag |
| `pkg/api/types/container_types.go:408` | `ContainerCommitOptions` struct — no timeout field |

## Environment

- **nerdctl**: latest (main branch)
- **containerd**: any version (the diff timeout is not in containerd, it's purely in nerdctl)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.