Skip to main content

poetry-oci

A Poetry plugin that integrates pyoci to build OCI container images directly from your Poetry projects — no Docker required.

Features

  • 🐍 Native Poetry Integration - Build containers with poetry build-container
  • 🚫 No Docker Required - Pure Python OCI image generation
  • ⚡ Fast Builds - Efficient layer caching and reuse
  • 🔧 Configuration via pyproject.toml - Use [tool.pyoci] section
  • 📦 Automatic Dependency Packaging - Includes Poetry dependencies
  • 🔒 SBOM Generation - Built-in security compliance

Installation

poetry self add poetry-oci

Or install pyoci and the plugin:

pip install poetry-oci pyoci

Quick Start

Basic Usage

# Build a container image from your Poetry project
poetry build-container

# Build with a specific tag
poetry build-container --tag myapp:v1.0.0

# Build and push to registry
poetry build-container --tag ghcr.io/user/myapp:latest --push

Configuration

Add configuration to your pyproject.toml:

[tool.poetry]
name = "myapp"
version = "1.0.0"
description = "My Python application"

[tool.pyoci]
tag = "myapp:latest"
base_image = "python:3.11-slim"
registry = "ghcr.io/user/myapp"
include_deps = true
push = false

[tool.pyoci.env]
ENV = "production"
PORT = "8080"

[tool.pyoci.labels]
maintainer = "team@example.com"

Commands

poetry build-container

Build an OCI container image from your Poetry project.

Options:

  • --tag, -t - Container image tag (default: {name}:{version})
  • --base-image, -b - Base container image (default: python:3.11-slim)
  • --registry, -r - Container registry URL
  • --push, -p - Push image to registry
  • --include-deps, -d - Include Poetry dependencies (default: true)
  • --sbom, -s - Generate SBOM (spdx or cyclonedx)
  • --verbose, -v - Verbose output
  • --dry-run - Show what would be built without building
  • --no-cache - Disable layer caching

Examples:

# Basic build
poetry build-container

# Build with custom tag
poetry build-container --tag myapp:v2.0.0

# Build on different base image
poetry build-container --base-image python:3.12-alpine

# Build with SBOM
poetry build-container --sbom spdx

# Build and push to GHCR
poetry build-container \
  --tag ghcr.io/myorg/myapp:latest \
  --push \
  --verbose

# Dry run to preview
poetry build-container --dry-run --verbose

Configuration Reference

All configuration is under [tool.pyoci] in pyproject.toml:

[tool.pyoci]
# Container image tag (optional, defaults to {name}:{version})
tag = "myapp:latest"

# Base container image
base_image = "python:3.11-slim"

# Container registry URL
registry = "ghcr.io/user/myapp"

# Push image to registry after build
push = false

# Include Poetry dependencies in the image
include_deps = true

# Generate SBOM (spdx or cyclonedx)
sbom = "spdx"

# Enable verbose output
verbose = false

# Dry run mode
dry_run = false

# Disable layer caching
no_cache = false

# Environment variables to set in the container
[tool.pyoci.env]
ENV = "production"
PORT = "8080"
DEBUG = "false"

# Container labels
[tool.pyoci.labels]
maintainer = "team@example.com"
version = "1.0.0"
org.opencontainers.image.source = "https://github.com/user/repo"

How It Works

  1. Reads Poetry Configuration - Extracts project name, version, dependencies from pyproject.toml
  2. Applies Tool Configuration - Merges [tool.pyoci] settings
  3. Builds Container - Uses pyoci to create OCI image
  4. Adds Metadata - Automatically adds Poetry metadata as OCI labels
  5. Pushes (Optional) - Pushes to registry if --push is specified

Integration Examples

With GitHub Actions

name: Build and Push Container

on:
  push:
    branches: [main]

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 Poetry
        run: pipx install poetry
      
      - name: Install plugin
        run: poetry self add poetry-oci
      
      - name: Install dependencies
        run: poetry install
      
      - name: Build and push container
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          poetry build-container \
            --tag ghcr.io/${{ github.repository }}:${{ github.sha }} \
            --push \
            --verbose

With Azure Developer CLI

# azure.yaml
name: myapp

services:
  api:
    project: ./
    language: python
    host: containerapp
    hooks:
      prebuild:
        shell: sh
        run: |
          pip install poetry
          poetry self add poetry-oci
      build:
        shell: sh
        run: |
          poetry build-container \
            --tag ${SERVICE_IMAGE_NAME}:${SERVICE_IMAGE_TAG} \
            --push

Local Development

# Install dependencies
poetry install

# Build container locally
poetry build-container --tag myapp:dev

# Import the OCI layout into Docker for validation
skopeo copy oci:dist/image docker-daemon:myapp:dev
docker run myapp:dev

Advanced Usage

Custom Base Images

# Use distroless for smaller images
poetry build-container --base-image gcr.io/distroless/python3-debian12

# Use Alpine for minimal size
poetry build-container --base-image python:3.11-alpine

Multi-Stage Configuration

[tool.pyoci]
base_image = "python:3.11-slim"

[tool.pyoci.env]
# Development
ENV = "development"

Framework Auto-Detection

pyoci automatically detects and configures:

  • FastAPI - Sets up uvicorn with correct host/port
  • Flask - Configures Flask development server
  • Django - Sets up Django runserver

No manual configuration needed!

Troubleshooting

Plugin Not Found

# Ensure plugin is installed
poetry self show plugins

# Reinstall if needed
poetry self remove poetry-oci
poetry self add poetry-oci

Build Fails: "pyoci not found"

# Install pyoci
pip install pyoci

# Or add as a dev dependency
poetry add --group dev pyoci

Dependencies Not Included

Ensure include_deps = true in your config:

[tool.pyoci]
include_deps = true

Requirements

  • Python 3.11+
  • Poetry 1.2.0+
  • pyoci (installed automatically as dependency)

License

MIT License - See LICENSE file for details

Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

  • pyoci - The core container builder
  • hatch-oci - Hatch plugin for pyoci
  • Poetry - Python dependency management

Support

Metadata

Release files for poetry-oci 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for poetry-oci 0.2.0
File Size Uploaded Provenance
poetry_oci-0.2.0.tar.gz 11.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for poetry-oci 0.2.0
File Interpreter ABI Platform
poetry_oci-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.6 kB

Release files / poetry_oci-0.2.0.tar.gz

Download URL poetry_oci-0.2.0.tar.gz
Size 11.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4e6aa38b8ce2e118d0db76de12a9f31a38e933f7b0de744f4e22bde4be762c49
BLAKE2b-256 checksum
How to use checksums
eb1f0c6a70e7ede44a1dd450b921c7d7b8f215d9003779bca7f3a1e7fdc04174
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 Oct 1, 2026.

Transparency log

Release files / poetry_oci-0.2.0-py3-none-any.whl

Download URL poetry_oci-0.2.0-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0bcedca95213afb0a43cbbfa2eb279e2b42cb8b8d954b6b093be2be2d34bf20c
BLAKE2b-256 checksum
How to use checksums
7fe7d7ecc6a636231ebc16c816527c6860a39354ead7312dcbc882d6d04314c2
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 Oct 1, 2026.

Transparency log

Security for poetry-oci 0.2.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.

Select from 2 files

Attestation for poetry_oci-0.2.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 Oct 1, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page