npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@putnami/docker

v0.0.3-cfbc20e

Published

Docker support for building, publishing, and running containerized applications

Downloads

87

Readme

@putnami/docker

Docker support for building, publishing, and running containerized applications in the Putnami monorepo.

Overview

The @putnami/docker plugin provides a unified interface for Docker operations across all runtime/service projects. It delegates the concrete Docker image implementation to technology-specific plugins (TypeScript, Python, Go) while providing consistent commands for building, publishing, and running containers.

Installation

Add @putnami/docker to your project's devDependencies:

{
  "devDependencies": {
    "@putnami/docker": "workspace:*",
    "@putnami/typescript": "workspace:*"
  }
}

Commands

Project Resolution Defaults (project-scoped commands):

  • If run inside a project directory with no project argument, . is used.
  • If run from the workspace root with no project argument, [impacted] is used.

docker build

Build a Docker image for a project.

putnami docker build [project]

Options:

  • --tag <tag>: Image tag (default: branch-based tag with SHA, e.g., canary.abc1234)
  • --registry <registry>: Docker registry (default: from workspace config or local)
  • --platform <platform>: Target platform (default: linux/amd64)
  • --no-cache: Disable build cache
  • --push: Push image after build
  • --file <file>: Custom Dockerfile path (overrides auto-generation)
  • --port <port>: Port to expose (default: from project config or 3000)
  • --workspace-builder-image <image>: Shared workspace builder image to use for build stage

Dockerfile Resolution (first match wins):

  1. --file <path> (absolute or relative to the project root)
  2. Dockerfile at the project root
  3. Generated Dockerfile at {project}/.gen/Dockerfile

Tag Strategy: When --tag is not provided, the build uses the same strategy as registry publishing:

  • Uses branch-based tag with git SHA (e.g., canary.abc1234 for main branch)
  • Format: {branch-tag}.{sha} or {branch-tag}.{sha}.{dirty-hash} for uncommitted changes
  • Main/master branches use canary as the branch tag
  • Other branches use sanitized branch name as the tag

Example:

# Build image for current project
putnami docker build .

# Build with custom tag
putnami docker build my-app --tag my-app:v1.0.0

# Build and push to registry
putnami docker build my-app --registry ghcr.io/myorg --push

# Build using shared workspace builder image
putnami docker build my-app --workspace-builder-image ghcr.io/myorg/putnami-workspace-builder:canary

docker build-workspace

Build a shared workspace builder image (Bun cache + full workspace build output).

When no custom Dockerfile is provided, the generated Dockerfile is stored at .putnami/projects/[workspace]/@putnami-docker/Dockerfile and copies all workspace projects discovered by Putnami.

putnami docker build-workspace

Options:

  • --image <image>: Full image name (overrides registry/name/tag)
  • --tag <tag>: Image tag (default: branch-based tag with SHA)
  • --registry <registry>: Docker registry (default: from workspace config or local)
  • --platform <platform>: Target platform (default: linux/amd64)
  • --no-cache: Disable build cache
  • --push: Push image after build
  • --file <file>: Custom Dockerfile path (overrides auto-generation)

Default naming: If --image is not provided, the image is named: {workspace}-workspace-builder:{branch-tag}.{sha}

Example:

# Build workspace builder image (default naming)
putnami docker build-workspace

# Build with custom tag
putnami docker build-workspace --tag canary

# Build and push to registry
putnami docker build-workspace --registry ghcr.io/myorg --push

# Use the workspace builder for project images
putnami docker build my-app --workspace-builder-image ghcr.io/myorg/putnami-workspace-builder:canary

docker publish

Publish a Docker image to a registry.

putnami docker publish [project] --registry <registry>

Options:

  • --tag <tag>: Image tag (default: version from package.json)
  • --registry <registry>: Docker registry (required, or from workspace config)
  • --platform <platform>: Target platform (default: linux/amd64)
  • --latest: Also tag as latest (otherwise uses branch-based tag like registry dist-tags)
  • --dry-run: Show what would be published

Tag Strategy: When --tag is not provided, the publish uses the same strategy as registry publishing:

  • Uses version from package.json as the base tag
  • If --latest is set, also tags as latest
  • Otherwise, also tags with branch-based tag (e.g., canary) similar to registry dist-tags
  • Example: For version 1.0.0 on main branch, publishes tags: 1.0.0 and canary

Base Image Resolution:

  • Publishes from the image tagged with the current branch-based suffix (e.g., canary.abc1234)
  • If that image does not exist, falls back to a local latest image
  • If neither exists, publish fails (build with putnami docker build <project> --no-cache)

Requirements:

  • A version in package.json or --tag is required, otherwise no tags can be published

Example:

# Publish with version tag
putnami docker publish my-app --registry ghcr.io/myorg

