An open API service indexing awesome lists of open source software.

https://github.com/anthony-spruyt/container-images

Container images built from upstream sources or custom Dockerfiles, with automated security scanning, release management, and SLSA provenance
https://github.com/anthony-spruyt/container-images

chrony container container-image containers docker docker-container docker-image docker-images llm-guard llm-guardrail llm-guardrails megalinter

Last synced: 11 days ago
JSON representation

Container images built from upstream sources or custom Dockerfiles, with automated security scanning, release management, and SLSA provenance

Awesome Lists containing this project

README

          

# Container Images

[![License](https://img.shields.io/github/license/anthony-spruyt/container-images)](https://github.com/anthony-spruyt/container-images/blob/main/LICENSE) [![CI](https://github.com/anthony-spruyt/container-images/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/anthony-spruyt/container-images/actions/workflows/ci.yaml)
[![Trivy Scan](https://github.com/anthony-spruyt/container-images/actions/workflows/trivy-scan.yaml/badge.svg?branch=main)](https://github.com/anthony-spruyt/container-images/actions/workflows/trivy-scan.yaml) [![Stars](https://img.shields.io/github/stars/anthony-spruyt/container-images)](https://github.com/anthony-spruyt/container-images/stargazers)
[![Forks](https://img.shields.io/github/forks/anthony-spruyt/container-images)](https://github.com/anthony-spruyt/container-images/forks) [![Contributors](https://img.shields.io/github/contributors/anthony-spruyt/container-images)](https://github.com/anthony-spruyt/container-images/graphs/contributors)
[![Issues](https://img.shields.io/github/issues/anthony-spruyt/container-images)](https://github.com/anthony-spruyt/container-images/issues)

Container images built from upstream sources or custom Dockerfiles, published to GitHub Container Registry with automated security scanning and SLSA provenance.

## Development

See [DEVELOPMENT.md](DEVELOPMENT.md) for development environment setup.

## Usage

Pull an image:

```bash
docker pull ghcr.io/anthony-spruyt/chrony:latest
```

## Adding a New Image

### Option 1: Build from Upstream Source

Use this when building from an external repository (e.g., a GitHub project):

1. Create a directory with the image name

2. Add `metadata.yaml`:

```yaml
upstream: owner/repo
version: "1.0.0"
```

3. Optionally add a custom `Dockerfile` to override the upstream's

4. Push to main - the image will be built and published automatically

### Option 2: Build from Local Dockerfile

Use this for custom images with no upstream source:

1. Create a directory with the image name

2. Add your `Dockerfile` and any required files

3. Add `metadata.yaml`:

```yaml
version: "1.0.0"
```

4. Push to main - the image will be built and published automatically

### Option 3: Auto-Patched Version

For images where CI should auto-increment the patch version on each build, specify only the base version and set `auto_patch: true`:

```yaml
version: "1.1"
auto_patch: true
```

CI appends `.N` automatically (e.g., `1.1.0`, `1.1.1`, `1.1.2`). Do **not** include the patch segment in `version` — writing `"1.1.0"` with `auto_patch: true` would produce `1.1.0.0`.

### Automatic Configuration

- **Upstream validation** - Uses each image's own `metadata.yaml` as source of truth
- **Renovate tracking** - Add `# renovate:` annotations to `metadata.yaml` for automatic version updates

## Adding a Custom MegaLinter Flavor

Custom MegaLinter flavors extend official flavors with additional linters. The `megalinter-factory/` directory contains tooling to generate flavor files from a simple configuration.

### Using Claude Code (Recommended)

The `/create-megalinter-flavor` command automates flavor creation with automatic base flavor selection:

```bash
# With specific linters
/create-megalinter-flavor my-ci ACTION_ACTIONLINT,MARKDOWN_MARKDOWNLINT,BASH_SHELLCHECK

# Interactive mode (prompts for linter selection)
/create-megalinter-flavor my-ci
```

The command will:

1. Validate the flavor name and check for conflicts
2. Look up linter configurations from the catalog
3. Auto-select the optimal base flavor (minimizing custom installs)
4. Generate `megalinter-/flavor.yaml` with Renovate annotations

### Manual Setup

1. Create a directory for your flavor:

```bash
mkdir megalinter-/
```

2. Create `flavor.yaml` with your configuration:

```yaml
name: my-flavor
description: "MegaLinter for my use case"

# renovate: datasource=docker depName=oxsecurity/megalinter-ci_light
upstream_image: "oxsecurity/megalinter-ci_light:v9.3.0@sha256:..."

custom_linters:
- ACTION_ACTIONLINT
- MARKDOWN_MARKDOWNLINT
- PYTHON_BANDIT
```

3. Commit `flavor.yaml` - CI generates Dockerfile, test.sh, and metadata.yaml, then builds automatically

### Available Linters

Linter information is extracted directly from MegaLinter's descriptors at build time. The generator automatically fetches the latest versions from .

### Version Updates

Linter versions are automatically extracted from MegaLinter at build time - no manual tracking needed. The weekly scheduled rebuild workflow picks up any new linter versions.

For the base image, Renovate tracks the upstream MegaLinter version:

```yaml
# renovate: datasource=docker depName=oxsecurity/megalinter-ci_light
upstream_image: "oxsecurity/megalinter-ci_light:v9.3.0@sha256:..."
```

When Renovate creates a PR updating `flavor.yaml`, CI regenerates the Dockerfile and builds.

### Local Development

To test locally, generate files first:

```bash
pip install pyyaml jinja2
python megalinter-factory/generate.py megalinter-/
```

Generated files (`Dockerfile`, `test.sh`) are regenerated by CI at build time.

## Build Triggers

### Automatic

Pushing changes to `metadata.yaml`, `Dockerfile`, `flavor.yaml`, or `assets/` on main triggers a build using the version in metadata. Changes to `megalinter-factory/` trigger rebuilds of all flavors.

### Manual / n8n Integration

Trigger via GitHub API (workflow_dispatch):

```bash
# Dry run (default) - builds and scans but doesn't push or release
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/anthony-spruyt/container-images/actions/workflows/ci.yaml/dispatches \
-d '{"ref":"main","inputs":{"image":"chrony","version":"4.6.1"}}'

# Production build - pushes to GHCR and creates release
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/anthony-spruyt/container-images/actions/workflows/ci.yaml/dispatches \
-d '{"ref":"main","inputs":{"image":"chrony","version":"4.6.1","dry_run":"false"}}'
```

Parameters:

- **image** (required): Image directory name (e.g., `chrony`, `ssh-key-rotation`)
- **version** (optional): Semver tag to build (e.g., `4.6.1`) - checks out this tag from upstream
- **dry_run** (optional, default: `true`): When `true`, builds and scans the image but skips push to GHCR and release creation. Set to `false` for production builds.

## Automatic Version Updates

### Renovate (Recommended)

Add a Renovate annotation to `metadata.yaml` for automatic version tracking:

```yaml
upstream: owner/repo
# renovate: datasource=github-tags depName=owner/repo
version: "1.0.0"
```

Supported datasources:

- `github-tags` - GitHub repository tags
- `github-releases` - GitHub releases
- `docker` - Docker Hub or container registries

When Renovate detects a new version, it creates a PR. Merging triggers the build automatically.

### n8n Workflow (Special Cases)

For upstream sources Renovate cannot monitor (e.g., Alpine packages), use n8n workflows. See `chrony/n8n-release-watcher.json` for an example that monitors Alpine package versions and triggers builds via workflow_dispatch

## Security

See [SECURITY.md](SECURITY.md) for security policy and controls.