Skip to main content
NodePad ships as a set of container images and a Helm chart. The same artifacts serve every supported install posture.
PostureNetworkConsumesInstall path
A. ConnectedPublic internetGHCR + OCI Helm charthelm install … oci://ghcr.io/… or docker compose up
B. Proxied air-gapPrivate, with registry mirrorGHCR via Nexus / Harbor / ArtifactoryRetarget image.registry to your mirror
C. Fully air-gappedNo internetOffline zip bundle from GitHub Release./load-images.sh + helm install ./chart.tgz
D. Trial / single-VMPublic internet or offlineGHCR images or bundledocker compose up

Prerequisites

  • Linux x86_64 (v0.1 is single-arch)
  • TLS certificate for your API and frontend domains
  • Generated secrets:
    • Django secret key — python -c "import secrets; print(secrets.token_urlsafe(50))"
    • Fernet key — python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
  • Kubernetes 1.24+
  • Helm 3.8+ (OCI chart support)
  • An ingress controller (nginx-ingress recommended)
  • Docker 24+ with Compose v2
  • PostgreSQL 15+
  • Redis 6+
  • S3-compatible object storage (AWS S3, Cloudflare R2, DO Spaces, MinIO)

Posture A — Connected install (Kubernetes)

1

Pull the values template

curl -o values.yaml https://raw.githubusercontent.com/palazski/nodepad-api/master/helm/values-template.yaml
Open values.yaml and fill in secrets, database URL, S3 credentials, and hostnames.
2

(If packages are private) log Helm in to GHCR

Use a GitHub token with at least read:packages scope on the owning account:
echo "$GITHUB_TOKEN" | helm registry login ghcr.io -u <github-user> --password-stdin
3

Install the chart

helm install nodepad oci://ghcr.io/palazski/charts/nodepad \
  --version 0.1.0 \
  -f values.yaml
4

Create the first admin user (one-time)

kubectl exec -it deploy/nodepad-nodepad-api -- python manage.py createsuperuser

Posture B — Proxied air-gap (Kubernetes with internal registry)

Your internal registry (Nexus / Harbor / Artifactory) must proxy GHCR (ghcr.io) and cache the NodePad images. Point the chart at your mirror via a single value:
values.yaml (excerpt)
image:
  registry: nexus.company.com/ghcr-proxy
  repository: palazski
  # tag defaults to chart appVersion
  pullSecrets:
    - name: nexus-creds  # if your mirror requires auth
Install as in Posture A.

Posture C — Fully air-gapped install

1

Download the bundle on a connected machine

Grab nodepad-0.1.0.zip from the GitHub Release.
2

Transfer to the air-gapped environment

USB, DMZ, approved file transfer — whatever your policy mandates.
3

Load images into your internal registry

unzip nodepad-0.1.0.zip
cd nodepad-0.1.0
./load-images.sh registry.internal.corp/nodepad
4

Install the chart pointing at your internal registry

values.yaml (excerpt)
image:
  registry: registry.internal.corp
  repository: nodepad
helm install nodepad ./chart/nodepad-0.1.0.tgz -f values.yaml
5

Create the first admin user (same as Posture A)

kubectl exec -it deploy/nodepad-nodepad-api -- python manage.py createsuperuser

Posture D — Single-VM trial (docker compose)

# 1. Download or unzip the bundle
curl -LO https://github.com/palazski/nodepad-api/releases/download/v0.1.0/nodepad-0.1.0.zip
unzip nodepad-0.1.0.zip && cd nodepad-0.1.0

# 2. Load images (offline) OR docker compose will pull them from GHCR
gunzip -c images/api.tar.gz      | docker load
gunzip -c images/frontend.tar.gz | docker load

# 3. Copy .env.example to .env and fill in values
cp .env.example .env
$EDITOR .env     # pin VERSION + IMAGE_OWNER, set secrets

# 4. Start the stack
docker compose up -d

# 5. Create the first admin user
docker compose exec api python manage.py createsuperuser

External vs bundled services

The chart defaults to bring-your-own Postgres / Redis / S3 for production. Set externalPostgres.url, externalRedis.url, and externalS3.* values. For self-contained installs (POC, demo, dev), flip the sub-chart flags:
values.yaml (excerpt)
postgresql:
  enabled: true
  auth:
    username: nodepad
    password: <strong-password>
    database: nodepad
redis:
  enabled: true
  auth:
    enabled: true
    password: <strong-password>
minio:
  enabled: true
  auth:
    rootUser: nodepad
    rootPassword: <strong-password>
The Bitnami sub-charts spin up single-instance Postgres / Redis / MinIO.
Sub-chart databases are not recommended for production — a single pod crash can lose data. Use external managed services for anything that matters.

Verification

# Pods are Running
kubectl get pods -l app.kubernetes.io/instance=nodepad

# Health endpoint returns {"status":"ok"}
curl https://api.nodepad.yourcompany.com/api/health

# Admin panel loads
open https://api.nodepad.yourcompany.com/admin/

Next steps

Upgrade & rollback playbook

How to upgrade safely, roll back, and handle migration-incompatible rollbacks.

Air-gapped install details

Bundle contents, offline upgrade flow, and the zero-outbound-telemetry guarantee.