{"id":29272752,"url":"https://github.com/taihen/base-image","last_synced_at":"2026-05-23T09:01:56.452Z","repository":{"id":298000261,"uuid":"998428725","full_name":"taihen/base-image","owner":"taihen","description":"Minimal Distroless Container Base Image based on Wolfi","archived":false,"fork":false,"pushed_at":"2026-04-28T11:01:18.000Z","size":1381,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-28T12:33:35.944Z","etag":null,"topics":["apko","container","container-image","docker","docker-image","glibc","wolfi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taihen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-08T15:36:49.000Z","updated_at":"2026-04-28T10:57:46.000Z","dependencies_parsed_at":"2025-07-03T17:29:49.675Z","dependency_job_id":"ba29b5dd-566c-42a0-ad19-a24d978f3526","html_url":"https://github.com/taihen/base-image","commit_stats":null,"previous_names":["taihen/base-image"],"tags_count":137,"template":false,"template_full_name":null,"purl":"pkg:github/taihen/base-image","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taihen%2Fbase-image","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taihen%2Fbase-image/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taihen%2Fbase-image/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taihen%2Fbase-image/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taihen","download_url":"https://codeload.github.com/taihen/base-image/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taihen%2Fbase-image/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33389229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apko","container","container-image","docker","docker-image","glibc","wolfi"],"created_at":"2025-07-05T01:10:27.410Z","updated_at":"2026-05-23T09:01:56.430Z","avatar_url":"https://github.com/taihen.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Distroless Base Images\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"docs/logo.png\" alt=\"Base Image Logo\" width=\"300\"\u003e\n\u003c/div\u003e\n\nThis repository builds, updates, and secures multi-arch (currently only `x86_64` and `arm64`) **distroless Docker base images**. Three variants are published to GitHub Container Registry (GHCR) at `ghcr.io/taihen/base-image`:\n\n- **Base image** (`:latest`) - Minimal distroless image with musl libc\n- **glibc image** (`:glibc`) - Includes GNU libc for better compatibility  \n- **Debug image** (`:debug`) - Development variant with shell and debugging tools\n\nAll images are available with both convenience tags and version tags (e.g., `v2025.06.13`) for reproducible builds.\n\nThis project has been configured to use the Chainguard `apko` toolchain, which is the best-in-class method for building minimal, secure, and reproducible container images.\n\nCurious about distroless, checkout my [blog post](https://taihen.org/posts/distroless/).\n\n## Why You Need a Secure and Simple Base Image\n\nModern containerized applications face increasing security threats and compliance requirements. Traditional base images often include unnecessary packages, tools, and potential vulnerabilities that expand your attack surface. A secure and simple base image is essential because:\n\n- **Reduced Attack Surface**: By including only the bare minimum required to run your application (glibc and ca-certificates), there are fewer components that could contain vulnerabilities\n- **Compliance**: Many security standards and regulations require minimizing unnecessary software in production environments\n- **Smaller Images**: Minimal images mean faster pulls, reduced storage costs, and quicker deployments\n- **No Shell or Package Manager**: Without these tools, attackers have fewer options if they manage to breach your container\n- **Immutable Infrastructure**: Distroless images encourage building immutable containers where everything is defined at build time\n- **Supply Chain Security**: Using a well-maintained base image with automated security updates helps protect against supply chain attacks\n\n## Build Process\n\nInstead of `Dockerfile`s, this project uses declarative `apko` YAML files to define the image contents:\n\n- **[`base.yaml`](./base.yaml)** - Base distroless image with minimal packages (ca-certificates, tzdata, wolfi-baselayout)\n- **[`glibc.yaml`](./glibc.yaml)** - Extends base.yaml and adds the `glibc` package for compatibility\n- **[`debug.yaml`](./debug.yaml)** - Extends glibc.yaml and adds debugging tools (`wolfi-base` with busybox and apk)\n\nEach configuration specifies:\n- The minimal set of packages required from the [Wolfi](https://github.com/wolfi-dev) repository\n- A non-root user (`65532:65532`) for secure execution (except debug which runs as root)\n- The target architectures (`linux/amd64`, `linux/arm64`)\n\nThis declarative approach, inspired by Google Distroless and perfected by Chainguard, ensures the resulting image contains only what is explicitly defined, drastically reducing the attack surface.\n\n## Features\n\n- **Declarative \u0026 Reproducible:** The `apko.yaml` file provides a clear, auditable, and reproducible definition of the image.\n- **Multi-Arch:** Natively builds and pushes a multi-arch manifest for `linux/amd64` and `linux/arm64`.\n- **Minimal \u0026 Secure:**\n  - Built from trusted, minimal [Wolfi](https://github.com/wolfi-dev) packages.\n  - Contains no shell, package manager, or other unnecessary components.\n  - Runs as a non-root user (`65532:65532`).\n  - Automatically rebuilt daily to incorporate the latest security patches from upstream packages.\n  - Images are signed with Cosign using keyless signing.\n  - A high-quality SBOM (Software Bill of Materials) is generated natively by `apko` during the build.\n- **CI/CD:** A streamlined GitHub Actions workflow using [`wolfi-act`](https://github.com/wolfi-dev/wolfi-act) handles the entire build, publish, and sign process in a single, efficient step.\n\n## Image Variants\n\nThis repository provides three distinct image variants to meet different use cases:\n\n### Base Image (`:latest`)\nThe default minimal distroless image with musl libc. This is the most minimal option suitable for statically-linked binaries or applications that don't require glibc.\n\n### glibc Image (`:glibc`)\nExtends the base image with GNU libc for maximum compatibility with dynamically-linked applications that expect glibc. Recommended for most applications requiring C library compatibility.\n\n### Debug Image (`:debug`)\nWhile the production images are designed for production use without a shell or debugging tools, sometimes you need these capabilities during development or troubleshooting. The debug variant provides these tools.\n\n### Debug Image Configuration\n\nThe debug image is defined in [`debug.yaml`](./debug.yaml) and extends the base configuration with:\n\n- **`wolfi-base` package**: Adds busybox (providing common Unix utilities) and apk-tools (package manager)\n- **Root user**: Runs as root instead of the non-root user (65532:65532)\n- **Shell entrypoint**: Sets `/bin/sh -l` as the default entrypoint\n\n### When to Use the Debug Image\n\n⚠️ **Warning**: The debug image should **NEVER** be used in production as it significantly increases the attack surface by including a shell and running as root.\n\nUse cases for the debug image:\n\n- Local development and testing\n- Debugging application issues in non-production environments\n- Exploring the container filesystem\n- Installing additional packages for testing\n- Troubleshooting permission or dependency issues\n\n### Available Image Tags\n\n**Base Production Image (musl libc):**\n- `ghcr.io/taihen/base-image:latest` - Latest base image build\n- `ghcr.io/taihen/base-image:v2025.06.13` - Specific version tag\n\n**glibc Production Image (GNU libc):**\n- `ghcr.io/taihen/base-image:glibc` - Latest glibc image build  \n- `ghcr.io/taihen/base-image:v2025.06.13-glibc` - Specific version glibc tag\n\n**Debug Development Image:**\n- `ghcr.io/taihen/base-image:debug` - Latest debug build\n- `ghcr.io/taihen/base-image:v2025.06.13-debug` - Specific version debug tag\n\n### Building Images Locally\n\nTo build any variant using apko:\n\n```sh\n# Build base image (musl libc)\ndocker run -v $PWD:/work cgr.dev/chainguard/apko build base.yaml base:test base.tar\ndocker load \u003c base.tar\n\n# Build glibc image  \ndocker run -v $PWD:/work cgr.dev/chainguard/apko build glibc.yaml glibc:test glibc.tar\ndocker load \u003c glibc.tar\n\n# Build debug image\ndocker run -v $PWD:/work cgr.dev/chainguard/apko build debug.yaml debug:test debug.tar\ndocker load \u003c debug.tar\n\n# Run the debug image interactively\ndocker run -it --rm debug:test\n```\n\n## What is apko and Wolfi?\n\n### apko\n\n[apko](https://github.com/chainguard-dev/apko) is a declarative tool for building container images using Alpine APK packages. Unlike traditional Dockerfiles that use imperative commands, apko uses a YAML configuration to define exactly what goes into an image. This approach:\n\n- Produces minimal, reproducible images\n- Generates SBOMs (Software Bill of Materials) automatically\n- Eliminates unnecessary build artifacts and package managers\n- Creates truly distroless images without shells or other debugging tools\n\n### Wolfi\n\n[Wolfi](https://github.com/wolfi-dev) is a Linux distribution designed specifically for containers, created by Chainguard. Key features:\n\n- **glibc-based**: Unlike Alpine (which uses musl), Wolfi uses glibc for better compatibility\n- **Security-focused**: Rapid CVE patching and minimal attack surface\n- **Supply chain hardened**: All packages are signed and built with provenance\n- **Container-native**: Designed from the ground up for containerized workloads\n- **Daily updates**: Packages are rebuilt frequently to incorporate the latest security patches\n\nTogether, apko and Wolfi provide a secure foundation for building container images that meet range of requirements while maintaining minimal size and attack surface.\n\n## How to Use\n\nYou can use these images as secure and minimal bases for your applications. Choose the appropriate variant based on your application's requirements:\n\n- Use `:latest` for statically-linked binaries or musl libc compatible apps\n- Use `:glibc` for applications that require GNU libc compatibility  \n- Use `:debug` only for development and troubleshooting\n\n### Example: Go Application (CGO-enabled, glibc)\n\n```dockerfile\nFROM golang:1.23 AS builder\nWORKDIR /src\nCOPY main.go .\nARG TARGETARCH\nENV CGO_ENABLED=1 GOOS=linux GOARCH=$TARGETARCH\nRUN go build -o /hello main.go\n\n# Use glibc variant for CGO-enabled applications\nFROM ghcr.io/taihen/base-image:glibc\n# OR use a specific version for reproducible builds\n# FROM ghcr.io/taihen/base-image:v2025.06.13-glibc\nCOPY --from=builder /hello /hello\nUSER 65532:65532\nENTRYPOINT [\"/hello\"]\n```\n\n### Example: Static Binary (musl libc)\n\n```dockerfile  \nFROM golang:1.23-alpine AS builder\nWORKDIR /src\nCOPY main.go .\nARG TARGETARCH\nENV CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH\nRUN go build -ldflags=\"-s -w\" -o /hello main.go\n\n# Use base variant for static binaries\nFROM ghcr.io/taihen/base-image:latest\nCOPY --from=builder /hello /hello\nUSER 65532:65532\nENTRYPOINT [\"/hello\"]\n```\n\n### Example: Java (custom JRE with jlink)\n\n```dockerfile\nFROM eclipse-temurin:17-jdk AS builder\nWORKDIR /app\nCOPY Hello.java .\nRUN javac Hello.java\nRUN echo \"Main-Class: Hello\" \u003e manifest.txt \u0026\u0026 jar cfm hello.jar manifest.txt Hello.class\nRUN $JAVA_HOME/bin/jlink --add-modules java.base --strip-debug --no-man-pages --no-header-files --compress=2 --output /jre\n\n# Use glibc variant for Java applications  \nFROM ghcr.io/taihen/base-image:glibc\nCOPY --from=builder /jre /jre\nCOPY --from=builder /app/hello.jar /app/hello.jar\nENTRYPOINT [\"/jre/bin/java\", \"-jar\", \"/app/hello.jar\"]\n```\n\n### Using the Debug Image for Development\n\n```dockerfile\n# For development and debugging\nFROM ghcr.io/taihen/base-image:debug\n\n# You can install additional packages with apk\nRUN apk add --no-cache curl jq\n\n# Debug your application interactively\nCOPY my-app /usr/local/bin/\nENTRYPOINT [\"/bin/sh\"]  # or [\"/usr/local/bin/my-app\"]\n```\n\n**Quick debugging session:**\n\n```bash\n# Run the debug image interactively\ndocker run -it --rm ghcr.io/taihen/base-image:debug\n\n# Inside the container, you have shell access and tools\n/ # apk add --no-cache curl\n/ # curl -s https://httpbin.org/json | jq\n/ # ps aux\n/ # ls -la /\n```\n\n## Local Testing\n\nTo build the image locally, you need Docker with BuildKit enabled.\n\n1. **Enable BuildKit:**\n\n    ```sh\n    export DOCKER_BUILDKIT=1\n    ```\n\n2. **Build for multiple platforms:**\n\n    ```sh\n    docker buildx create --use\n    docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/taihen/base-image:latest --push .\n    ```\n\n3. **Run the test suite:**\n\n    ```sh\n    # Test the latest published image\n    ./test/test-image.sh\n\n    # Test a specific image\n    ./test/test-image.sh ghcr.io/taihen/base-image:latest\n    ```\n\n    The test script will:\n    - Build and run a Go hello world application using the base image\n    - Verify the non-root user configuration\n    - Run a security scan with Trivy\n    - Report any issues found\n\n## Automation\n\nThe [`.github/workflows/build.yml`](./.github/workflows/build.yml) workflow handles the entire build, push, and sign process for all three image variants. It is triggered on:\n\n- A `push` to the `main` branch.\n- A daily schedule (`cron: \"0 5 * * *\"`) to ensure images are kept up-to-date with upstream packages.\n\nThe workflow builds all three image variants in parallel and applies the following tagging strategy:\n\n- **Base images**: Tagged with `latest` and version tags (e.g., `v2025.06.13`)\n- **glibc images**: Tagged with `glibc` and version-glibc tags (e.g., `v2025.06.13-glibc`)\n- **Debug images**: Tagged with `debug` and version-debug tags (e.g., `v2025.06.13-debug`)\n\n## Automatic Release System\n\nThis repository includes an intelligent automatic release system that creates GitHub releases only when there are actual changes in the built image. This prevents unnecessary releases when the daily cron job runs but no packages have been updated.\n\n### How it Works\n\n1. **Digest Comparison**: After each build, the workflow captures the image digest (a unique identifier based on the image's content).\n2. **Change Detection**: The digest is compared with the previous build's digest stored as a GitHub artifact.\n3. **Conditional Release**: A new GitHub release is created only if:\n   - No previous digest exists (first run)\n   - The current digest differs from the previous one (indicating changes)\n4. **Release Contents**: Each release includes:\n   - The image digest for verification\n   - The SBOM (Software Bill of Materials) as an attachment\n   - Instructions for verifying the image signature\n   - **Detailed package changelog** showing what changed since the last release\n\n### Package Change Tracking\n\nThe release system automatically compares the SBOMs from the current and previous releases to generate a detailed changelog that shows:\n\n- **Added packages**: New packages introduced in this release\n- **Updated packages**: Packages with version changes\n- **Removed packages**: Packages that were removed\n- **Summary statistics**: Total package counts and change counts for both images\n\nIf no package changes are detected (e.g., only metadata or rebuild changes), the release notes will indicate \"No package changes detected (metadata or rebuild only)\".\n\n### Benefits\n\n- **Meaningful Releases**: Only creates releases when there are actual changes\n- **Transparent Changes**: Every release documents exactly what packages changed\n- **Audit Trail**: Each release documents what changed and when\n- **Resource Efficiency**: Avoids cluttering the releases page with identical builds\n- **Supply Chain Security**: Every release includes verification instructions and SBOM\n\n### Release Naming\n\nReleases are automatically tagged with a date-based version format: `vYYYY.MM.DD` (e.g., `v2025.06.13`). If multiple releases occur on the same day, a counter is appended (e.g., `v2025.06.13.1`).\n\nEach release creates:\n\n- A GitHub release with the version tag\n- A Docker image tagged with the same version (e.g., `ghcr.io/taihen/base-image:v2025.06.13`)\n- The `latest` tag is also updated to point to the newest release\n\n## Automated Testing\n\nBefore creating a release, the workflow runs comprehensive tests to ensure all three image variants work correctly:\n\n### Test Suite\n\n1. **Go Application Test**: Builds and runs a hello world Go application on all three image variants\n   - Verifies glibc/musl compatibility as appropriate\n   - Tests both `linux/amd64` and `linux/arm64` architectures\n   - Confirms correct user execution (UID 65532 for production variants, UID 0 for debug)\n   - Validates environment variable handling\n\n2. **Multi-Platform Build Test**: Ensures all images work correctly in multi-architecture builds\n\n3. **Security Scan**: Runs Trivy to scan all image variants for vulnerabilities and reports any critical or high-severity issues\n\n### Test Failure Handling\n\nIf any test fails:\n\n- The workflow stops immediately\n- No release is created\n- The build artifacts remain available for debugging\n- The next scheduled run will retry if the issues are resolved\n\nThis ensures that only fully functional and tested images are released.\n\n## Projects using it\n\n- [MCP RIPEStat](https://github.com/taihen/mcp-ripestat)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaihen%2Fbase-image","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaihen%2Fbase-image","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaihen%2Fbase-image/lists"}