Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4586373
build(nix): add modular flake.nix + ./nix static-analysis harness
randomizedcoder Jul 11, 2026
ca310e7
ci(nix): run `nix flake check` on PRs + declare Blacksmith runner labels
randomizedcoder Jul 11, 2026
f23e48e
fix(nix): actionlint needs a git root in the sandbox; allowlist gitle…
randomizedcoder Jul 11, 2026
fb5e047
fix(nix): align gated hadolint with the repo's existing ignore rules
randomizedcoder Jul 11, 2026
65e5c58
style: fix pre-existing yaml + markdown lint findings
randomizedcoder Jul 11, 2026
3b2bfb2
feat(nix): experimental build-only Nix container image + size comparison
randomizedcoder Jul 11, 2026
0fec212
feat(nix): hybrid CUDA image PoC + cross-image layer-sharing notes
randomizedcoder Jul 11, 2026
2f4ce3b
feat(nix): shared-userland image family + layer-sharing footprint metric
randomizedcoder Jul 12, 2026
a601f6f
fix(nix): realize family closures before footprint measurement
randomizedcoder Jul 12, 2026
4d16880
feat(nix): fleet-wide layer-sharing footprint across all container types
randomizedcoder Jul 12, 2026
2f83408
fix(nix): measure REAL OCI layer sharing, not Nix store-path closure
randomizedcoder Jul 12, 2026
9309d69
feat(nix): nix2container image targets + head-to-head OCI sharing com…
randomizedcoder Jul 12, 2026
1eee3e2
feat(nix): explicit-tiering image family (nix2container buildLayer)
randomizedcoder Jul 12, 2026
132e29f
feat(nix): native-parity prod image tree (base + pytorch) from nixpkgs
randomizedcoder Jul 12, 2026
6298378
docs(nix): record prod-base-cuda size (full-nix CUDA ~42% smaller tha…
randomizedcoder Jul 12, 2026
7269325
feat(nix): complete prod-pytorch CUDA image (source-built torch)
randomizedcoder Jul 13, 2026
0108621
docs(nix): fix MD004 in prod-images README (wrapped-line + marker)
randomizedcoder Jul 13, 2026
3a76f31
feat(nix): add prod-base-cpu-lean + bump nixpkgs to latest unstable
randomizedcoder Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
9 changes: 9 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Custom self-hosted runner labels used across this repo's workflows
# (Blacksmith runners). Declaring them here stops actionlint from
# reporting "unknown runner label" for runs-on: blacksmith-*.
self-hosted-runner:
labels:
- blacksmith-16vcpu-ubuntu-2204
- blacksmith-4vcpu-ubuntu-2204
- blacksmith-16vcpu-ubuntu-2404
- blacksmith-4vcpu-ubuntu-2404
2 changes: 1 addition & 1 deletion .github/actions/docker-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ runs:
BRANCH_NAME=$(echo "${RAW_BRANCH}" | sed 's/\//-/g')
SUFFIX="-dev-${BRANCH_NAME}"
echo "RELEASE=${SUFFIX}" >> $GITHUB_ENV
echo "release_suffix=${SUFFIX}" >> $GITHUB_OUTPUT
echo "release_suffix=${SUFFIX}" >> $GITHUB_OUTPUT
2 changes: 1 addition & 1 deletion .github/actions/hadolint/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ runs:
failure-threshold: ${{ inputs.failure-threshold }}
ignore: ${{ inputs.ignore }}
format: ${{ inputs.format }}
output-file: ${{ inputs.output-file }}
output-file: ${{ inputs.output-file }}
79 changes: 39 additions & 40 deletions .github/actions/update-readme/action.yml
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
name: "Update Template README"
description: "Updates a Runpod template README via the API"
inputs:
template_id:
description: "Runpod Template ID"
required: true
template_path:
description: "Path to the template directory"
required: true

runs:
using: "composite"
steps:
- name: Check if README exists
id: check_readme
shell: bash
env:
TEMPLATE_PATH: ${{ inputs.template_path }}
run: |
if [[ -f "${TEMPLATE_PATH}/README.md" ]]; then
echo "skip=false" >> "$GITHUB_OUTPUT"
else
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "README.md not found at ${TEMPLATE_PATH}/README.md, skipping update"
fi

- name: Make script executable
if: steps.check_readme.outputs.skip != 'true'
shell: bash
run: chmod +x "${GITHUB_WORKSPACE}/scripts/update-template-readme.sh"

- name: Update template README
if: steps.check_readme.outputs.skip != 'true'
shell: bash
env:
TEMPLATE_ID: ${{ inputs.template_id }}
TEMPLATE_PATH: ${{ inputs.template_path }}
run: |
"${GITHUB_WORKSPACE}/scripts/update-template-readme.sh" "${TEMPLATE_ID}" "${TEMPLATE_PATH}"

name: "Update Template README"
description: "Updates a Runpod template README via the API"
inputs:
template_id:
description: "Runpod Template ID"
required: true
template_path:
description: "Path to the template directory"
required: true

runs:
using: "composite"
steps:
- name: Check if README exists
id: check_readme
shell: bash
env:
TEMPLATE_PATH: ${{ inputs.template_path }}
run: |
if [[ -f "${TEMPLATE_PATH}/README.md" ]]; then
echo "skip=false" >> "$GITHUB_OUTPUT"
else
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "README.md not found at ${TEMPLATE_PATH}/README.md, skipping update"
fi

- name: Make script executable
if: steps.check_readme.outputs.skip != 'true'
shell: bash
run: chmod +x "${GITHUB_WORKSPACE}/scripts/update-template-readme.sh"

- name: Update template README
if: steps.check_readme.outputs.skip != 'true'
shell: bash
env:
TEMPLATE_ID: ${{ inputs.template_id }}
TEMPLATE_PATH: ${{ inputs.template_path }}
run: |
"${GITHUB_WORKSPACE}/scripts/update-template-readme.sh" "${TEMPLATE_ID}" "${TEMPLATE_PATH}"
8 changes: 4 additions & 4 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ version: 2
updates:

# Enable version updates for github-actions
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

# Enable version updates for Docker
# Enable version updates for Docker
- package-ecosystem: "docker"
directory: "/"
directory: "/"
schedule:
interval: "daily"
2 changes: 1 addition & 1 deletion .github/workflows/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ jobs:
with:
image-refs: ${{ steps.refs.outputs.refs }}
ref-digests: ${{ steps.refs.outputs.ref-digests }}

- name: Install Cosign
if: github.event_name == 'workflow_dispatch' || steps.changes.outputs.pytorch_any_changed == 'true'
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/hadolint-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,3 @@ jobs:
format: tty
output-file: /dev/stdout
ignore: ${{ matrix.ignore }}

3 changes: 1 addition & 2 deletions .github/workflows/hadolint-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ jobs:
format: sarif
output-file: hadolint.sarif
ignore: ${{ matrix.ignore }}

- name: Upload Hadolint SARIF to Code Scanning
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e
with:
sarif_file: hadolint.sarif
category: hadolint-${{ strategy.job-index }}

120 changes: 120 additions & 0 deletions .github/workflows/nix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Nix static analysis

on:
push:
branches: [main]
pull_request:
workflow_dispatch:
inputs:
heavy:
description: "Which heavy build-only job(s) to run"
type: choice
default: all
options: [none, cuda, fleet, all]

permissions:
contents: read

jobs:
flake-check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
extra-conf: |
experimental-features = nix-command flakes

# Runs the sandbox-safe gated checks (nixfmt/statix/deadnix/nil,
# shellcheck, yamllint, actionlint, hadolint, markdown, taplo,
# editorconfig, gitleaks). --keep-going so every check's findings
# surface in one run instead of stopping at the first failure.
- name: nix flake check
run: nix flake check --print-build-logs --keep-going

# Experimental: build the base-cpu image with Nix and compare its size to the
# published runpod/base CPU image. Build-only — nothing is pushed. Kept in a
# separate job so it never slows the gated flake-check above.
image-size:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
extra-conf: |
experimental-features = nix-command flakes

- name: Build Nix base-cpu image + size comparison (build-only)
run: bash nix/images/compare-size.sh

# Cross-image layer-sharing footprint for the Nix image family: bytes a host
# caches once shared layers dedupe, vs the naïve per-image sum. Build-only.
family-footprint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
extra-conf: |
experimental-features = nix-command flakes

- name: Image-family layer-sharing footprint
run: bash nix/images/footprint.sh

# Experimental hybrid CUDA image (nvidia base + Nix userland). Heavy: pulls a
# ~5.6 GB CUDA base and streams ~11 GB, so it is manual-dispatch only — it
# does NOT run on every push. Trigger with:
# gh workflow run "Nix static analysis" --ref <branch>
cuda-image-size:
if: github.event_name == 'workflow_dispatch' && (inputs.heavy == 'cuda' || inputs.heavy == 'all')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Free disk space
run: |
sudo rm -rf /opt/hostedtoolcache /usr/local/lib/android /usr/share/dotnet /usr/local/.ghcup
df -h /

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
extra-conf: |
experimental-features = nix-command flakes

- name: Build hybrid CUDA image + size comparison (build-only)
run: bash nix/images/compare-cuda-size.sh

# Fleet-wide layer-sharing footprint of the published images across all
# container types (skopeo manifests only, no pulls). Manual-dispatch: ~38
# images = many Docker Hub manifest requests, so authenticate + don't run on
# every push. Trigger with:
# gh workflow run "Nix static analysis" --ref <branch> -f heavy=fleet
fleet-footprint:
if: github.event_name == 'workflow_dispatch' && (inputs.heavy == 'fleet' || inputs.heavy == 'all')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25
with:
extra-conf: |
experimental-features = nix-command flakes

- name: Published-fleet layer-sharing footprint
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
run: bash nix/images/fleet-footprint.sh
4 changes: 2 additions & 2 deletions .github/workflows/rocm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
fetch-depth: 0

- name: Setup Docker
uses: ./.github/actions/docker-setup
id: setup
Expand Down Expand Up @@ -99,7 +99,7 @@ jobs:
path: /tmp/rocm-refs/refs.json
retention-days: 1
if-no-files-found: error

test-rocm:
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: build-rocm
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sonarqube.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ jobs:
pollingTimeoutSec: 300
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: https://sonarcloud.io
SONAR_HOST_URL: https://sonarcloud.io
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
*.safetensors
*.pth

__pycache__/
__pycache__/

# Nix
result
result-*
.direnv/
21 changes: 21 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
title = "runpod/containers gitleaks config"

# Start from gitleaks' built-in rule set, then add repo-specific allowlists.
[extend]
useDefault = true

# The smoke-test composite action greps a user-supplied SSH key for PEM header
# lines to validate its shape. The "-----BEGIN ... PRIVATE KEY-----" strings are
# literals in a case statement, not committed secrets. Scope the allowlist to
# that file AND the PEM-header pattern (matchCondition = AND) so a genuine key
# committed elsewhere still trips the scanner.
[[allowlists]]
description = "PEM header literals in the smoke-test SSH key validator"
matchCondition = "AND"
paths = [
'''\.github/actions/smoke-test/action\.yml''',
]
regexTarget = "line"
regexes = [
'''BEGIN (OPENSSH |RSA |EC )?PRIVATE KEY''',
]
14 changes: 14 additions & 0 deletions .hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Align the Nix gated hadolint check with the ignore rules the repo's own
# hadolint workflow (.github/workflows/hadolint-*.yml) already applies
# per-Dockerfile, so the two agree on policy:
# DL3006 — always tag image version
# DL3008 — pin apt package versions
# DL3013 — pin pip package versions
# DL3022 — COPY --from references a prior FROM alias
# DL3042 — pip --no-cache-dir
ignored:
- DL3006
- DL3008
- DL3013
- DL3022
- DL3042
9 changes: 9 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Pragmatic markdownlint config. Keep structural rules; disable the
# stylistic ones that commonly fire on READMEs.
default: true
# Line length — prose and tables routinely exceed a fixed width.
MD013: false
# Allow inline HTML (badges, <details>, etc.).
MD033: false
# Do not require the first line to be a top-level heading.
MD041: false
15 changes: 15 additions & 0 deletions .yamllint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Pragmatic yamllint config. Extends the default rules but relaxes the
# ones that fight normal GitHub Actions / Docker-compose style YAML.
extends: default

rules:
# GitHub Actions workflows use `on:` which yamllint's default flags as
# a truthy value; and long lines are common in run: blocks.
line-length: disable
truthy:
allowed-values: ["true", "false"]
check-keys: false
comments:
min-spaces-from-content: 1
comments-indentation: disable
document-start: disable
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This repository uses Docker Buildx with [bake files](https://docs.docker.com/bui

### Using the Bake Script

`./bake.sh` automatically combines shared version definitions with template specific bake files.
`./bake.sh` automatically combines shared version definitions with template specific bake files.

Use it like this:

Expand Down
Loading
Loading