Skip to content

Lint Rules

Rules run in two phases:

  • Pre-synth (chant lint) — static analysis on TypeScript source
  • Post-synth (chant build) — checks on the generated docker-compose.yml / Dockerfile.*

Severity: warning | Category: reproducibility

Warns when a Service.image prop is a literal string ending in :latest or has no tag. Applies to source-level string literals; env() values are skipped.

// ✗ triggers DKRS001
export const api = new Service({ image: "myapp" });
export const api = new Service({ image: "myapp:latest" });
// ✓ ok
export const api = new Service({ image: "myapp:1.0" });
export const api = new Service({ image: env("APP_IMAGE") });

Post-synth checks run after build and inspect the serialized output.

Severity: warning

Same as DKRS001 but catches cases the pre-synth rule misses (e.g. dynamic values that resolve to :latest at build time).

Severity: warning

A Volume entity is declared but not mounted by any service.

export const orphan = new Volume({}); // ✗ never mounted

Severity: error

A service exposes port 22 externally. SSH should not be accessible from the host.

export const svc = new Service({ ports: ["22:22"] }); // ✗

DKRD010 — apt-get without —no-install-recommends

Section titled “DKRD010 — apt-get without —no-install-recommends”

Severity: warning | Applies to: Dockerfiles

apt-get install without --no-install-recommends installs unnecessary packages and bloats image size.

# ✗
RUN apt-get install -y curl
# ✓
RUN apt-get install -y --no-install-recommends curl

Severity: info | Applies to: Dockerfiles

ADD has implicit behaviours (URL fetching, tar extraction). Use COPY for plain file copies; use ADD only when its extra features are intentionally needed.

Severity: warning | Applies to: Dockerfiles

A Dockerfile has no USER instruction, meaning the container runs as root. Set an unprivileged user.

export const app = new Dockerfile({
from: "node:20-alpine",
user: "node", // ✓
cmd: `["node", "index.js"]`,
});