Norish Helm Chart
A Helm chart for deploying Norish, a recipe management and meal planning application, on Kubernetes.
Introduction
This chart deploys Norish on a Kubernetes cluster. Norish requires an external PostgreSQL database, a Redis server, and includes a Chrome headless sidecar for recipe parsing. It supports multiple authentication methods including password auth, OIDC, GitHub OAuth, and Google OAuth.
Source code: https://github.com/rtomik/helm-charts/tree/main/charts/norish
Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
- PostgreSQL database (required)
- Redis server (required)
- PV provisioner support (if persistence is enabled)
Installing the Chart
Uninstalling the Chart
Configuration Examples
Minimal Installation (Password Authentication)
Production with Existing Secrets
Create the required secrets:
OIDC Authentication
GitHub OAuth
- Create a GitHub OAuth App at https://github.com/settings/developers
- Set Authorization callback URL to:
https://norish.example.com/api/auth/callback/github
Google OAuth
- Create OAuth credentials at https://console.cloud.google.com/apis/credentials
- Set Authorized redirect URI to:
https://norish.example.com/api/auth/callback/google
Using Existing PVC
Parameters
Global Parameters
| Name |
Description |
Default |
nameOverride |
Override the release name |
"" |
fullnameOverride |
Fully override the release name |
"" |
Image Parameters
| Name |
Description |
Default |
image.repository |
Norish image repository |
norishapp/norish |
image.tag |
Image tag |
v0.15.4-beta |
image.pullPolicy |
Image pull policy |
IfNotPresent |
imagePullSecrets |
Image pull secrets |
[] |
Deployment Parameters
| Name |
Description |
Default |
replicaCount |
Number of replicas |
1 |
revisionHistoryLimit |
Revisions to retain |
3 |
podSecurityContext.runAsNonRoot |
Run as non-root |
true |
podSecurityContext.runAsUser |
User ID |
1000 |
podSecurityContext.fsGroup |
Filesystem group ID |
1000 |
nodeSelector |
Node selector |
{} |
tolerations |
Tolerations |
[] |
affinity |
Affinity rules |
{} |
podAnnotations |
Pod annotations |
{} |
Service Parameters
| Name |
Description |
Default |
service.type |
Service type |
ClusterIP |
service.port |
Service port |
3000 |
service.annotations |
Service annotations |
{} |
Ingress Parameters
| Name |
Description |
Default |
ingress.enabled |
Enable ingress |
false |
ingress.className |
Ingress class name |
"" |
ingress.annotations |
Ingress annotations |
See values.yaml |
ingress.hosts |
Ingress hosts |
See values.yaml |
ingress.tls |
TLS configuration |
See values.yaml |
Persistence Parameters
| Name |
Description |
Default |
persistence.enabled |
Enable persistence |
true |
persistence.existingClaim |
Use an existing PVC |
"" |
persistence.storageClass |
Storage class |
"" |
persistence.accessMode |
Access mode |
ReadWriteOnce |
persistence.size |
PVC size |
5Gi |
persistence.annotations |
PVC annotations |
{} |
Database Configuration (Required)
| Name |
Description |
Default |
database.host |
PostgreSQL host |
"" |
database.port |
PostgreSQL port |
5432 |
database.name |
Database name |
norish |
database.username |
Username |
postgres |
database.password |
Password |
"" |
database.existingSecret |
Existing secret name |
"" |
database.usernameKey |
Key for username in secret |
username |
database.passwordKey |
Key for password in secret |
password |
database.databaseKey |
Key for database name in secret |
database |
database.hostKey |
Key for host in secret |
"" |
Redis Configuration (Required)
| Name |
Description |
Default |
redis.host |
Redis host |
"" |
redis.port |
Redis port |
6379 |
redis.database |
Redis database number |
0 |
redis.username |
Redis username (6.0+) |
"" |
redis.password |
Redis password |
"" |
redis.existingSecret |
Existing secret name |
"" |
redis.urlKey |
Key for full Redis URL in secret |
redis-url |
redis.passwordKey |
Key for password in secret |
password |
Application Configuration
| Name |
Description |
Default |
config.authUrl |
Application URL (must match ingress) |
http://norish.domain.com |
config.logLevel |
Log level (trace, debug, info, warn, error, fatal) |
"" |
config.trustedOrigins |
Additional trusted origins (comma-separated) |
"" |
config.passwordAuthEnabled |
Enable/disable password auth |
"" |
config.extraEnv |
Extra environment variables |
[] |
Master Key Configuration (Required)
| Name |
Description |
Default |
config.masterKey.value |
32-byte base64 encryption key |
"" |
config.masterKey.existingSecret |
Existing secret name |
"" |
config.masterKey.secretKey |
Key in secret |
master-key |
Generate with: openssl rand -base64 32
OIDC Authentication
| Name |
Description |
Default |
config.auth.oidc.enabled |
Enable OIDC |
false |
config.auth.oidc.name |
Provider display name |
MyAuth |
config.auth.oidc.issuer |
OIDC issuer URL |
"" |
config.auth.oidc.clientId |
Client ID |
"" |
config.auth.oidc.clientSecret |
Client secret |
"" |
config.auth.oidc.wellKnown |
Well-known URL (optional) |
"" |
config.auth.oidc.existingSecret |
Existing secret name |
"" |
config.auth.oidc.clientIdKey |
Key for client ID in secret |
oidc-client-id |
config.auth.oidc.clientSecretKey |
Key for client secret in secret |
oidc-client-secret |
GitHub OAuth
| Name |
Description |
Default |
config.auth.github.enabled |
Enable GitHub OAuth |
false |
config.auth.github.clientId |
Client ID |
"" |
config.auth.github.clientSecret |
Client secret |
"" |
config.auth.github.existingSecret |
Existing secret name |
"" |
config.auth.github.clientIdKey |
Key for client ID in secret |
github-client-id |
config.auth.github.clientSecretKey |
Key for client secret in secret |
github-client-secret |
Google OAuth
| Name |
Description |
Default |
config.auth.google.enabled |
Enable Google OAuth |
false |
config.auth.google.clientId |
Client ID |
"" |
config.auth.google.clientSecret |
Client secret |
"" |
config.auth.google.existingSecret |
Existing secret name |
"" |
config.auth.google.clientIdKey |
Key for client ID in secret |
google-client-id |
config.auth.google.clientSecretKey |
Key for client secret in secret |
google-client-secret |
Chrome Headless Parameters
| Name |
Description |
Default |
chrome.enabled |
Enable Chrome sidecar |
true |
chrome.image.repository |
Chrome image repository |
zenika/alpine-chrome |
chrome.image.tag |
Chrome image tag |
latest |
chrome.image.pullPolicy |
Image pull policy |
IfNotPresent |
chrome.port |
Chrome debugging port |
9222 |
chrome.securityContext |
Chrome security context (requires root + SYS_ADMIN) |
See values.yaml |
chrome.resources |
Chrome resource limits |
{} |
Resource Parameters
| Name |
Description |
Default |
resources |
Resource limits and requests |
{} |
Health Check Parameters
| Name |
Description |
Default |
probes.startup.enabled |
Enable startup probe |
true |
probes.startup.initialDelaySeconds |
Startup initial delay |
10 |
probes.startup.periodSeconds |
Startup period |
10 |
probes.startup.failureThreshold |
Startup failure threshold |
30 |
probes.liveness.enabled |
Enable liveness probe |
true |
probes.liveness.initialDelaySeconds |
Liveness initial delay |
30 |
probes.liveness.periodSeconds |
Liveness period |
10 |
probes.readiness.enabled |
Enable readiness probe |
true |
probes.readiness.initialDelaySeconds |
Readiness initial delay |
5 |
probes.readiness.periodSeconds |
Readiness period |
5 |
Upgrading
From v0.13.x to v0.14.x
Breaking change: Redis is now required. Configure Redis before upgrading (see Redis Configuration).
From v0.14.x to v0.15.x
No configuration changes required. Redis, PostgreSQL, and Chrome headless are already configured. Back up your database before upgrading as a precaution.
Troubleshooting
- Master Key Not Set: Generate with
openssl rand -base64 32
- Login Failures: Password auth is enabled by default when no OAuth/OIDC is configured. Verify callback URLs match your ingress hostname.
- Database Connection Failed: Verify host, credentials, and that the database exists.
- Chrome Headless Issues: Chrome requires
SYS_ADMIN capability and 256Mi-512Mi memory. Check logs with kubectl logs -l app.kubernetes.io/name=norish -c chrome-headless
- Recipe Parsing Failures: Ensure Chrome is running.
CHROME_WS_ENDPOINT is automatically configured by the chart.
Links