Skip to main content
tally supports configuration via TOML config files, environment variables, and CLI flags. Sources cascade in a predictable order so you can set project defaults while allowing per-run overrides.

Priority order

Configuration sources are applied highest-priority first:
  1. CLI flags--fail-level error
  2. Environment variablesTALLY_OUTPUT_FAIL_LEVEL=error
  3. Config file.tally.toml or tally.toml
  4. Built-in defaults

Config file

File names

tally looks for these config file names, in order:
  1. .tally.toml (hidden file, recommended)
  2. tally.toml

Discovery

tally uses cascading config discovery similar to Ruff:
  1. Starting from the Dockerfile’s directory, walks up the filesystem.
  2. Stops at the first .tally.toml or tally.toml found.
  3. Uses that config — no merging with parent configs.
This allows monorepo setups with per-directory configurations:
monorepo/
├── .tally.toml              # Default config for most services
├── services/
│   ├── api/
│   │   └── Dockerfile       # Uses monorepo/.tally.toml
│   └── legacy/
│       ├── .tally.toml      # Override for legacy service
│       └── Dockerfile       # Uses services/legacy/.tally.toml

Explicit config path

Override discovery with --config:
tally lint --config /path/to/.tally.toml Dockerfile

Config file reference

Controls how tally reports violations.
[output]
format = "text"           # text, json, sarif, github-actions, markdown
path = "stdout"           # stdout, stderr, or a file path
show-source = true        # Show source code snippets
fail-level = "style"      # Minimum severity for exit code 1
OptionDefaultDescription
format"text"Output format: text, json, sarif, github-actions, markdown
path"stdout"Output destination: stdout, stderr, or a file path
show-sourcetrueShow source code snippets alongside violations
fail-level"style"Minimum severity that produces exit code 1: error, warning, info, style, none

Environment variables

VariableDescription
TALLY_OUTPUT_FORMATOutput format: text, json, sarif, github-actions, markdown
TALLY_FORMATAlias for TALLY_OUTPUT_FORMAT
TALLY_OUTPUT_PATHOutput destination: stdout, stderr, or file path
TALLY_OUTPUT_SHOW_SOURCEShow source snippets: true / false
TALLY_OUTPUT_FAIL_LEVELMinimum severity for non-zero exit
NO_COLORDisable colored output (standard env var)

CLI flags

FlagDescription
--config, -cPath to config file (overrides discovery)
--excludeGlob pattern(s) to exclude files (repeatable)
--contextBuild context directory for context-aware rules
--selectEnable specific rules (repeatable)
--ignoreDisable specific rules (repeatable)

Inline directives

Suppress specific violations using inline comment directives directly in your Dockerfile.
Suppress violations on the next line:
# tally ignore=StageNameCasing
FROM alpine AS Build
Suppress multiple rules with comma-separated values:
# tally ignore=StageNameCasing,DL3006
FROM Ubuntu AS Build
Suppress all rules on a line:
# tally ignore=all
FROM Ubuntu AS Build
Suppress violations throughout the entire file:
# tally global ignore=max-lines
FROM alpine
# ... rest of file is not checked for max-lines
Document why a rule is suppressed using ;reason=:
# tally ignore=DL3006;reason=Using older base image for compatibility
FROM ubuntu:16.04

# tally global ignore=max-lines;reason=Generated file, size is expected
Use --require-reason (or require-reason = true in .tally.toml) to enforce that all ignore directives include an explanation.
tally supports directive formats from other linters, making migration easy:
# hadolint ignore=DL3006
FROM ubuntu

# hadolint global ignore=DL3008
FROM alpine

# check=skip=StageNameCasing
FROM alpine AS Build

Example configurations

Strict CI

# .tally.toml - Strict settings for CI
[output]
format = "sarif"
path = "tally-results.sarif"
fail-level = "warning"

[rules]
include = ["buildkit/*", "tally/*", "hadolint/*"]

[rules.tally.max-lines]
max = 50
skip-blank-lines = true
skip-comments = true

[inline-directives]
require-reason = true
warn-unused = true

Relaxed development

# .tally.toml - Relaxed settings for development
[output]
format = "text"
show-source = true
fail-level = "error"

[rules]
include = ["buildkit/*", "tally/*"]
exclude = ["buildkit/MaintainerDeprecated"]

[rules.tally.max-lines]
severity = "warning"
max = 200

Monorepo setup

Place a root .tally.toml with shared defaults, then override for specific services:
monorepo/
├── .tally.toml              # Shared defaults
├── services/
│   ├── api/
│   │   └── Dockerfile       # Inherits root config
│   └── legacy/
│       ├── .tally.toml      # Legacy overrides
│       └── Dockerfile
# services/legacy/.tally.toml - Gradual migration from hadolint
[output]
format = "text"
fail-level = "error"

[rules]
# Start with just BuildKit rules; add hadolint rules gradually
include = ["buildkit/*"]

[rules.buildkit.StageNameCasing]
severity = "info"  # Downgrade during migration