hatch-oci
A Hatch plugin that integrates pyoci to build OCI container images directly from your Hatch projects — no Docker required.
Features
- 🐍 Native Hatch Integration - Build containers during
hatch build - 🚫 No Docker Required - Pure Python OCI image generation
- ⚡ Fast Builds - Efficient layer caching and reuse
- 🔧 Configuration via pyproject.toml - Use
[tool.hatch.build.hooks.pyoci]section - 📦 Automatic Dependency Packaging - Includes project dependencies
- 🔒 SBOM Generation - Built-in security compliance
Installation
pip install hatch-oci
Quick Start
Basic Usage
Add the plugin to your pyproject.toml:
[build-system]
requires = ["hatchling", "hatch-oci"]
build-backend = "hatchling.build"
[tool.hatch.build.hooks.pyoci]
# The hook runs when this section is present.
Then build your container:
hatch build
This will:
- Build your Python package (wheel)
- Create a container image with pyoci
- Output to
dist/image/
Configuration
Basic Configuration
[tool.hatch.build.hooks.pyoci]
# Container image tag
tag = "myapp:latest"
# Base container image
base-image = "python:3.11-slim"
# Include dependencies
include-deps = true
Complete Configuration
[tool.hatch.build.hooks.pyoci]
# Skip container build (useful for local dev)
skip = false
# Container image tag
tag = "myapp:v1.0.0"
# Base container image
base-image = "python:3.11-slim"
# Container registry URL
registry = "ghcr.io/user/myapp"
# Push to registry after build
push = false
# Include project dependencies
include-deps = true
# Generate SBOM (spdx or cyclonedx)
sbom = "spdx"
# Enable verbose output
verbose = true
# Disable layer caching
no-cache = false
# Environment variables
[tool.hatch.build.hooks.pyoci.env]
ENV = "production"
PORT = "8080"
DEBUG = "false"
# Container labels
[tool.hatch.build.hooks.pyoci.labels]
maintainer = "team@example.com"
org.opencontainers.image.source = "https://github.com/user/repo"
Usage Examples
Build Container with Package
# Build both wheel and container
hatch build
# The container image will be at dist/image/
Build and Push
[tool.hatch.build.hooks.pyoci]
tag = "ghcr.io/myorg/myapp:latest"
push = true
# Build and push in one command
GITHUB_TOKEN=$GITHUB_TOKEN hatch build
Development vs Production
Use environment-specific configuration:
[tool.hatch.envs.default.build.hooks.pyoci]
tag = "myapp:dev"
base-image = "python:3.11"
push = false
[tool.hatch.envs.production.build.hooks.pyoci]
tag = "myapp:latest"
base-image = "python:3.11-slim"
push = true
sbom = "spdx"
Skip Container Build
# Skip container build for local dev
hatch build -e local
# Or set in pyproject.toml
[tool.hatch.envs.local.build.hooks.pyoci]
skip = true
Integration Examples
With GitHub Actions
name: Build and Release
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install Hatch
run: pip install hatch hatch-oci
- name: Build package and container
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: hatch build
With Azure Developer CLI
# azure.yaml
name: myapp
services:
api:
project: ./
language: python
host: containerapp
hooks:
prebuild:
shell: sh
run: pip install hatch hatch-oci
build:
shell: sh
run: hatch build
With CI/CD Pipeline
# .gitlab-ci.yml
build:
image: python:3.11
script:
- pip install hatch hatch-oci
- hatch build
artifacts:
paths:
- dist/
How It Works
- Registers Build Hook - Hatch calls the pyoci hook during build
- Reads Configuration - Extracts settings from
pyproject.toml - Builds Container - Uses pyoci to create OCI image
- Adds Metadata - Automatically adds version and build info
- Pushes (Optional) - Pushes to registry if configured
Advanced Usage
Custom Build Targets
[tool.hatch.build.targets.wheel.hooks.pyoci]
tag = "myapp:wheel-build"
[tool.hatch.build.targets.sdist.hooks.pyoci]
skip = true # Don't build container for sdist
Multi-Architecture
[tool.hatch.build.hooks.pyoci]
platform = "linux/amd64"
# Note: Full multi-arch builds coming in future release
Framework Auto-Detection
pyoci automatically detects:
- FastAPI - Configures uvicorn entrypoint
- Flask - Sets up Flask server
- Django - Configures Django runserver
Custom Base Images
[tool.hatch.build.hooks.pyoci]
# Minimal distroless image
base-image = "gcr.io/distroless/python3-debian12"
# Alpine for small size
base-image = "python:3.11-alpine"
# Microsoft Azure-optimized
base-image = "mcr.microsoft.com/python/distroless"
Environment Variables
Set these during build for authentication:
# GitHub Container Registry
GITHUB_TOKEN=ghp_... hatch build
# Docker Hub
REGISTRY_USERNAME=myuser REGISTRY_PASSWORD=mypass hatch build
# Azure Container Registry (uses az cli)
az acr login --name myregistry
hatch build
Troubleshooting
Hook Not Running
Ensure the hook is enabled:
[tool.hatch.build.hooks.pyoci]
enable = true
skip = false
pyoci Not Found
Install it explicitly:
pip install pyoci
Or add to build requirements:
[build-system]
requires = ["hatchling", "hatch-oci", "pyoci"]
Dependencies Not Included
Check configuration:
[tool.hatch.build.hooks.pyoci]
include-deps = true
Push Fails
Verify authentication:
# For GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# For ACR
az acr login --name myregistry
Comparison with Other Tools
| Feature | hatch-oci | Dockerfile | Buildpacks |
|---|---|---|---|
| No Docker daemon | ✅ | ❌ | ❌ |
| Pure Python | ✅ | ❌ | ❌ |
| Hatch native | ✅ | ❌ | ❌ |
| Auto-config | ✅ | ❌ | ✅ |
| Layer caching | ✅ | ✅ | ✅ |
| SBOM generation | ✅ | ❌ | ✅ |
Requirements
- Python 3.11+
- Hatch 1.18.0+
- pyoci (installed automatically)
License
MIT License - See LICENSE file for details
Contributing
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
Related Projects
- pyoci - Core container builder
- poetry-oci - Poetry plugin
- Hatch - Modern Python project manager
Support
Metadata
Release files for hatch-oci 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hatch_oci-0.1.0.tar.gz | 7.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hatch_oci-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.8 kB
Release files / hatch_oci-0.1.0.tar.gz
| Download URL | hatch_oci-0.1.0.tar.gz |
|---|---|
| Size | 7.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5e87193073d7bc6de7f1524354b41b384e4589cb17de38e93435576184774bf8
|
|
BLAKE2b-256 checksum How to use checksums |
2a193d2195a622fddc5d4b174960c843af24c9f92d885954b93184c5830d2bdd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logRelease files / hatch_oci-0.1.0-py3-none-any.whl
| Download URL | hatch_oci-0.1.0-py3-none-any.whl |
|---|---|
| Size | 5.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2f11ef05a5d897947c07863eeb4714a59e22af413f7184e61f6a489acd6a23ca
|
|
BLAKE2b-256 checksum How to use checksums |
60e64be728db4ecc2919609ab7f007393d2d50d012c95a90c23898e5ec0e6e5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logSecurity for hatch-oci 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for hatch_oci-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.