# Publish with latest tag
putnami docker publish my-app --registry ghcr.io/myorg --latest

# Dry run to see what would be published
putnami docker publish my-app --registry ghcr.io/myorg --dry-run

docker run

Run a Docker container locally.

putnami docker run [project]

Options:

  • --tag <tag>: Image tag to run (default: latest)
  • --port <port>: Port mapping (format: host:container or just port number, can be specified multiple times; defaults to image PORT/EXPOSE or 3000)
  • --env <key=value>: Environment variable (can be specified multiple times)
  • --detach: Run in detached mode
  • --rm: Remove container after exit (default: true)
  • --name <name>: Container name

Behavior:

  • Removes any existing container with the same name before starting
  • Starts the container in detached mode and tails logs unless --detach is set
  • Ctrl+C stops the container and removes it when --rm is true

Example:

# Run container
putnami docker run my-app

# Run with port mapping
putnami docker run my-app --port 3000:3000

# Run with environment variables
putnami docker run my-app --env NODE_ENV=production --env API_KEY=secret

# Run in detached mode
putnami docker run my-app --detach

Detailed Command Docs

Technology Plugin Integration

The docker plugin automatically detects which technology plugin is available and delegates image building to it. Currently supported:

  • @putnami/typescript: Generates multi-stage Dockerfiles for Bun/TypeScript projects

How It Works

  1. The docker plugin detects which technology plugin is in your devDependencies
  2. It imports the docker implementation from that plugin (e.g., @putnami/typescript/docker)
  3. The technology plugin generates a Dockerfile optimized for that technology
  4. The docker plugin builds the image using the generated Dockerfile

TypeScript/Bun Implementation

For TypeScript projects, the plugin generates a multi-stage Dockerfile:

  • Builder stage: Full Bun runtime with all dependencies
  • Runtime stage: Minimal bun:1-slim image with only production dependencies

The Dockerfile is optimized for:

  • CI time: Layer caching separates dependency installation from source code
  • Artifact size: Multi-stage build removes build tools from final image
  • Reproducibility: Uses --frozen-lockfile for consistent builds

Configuration

Configure Docker behavior at either the workspace or project level. Project-level configuration overrides workspace-level configuration.

Workspace-Level Configuration

In putnami.json at workspace root:

{
  "defaultParams": {
    "@putnami/docker": {
      "registry": "europe-west9-docker.pkg.dev/myorg/images",
      "platform": "linux/amd64"
    }
  }
}

Project-Level Configuration

In your project's .putnamirc.json:

{
  "commands": {
    "@putnami/docker": {
      "registry": "ghcr.io/myorg",
      "platform": "linux/amd64",
      "port": 3000
    }
  }
}

Configuration Priority

Configuration is merged in the following order (highest to lowest priority):

  1. Command-line arguments (e.g., --registry)
  2. Project-level commands in .putnamirc.json
  3. Workspace-level defaultParams in putnami.json

Job Dependencies

The docker jobs have the following dependencies:

  • docker build: Depends on ^build and /docker-build-workspace (builds dependencies and the shared workspace builder image first)
  • docker build-workspace: Depends on *build (builds all workspace projects before creating the builder image)
  • docker publish: Depends on docker-build and ^docker-publish (publishes dependencies first)
  • docker run: Depends on docker-build (ensures the image is built before running)

This ensures that:

  1. All project dependencies are built before building the Docker image
  2. Dependencies are published before the project itself

CI/CD Integration

GitHub Actions Example

name: Build and Publish Docker Images

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: oven-sh/setup-bun@v1
      - name: Install dependencies
        run: bun install
      - name: Build Docker images
        run: bunx putnami docker build --impacted
      - name: Publish Docker images
        run: |
          echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          bunx putnami docker publish --impacted --registry ghcr.io/myorg --latest

Best Practices

  1. Use layer caching: Don't use --no-cache unless necessary
  2. Build dependencies first: The plugin handles this automatically via job dependencies
  3. Use version tags: Let the plugin generate version-based tags for reproducibility
  4. Multi-stage builds: Technology plugins generate optimized multi-stage Dockerfiles
  5. Minimal base images: Use slim/alpine variants when possible

Troubleshooting

Docker not available

If you see "Docker is not available", ensure:

  • Docker is installed and running
  • Docker daemon is accessible

Technology plugin not found

If you see "No technology plugin found", ensure:

  • You have @putnami/typescript, @putnami/python, or @putnami/go in devDependencies
  • The plugin supports Docker (exports ./docker)

Build fails

Common issues:

  • Missing build output: Ensure you've run putnami build first
  • Workspace dependencies: Ensure all workspace dependencies are built
  • Port conflicts: Check if the port is already in use

Architecture

See PLAN.md for detailed architecture and implementation details.