Skip to content

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

Description

@Turbo-Jiaxxx789

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

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions