Repository navigation
Releases: fwartner/pnp
Releases · fwartner/pnp
Release list
v1.4.0
What's New
Extensible Plugin System
- Project type registry — add new project types by implementing a single Go file with
init()self-registration - External plugins — third parties can add types, commands, and hooks via
~/.pnp/plugins/with a simpleplugin.yamlmanifest - Plugin protocol — stdin/stdout JSON communication for type detection, templates, Dockerfiles, and scaffolding
- Pre/post-deploy hooks — plugins can hook into the deploy lifecycle
Project Scaffolding
pnp new <type> <name>— scaffold a complete project with directory structure,.cluster.yaml, Dockerfile, and CI workflow in one command- Supports all built-in types:
laravel-web,laravel-api,nextjs-fullstack,nextjs-static,strapi
Scope-Prefixed Naming
- Projects automatically get scope-prefixed names (e.g.
agency-my-app,customer-acme-corp) - Smart detection prevents double-prefixing; backwards compatible with existing configs
Internal Improvements
- Refactored all type-specific logic from monolithic switch/case blocks into self-contained type files
- Removed ~950 lines of duplicated template/Dockerfile constants from shared files
- Registry-based architecture makes adding new types trivial
v1.3.0
What's New
New Commands
pnp doctor— Prerequisites checker with auto-fix (git, gh, docker, kubectl, config validation)pnp list— Show all deployed applications from the gitops repo in a formatted tablepnp env list|set|edit— Manage.cluster.yamlconfiguration with dot-notation supportpnp logs [app-name]— Stream application logs with--followand--tailflagspnp rollback— Interactive revert of deployment commits in the gitops repo
Simplified Wizard
- Basic mode (default) — Only 4 questions: name, type, scope, environment. Smart defaults handle everything else
- Advanced mode (
pnp deploy --advanced) — Full 7-step wizard with all options - Type-specific smart defaults for database, Redis, queue, scheduler, persistence, and resources
Deploy Improvements
- Live progress tracker — Spinner animation with step-by-step progress indicators (✓/✗)
- Prerequisite checks — Deploy now validates critical requirements before starting
- Preview environments (
pnp deploy --with-previews) — Generates GitHub Actions workflow for PR-based preview deployments
Enhanced Status
- Error explanations — Human-readable descriptions for ImagePullBackOff, CrashLoopBackOff, OOMKilled, etc.
- Suggested fixes — Each error includes a recommended
pnpcommand to resolve it - Pod table — Shows individual pod status when the app is unhealthy
Internal
- Extracted shared styles to
cmd/styles.go - New
internal/kubepackage for kubectl operations - New
internal/progresspackage for step tracking - New
internal/doctorpackage for prerequisite validation - Added
ListApps(),GitLog(),Revert()to gitops repo operations
v1.2.0
Changelog
- a2e1f35 feat: upgrade base images to latest deps with production hardening
v1.1.0
Pre-Built Base Images for Next.js and Strapi
Adds pre-built base images for Next.js and Strapi to match the existing Laravel base images, speeding up CI builds.
New Base Images
ghcr.io/fwartner/pnp/nextjs:latest— Node 20 Alpine with libc6-compat, vips, python3, build tools, non-rootnextjsuserghcr.io/fwartner/pnp/strapi:latest— Node 20 Alpine with libc6-compat, vips, python3, build tools, non-rootstrapiuser
All Base Images
| Image | Purpose |
|---|---|
ghcr.io/fwartner/pnp/laravel-fpm |
Laravel with nginx + PHP-FPM |
ghcr.io/fwartner/pnp/laravel-frankenphp |
Laravel Octane (FrankenPHP) |
ghcr.io/fwartner/pnp/laravel-swoole |
Laravel Octane (Swoole) |
ghcr.io/fwartner/pnp/laravel-roadrunner |
Laravel Octane (RoadRunner) |
ghcr.io/fwartner/pnp/nextjs |
Next.js applications |
ghcr.io/fwartner/pnp/strapi |
Strapi CMS |
Changes
- Generated Dockerfiles for Next.js and Strapi now use the pre-built base images instead of plain
node:20-alpine - Native dependencies (sharp, vips) are pre-installed in the base image, eliminating rebuild time in CI
v1.0.0
PnP CLI v1.0.0
Pixel & Process Kubernetes Deployment Manager — Run pnp deploy in any project and it's live on the cluster. Fully automatic.
Install
brew install fwartner/tap/pnpOr download binaries below (linux/darwin, amd64/arm64).
What It Does
Run pnp deploy inside a Laravel, Next.js, or Strapi project. The CLI:
- Detects project type automatically
- Runs an interactive wizard to configure domain, database, Redis, queues, etc.
- Generates Kubernetes manifests and pushes them to your GitOps repo
- Generates a Dockerfile and GitHub Actions CI/CD pipeline
- Commits and pushes everything — both to the GitOps repo and the project repo
- Sets up GITOPS_TOKEN so CI can push cross-repo automatically
After that, every push to main is fully automatic: build → push to GHCR → update GitOps repo → ArgoCD syncs → app is live.
Features
Project Types
- Laravel Web/API — nginx + PHP-FPM, queue workers, scheduler, Horizon, Reverb
- Laravel Octane — FrankenPHP, Swoole, or RoadRunner
- Next.js — Fullstack (with DB) or Static
- Strapi — Headless CMS with persistence
Infrastructure
- ArgoCD GitOps with auto-sync and self-heal
- CloudNativePG for PostgreSQL databases
- Redis via redis-operator
- cert-manager + Let's Encrypt for TLS
- external-dns + Cloudflare for DNS
- Infisical for secrets management (optional)
- Traefik ingress with HTTPS
Scope-Based Organization
apps/customer/{name}— client projectsapps/agency/{name}— agency/internal toolsapps/previews/{name}— preview/staging deployments
Pre-Built Base Images
Laravel builds use pre-built base images on GHCR for fast CI:
ghcr.io/fwartner/pnp/laravel-fpmghcr.io/fwartner/pnp/laravel-frankenphpghcr.io/fwartner/pnp/laravel-swooleghcr.io/fwartner/pnp/laravel-roadrunner
Security
- Docker BuildKit secrets for
COMPOSER_AUTH(no build args) - Auto-generated
APP_KEYand DB passwords - Private Composer package support
Commands
| Command | Description |
|---|---|
pnp deploy |
Full deploy wizard (first-time setup) |
pnp sync |
Re-render and push GitOps manifests (non-interactive) |
pnp update |
Re-render templates from existing config |
pnp destroy |
Remove app from cluster |
Configuration
Global (~/.pnp.yaml):
gitopsRepo: /path/to/local/gitops-repo
gitopsRemote: https://github.com/org/gitops.git
defaults:
domain: example.com
imageRegistry: ghcr.io
profiles:
customer:
domain: preview.example.com
githubOrg: my-orgPer-project (.cluster.yaml) — auto-generated by the wizard.