Skip to content

feat(backend/docker): add per-step resource limits and OOM score adjustment#6735

Open
bclermont wants to merge 2 commits into
woodpecker-ci:mainfrom
bclermont:feat/docker-per-step-resource-limits
Open

feat(backend/docker): add per-step resource limits and OOM score adjustment#6735
bclermont wants to merge 2 commits into
woodpecker-ci:mainfrom
bclermont:feat/docker-per-step-resource-limits

Conversation

@bclermont

Copy link
Copy Markdown
Contributor

Summary

Add support for per-step memory, CPU limits and OOM score adjustment in the Docker backend via backend_options in workflow YAML.

Motivation

The Docker backend currently only supports global resource limits via agent environment variables (WOODPECKER_BACKEND_DOCKER_LIMIT_MEM, etc.). There is no way to cap individual heavy steps without affecting all steps globally. This leads to OOM situations where the host server freezes because no step-level ceiling exists.

Changes

  • Extended BackendOptions struct with resources.limits.{memory,cpus} and oom_score_adj
  • toHostConfig now accepts BackendOptions and merges per-step limits over global agent limits
  • Added parseMemory helper supporting k/m/g suffixes
  • oom_score_adj restricted to [0, 1000] by design — steps can only be made more killable, never protected from the OOM killer
  • JSON schema updated so the linter validates backend_options.docker
  • Documentation updated with YAML example and option reference table
  • All existing tests pass; new tests added for validation, parsing, and toHostConfig merge logic

Usage

steps:
  heavy-build:
    image: golang:1.22
    commands:
      - go build ./...
    backend_options:
      docker:
        resources:
          limits:
            memory: 1g
            cpus: 1.5
        oom_score_adj: 500
Option Type Description
resources.limits.memory string Max memory (e.g. 512m, 1g). Overrides WOODPECKER_BACKEND_DOCKER_LIMIT_MEM.
resources.limits.cpus float Max CPU cores (e.g. 0.5, 1.5). Converted to NanoCPUs.
oom_score_adj int (0–1000) OOM killer priority. 0 = default, 1000 = kill first. Negative values rejected by design.

…stment

Add support for per-step memory, CPU limits and OOM score adjustment
in the Docker backend via backend_options in workflow YAML:

  steps:
    build:
      image: golang:1.22
      backend_options:
        docker:
          resources:
            limits:
              memory: 1g
              cpus: 1.5
          oom_score_adj: 500

- Memory accepts human-readable strings (512m, 1g) and overrides the
  global WOODPECKER_BACKEND_DOCKER_LIMIT_MEM when set
- CPUs (float) converted to Docker NanoCPUs
- oom_score_adj restricted to [0, 1000] by design — steps can only be
  made more likely to be OOM-killed, never protected
- Per-step limits override agent-level global limits when set
- JSON schema updated for linter support
- Documentation updated with examples and option reference table
if err != nil {
return nil, err
}
memLimit = parsed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need checks, golbal conf should be able to be limited but not widen

this allows to overwrite conf.resourceLimit.MemLimit to have a greater limit!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@6543 should I just change it to never go beyond WOODPECKER_BACKEND_DOCKER_LIMIT_MEM ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

@6543 6543 added enhancement improve existing features backend/docker labels Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/docker enhancement improve existing features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants