Skip to main content

Owner-scoped plan/apply/adopt controller for Nginx Proxy Manager resources.

Project description

npmctl

Owner-scoped GitOps for Nginx Proxy Manager

Validate desired-state YAML, plan safe owner-scoped changes, apply clean reconciles, and adopt existing NPM resources only when you ask for it.

PyPI version Python versions CI Live NPM Gate Apache 2.0 License

npmctl package hits npmctl downloads

npmctl architecture infographic

npmctl is the Python package and console script for declarative, owner-scoped Nginx Proxy Manager automation. It manages proxy hosts, certificates, access lists, redirection hosts, dead hosts, streams, users, settings, and provider-backed DNS records without silently mutating foreign-owned resources.

Supported Python Versions

npmctl supports Python 3.10, 3.11, 3.12, 3.13, and 3.14.

Why npmctl

  • Owner-scoped reconciliation instead of global mutable state
  • Explicit plan, apply, and adopt flows instead of ad hoc API scripting
  • Safe reference handling for certificates and access lists
  • Fail-closed behavior when the target NPM schema does not support a required operation
  • CLI-first workflows that fit GitOps, CI, and controlled repair operations

FAQ

What is npmctl?

Answer: npmctl is a GitOps-style controller for Nginx Proxy Manager that reads desired-state YAML, compares it to the live NPM API, and produces safe owner-scoped plans before any mutation happens.

What problem does npmctl solve?

Answer: npmctl replaces manual NPM clicking and one-off API scripts with repeatable desired state, explicit adoption, conflict detection, and controlled reconciliation for reverse-proxy resources.

Does npmctl modify resources it does not own?

Answer: No. npmctl treats NPM resources as owner-scoped, refuses to mutate foreign-owned resources, and only attaches metadata to unmanaged resources when you run npmctl adopt.

How does npmctl handle certificate issuance and rotation?

Answer: npmctl treats certificates as declarative resources in the same desired state as proxy hosts. Issuance happens when a desired certificate must be created, and rotation happens through explicit reconcile policy rather than hidden mutation of unrelated resources.

Can npmctl adopt existing manually created NPM resources?

Answer: Yes. npmctl adopt can attach npmctl ownership metadata to compatible unmanaged resources so future plans and applies can manage them under explicit owner scope.

Install

Use pipx for an isolated CLI install:

pipx install npmctl
npmctl --version

Use uv if you manage tools with uv:

uv tool install npmctl
npmctl --help

Use pip inside an existing virtual environment:

python -m venv .venv
. .venv/bin/activate
python -m pip install npmctl
npmctl --help

PowerShell activation:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install npmctl
npmctl --help

Configure NPM

Set Nginx Proxy Manager API credentials as environment variables:

export NPM_BASE_URL=http://127.0.0.1:81/api
export NPM_IDENTITY=admin@example.com
export NPM_SECRET=changeme

Or pass them directly:

npmctl --base-url http://127.0.0.1:81/api --identity admin@example.com --secret changeme health

Quick Start

Validate desired state without touching the API:

npmctl validate ./desired-state
npmctl --output json validate ./desired-state

Plan owner-scoped changes:

npmctl plan ./desired-state --owner workload-a

Apply a clean plan:

npmctl apply ./desired-state --owner workload-a

Adopt unmanaged matching resources:

npmctl adopt ./desired-state --owner workload-a
npmctl adopt ./desired-state --owner workload-a --allow-field-drift

Desired State

Every managed resource needs npmctl ownership metadata:

apiVersion: npmctl.com/v1
schemaVersion: 2
proxy_hosts:
  - domain_names: [app.example.com]
    forward_scheme: http
    forward_host: app
    forward_port: 3000
    meta:
      managed_by: npmctl
      owner: workload-a
      resource_id: proxy.app

References use resource_id values:

apiVersion: npmctl.com/v1
schemaVersion: 2
certificates:
  - name: wildcard-example
    domain_names: ["*.example.com", example.com]
    certificate_type: letsencrypt
    api_payload:
      provider: letsencrypt
    meta:
      managed_by: npmctl
      owner: workload-a
      resource_id: cert.wildcard-example
access_lists:
  - name: private-admins
    api_payload:
      satisfy_any: 0
      items: []
      clients: []
    meta:
      managed_by: npmctl
      owner: workload-a
      resource_id: acl.private-admins
proxy_hosts:
  - domain_names: [app.example.com]
    forward_host: app
    forward_port: 3000
    certificate_ref: cert.wildcard-example
    access_list_ref: acl.private-admins
    ssl_forced: 1
    allow_websocket_upgrade: 1
    caching_enabled: 1
    block_exploits: 1
    meta:
      managed_by: npmctl
      owner: workload-a
      resource_id: proxy.app

More Documentation

PyPI Trusted Publishing

The release workflow publishes all npmctl distributions through GitHub Actions OIDC first, then falls back to the configured PyPI API token only if trusted publishing is unavailable. Configure a pending trusted publisher on PyPI for each published project before dispatching a release:

PyPI project Owner Repository Workflow Environment
npmctl groupsum npmctl release.yml pypi
npmctl-namecheap groupsum npmctl release.yml pypi
npmctl-cloudflare groupsum npmctl release.yml pypi
npmctl-digitalocean groupsum npmctl release.yml pypi
npmctl-godaddy groupsum npmctl release.yml pypi
npmctl-route53 groupsum npmctl release.yml pypi

The GitHub workflow grants id-token: write and publishes from the pypi environment, so the PyPI project settings must match those fields exactly.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

npmctl-0.3.10.tar.gz (44.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

npmctl-0.3.10-py3-none-any.whl (56.7 kB view details)

Uploaded Python 3

File details

Details for the file npmctl-0.3.10.tar.gz.

File metadata

  • Download URL: npmctl-0.3.10.tar.gz
  • Upload date:
  • Size: 44.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for npmctl-0.3.10.tar.gz
Algorithm Hash digest
SHA256 2bbb8452ac21e790ecfb6cba8d4a162e0b0b40a0abdaed26489be3e510aca73d
MD5 76e01ee45fcc6ae9256db6c4ba55aefa
BLAKE2b-256 9d8282e29641c25db7a5204cec258ba451fa3c11d3393c588230d451e7e6556d

See more details on using hashes here.

Provenance

The following attestation bundles were made for npmctl-0.3.10.tar.gz:

Publisher: release.yml on groupsum/npmctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file npmctl-0.3.10-py3-none-any.whl.

File metadata

  • Download URL: npmctl-0.3.10-py3-none-any.whl
  • Upload date:
  • Size: 56.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for npmctl-0.3.10-py3-none-any.whl
Algorithm Hash digest
SHA256 a6b316148aba3f224bd9c2653f0efc38e42ace84f3d5fbe2c1a0bfe503e4c398
MD5 2c26dab5b3d2ec33c18c48eaa54e1723
BLAKE2b-256 f7471d3aa23d52576c67a41971ba62b812ce8ed3c9515cf9804aa13a938a31b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for npmctl-0.3.10-py3-none-any.whl:

Publisher: release.yml on groupsum/npmctl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page