mirror of
https://github.com/rtomik/helm-charts.git
synced 2026-04-05 17:50:38 +00:00
Compare commits
10 Commits
joplin-ser
...
paperless-
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cb45e3013 | |||
| e65df72663 | |||
| 33f865a892 | |||
| 2ecf4aeec0 | |||
| 720a81d343 | |||
| c9b25918d5 | |||
| c81bb1bbd1 | |||
| 741401a79d | |||
| 509492560e | |||
| af1ecd86cb |
@ -2,8 +2,8 @@ apiVersion: v2
|
||||
name: donetick
|
||||
description: Donetick helm chart for Kubernetes
|
||||
type: application
|
||||
version: 1.0.1
|
||||
appVersion: "v0.1.38"
|
||||
version: 1.0.4
|
||||
appVersion: "v0.1.60"
|
||||
maintainers:
|
||||
- name: Richard Tomik
|
||||
email: no@m.com
|
||||
|
||||
@ -27,12 +27,192 @@ $ helm install donetick donetick-chart/donetick
|
||||
|
||||
> **Tip**: List all releases using `helm list`
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Basic Installation with SQLite (Default)
|
||||
|
||||
```bash
|
||||
helm install donetick donetick-chart/donetick
|
||||
```
|
||||
|
||||
### Installation with External PostgreSQL
|
||||
|
||||
Create a values file for PostgreSQL configuration:
|
||||
|
||||
```yaml
|
||||
# values-postgres.yaml
|
||||
config:
|
||||
database:
|
||||
type: "postgres"
|
||||
host: "postgresql.database.svc.cluster.local"
|
||||
port: 5432
|
||||
user: "donetick"
|
||||
password: "your-secure-password"
|
||||
name: "donetick"
|
||||
migration: true
|
||||
|
||||
# Update JWT secret for production
|
||||
jwt:
|
||||
secret: "your-secure-jwt-secret-at-least-32-characters-long"
|
||||
|
||||
# Configure server settings
|
||||
server:
|
||||
cors_allow_origins:
|
||||
- "https://your-domain.com"
|
||||
- "http://localhost:5173"
|
||||
|
||||
# Enable features as needed
|
||||
features:
|
||||
notifications: true
|
||||
realtime: true
|
||||
oauth: false
|
||||
|
||||
# Enable ingress for external access
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: donetick.your-domain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: donetick-tls
|
||||
hosts:
|
||||
- donetick.your-domain.com
|
||||
|
||||
# Configure persistence
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: "fast-ssd"
|
||||
size: "5Gi"
|
||||
```
|
||||
|
||||
Install with PostgreSQL configuration:
|
||||
|
||||
```bash
|
||||
helm install donetick donetick-chart/donetick -f values-postgres.yaml
|
||||
```
|
||||
|
||||
### Production Installation with External Secrets
|
||||
|
||||
For production deployments, use Kubernetes secrets for sensitive data:
|
||||
|
||||
```yaml
|
||||
# values-production.yaml
|
||||
config:
|
||||
database:
|
||||
type: "postgres"
|
||||
host: "postgresql.database.svc.cluster.local"
|
||||
port: 5432
|
||||
name: "donetick"
|
||||
|
||||
# Use existing secret for postgres credentials
|
||||
database:
|
||||
type: "postgres"
|
||||
host: "postgresql.database.svc.cluster.local"
|
||||
port: 5432
|
||||
name: "donetick"
|
||||
secrets:
|
||||
existingSecret: "donetick-postgres-secret"
|
||||
userKey: "username"
|
||||
passwordKey: "password"
|
||||
|
||||
# Use existing secret for JWT
|
||||
jwt:
|
||||
existingSecret: "donetick-jwt-secret"
|
||||
secretKey: "jwt-secret"
|
||||
session_time: "168h"
|
||||
max_refresh: "168h"
|
||||
|
||||
# OAuth2 configuration with secrets
|
||||
oauth2:
|
||||
existingSecret: "donetick-oauth-secret"
|
||||
clientIdKey: "client-id"
|
||||
clientSecretKey: "client-secret"
|
||||
auth_url: "https://your-oauth-provider.com/auth"
|
||||
token_url: "https://your-oauth-provider.com/token"
|
||||
user_info_url: "https://your-oauth-provider.com/userinfo"
|
||||
redirect_url: "https://donetick.your-domain.com/auth/callback"
|
||||
|
||||
# Production server settings
|
||||
server:
|
||||
cors_allow_origins:
|
||||
- "https://donetick.your-domain.com"
|
||||
rate_limit: 100
|
||||
rate_period: "60s"
|
||||
|
||||
# Enable production features
|
||||
features:
|
||||
notifications: true
|
||||
realtime: true
|
||||
oauth: true
|
||||
|
||||
# Security context for production
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
|
||||
# Resource limits for production
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
# Ingress with TLS
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: donetick.your-domain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: donetick-tls
|
||||
hosts:
|
||||
- donetick.your-domain.com
|
||||
```
|
||||
|
||||
Create the required secrets:
|
||||
|
||||
```bash
|
||||
# Postgres secret
|
||||
kubectl create secret generic donetick-postgres-secret \
|
||||
--from-literal=username='donetick' \
|
||||
--from-literal=password='your-secure-db-password'
|
||||
|
||||
# JWT secret
|
||||
kubectl create secret generic donetick-jwt-secret \
|
||||
--from-literal=jwt-secret='your-very-secure-jwt-secret-at-least-32-characters-long'
|
||||
|
||||
# OAuth secret (if using OAuth)
|
||||
kubectl create secret generic donetick-oauth-secret \
|
||||
--from-literal=client-id='your-oauth-client-id' \
|
||||
--from-literal=client-secret='your-oauth-client-secret'
|
||||
```
|
||||
|
||||
Install with production configuration:
|
||||
|
||||
```bash
|
||||
helm install donetick donetick-chart/donetick -f values-production.yaml
|
||||
```
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
To uninstall/delete the `donetick` deployment:
|
||||
|
||||
```bash
|
||||
$ helm uninstall donetick
|
||||
helm uninstall donetick
|
||||
```
|
||||
|
||||
## Parameters
|
||||
@ -49,7 +229,7 @@ $ helm uninstall donetick
|
||||
| Name | Description | Value |
|
||||
|-------------------------|--------------------------------------------------------------------------------------|--------------------|
|
||||
| `image.repository` | Donetick image repository | `donetick/donetick` |
|
||||
| `image.tag` | Donetick image tag | `latest` |
|
||||
| `image.tag` | Donetick image tag | `v0.1.60` |
|
||||
| `image.pullPolicy` | Donetick image pull policy | `IfNotPresent` |
|
||||
| `imagePullSecrets` | Global Docker registry secret names as an array | `[]` |
|
||||
|
||||
@ -62,12 +242,9 @@ $ helm uninstall donetick
|
||||
| `config.oauth2.existingSecret` | Name of existing secret for OAuth2 credentials | `""` |
|
||||
| `config.oauth2.clientIdKey` | Key in the existing secret for OAuth2 client ID | `"client-id"` |
|
||||
| `config.oauth2.clientSecretKey` | Key in the existing secret for OAuth2 client secret | `"client-secret"` |
|
||||
| `config.database.existingSecret` | Name of existing secret for database credentials | `""` |
|
||||
| `config.database.hostKey` | Key in the existing secret for database host | `"db-host"` |
|
||||
| `config.database.portKey` | Key in the existing secret for database port | `"db-port"` |
|
||||
| `config.database.userKey` | Key in the existing secret for database user | `"db-user"` |
|
||||
| `config.database.passwordKey` | Key in the existing secret for database password | `"db-password"` |
|
||||
| `config.database.nameKey` | Key in the existing secret for database name | `"db-name"` |
|
||||
| `config.database.secrets.existingSecret` | Name of existing secret for postgres credentials | `""` |
|
||||
| `config.database.secrets.userKey` | Key in the existing secret for postgres username | `"username"` |
|
||||
| `config.database.secrets.passwordKey` | Key in the existing secret for postgres password | `"password"` |
|
||||
|
||||
### Deployment parameters
|
||||
|
||||
@ -90,7 +267,12 @@ $ helm uninstall donetick
|
||||
| `service.type` | Kubernetes Service type | `ClusterIP` |
|
||||
| `service.port` | Service HTTP port | `2021` |
|
||||
| `service.annotations` | Additional annotations for Service | `{}` |
|
||||
| `service.nodePort` | Service HTTP node port (when applicable) | `""` |
|
||||
|
||||
### Pod Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------|------------------------------------------------------|-------------|
|
||||
| `podAnnotations` | Additional annotations for pods | `{}` |
|
||||
|
||||
### Ingress parameters
|
||||
|
||||
@ -108,7 +290,174 @@ $ helm uninstall donetick
|
||||
|
||||
| Name | Description | Value |
|
||||
|-------------------------------|------------------------------------------------------|---------------|
|
||||
| `persistence.enabled` | Enable persistence using PVC | `true` |
|
||||
| `persistence.storageClass` | PVC Storage Class | `"longhorn"` |
|
||||
| `persistence.enabled` | Enable persistence using PVC | `false` |
|
||||
| `persistence.storageClass` | PVC Storage Class | `""` |
|
||||
| `persistence.accessMode` | PVC Access Mode | `ReadWriteOnce` |
|
||||
| `persistence.size` |
|
||||
| `persistence.size` | PVC Size | `1Gi` |
|
||||
|
||||
### Health Checks
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `probes.startup.enabled` | Enable startup probe | `true` |
|
||||
| `probes.startup.initialDelaySeconds` | Initial delay for startup probe | `10` |
|
||||
| `probes.startup.periodSeconds` | Period for startup probe | `10` |
|
||||
| `probes.startup.failureThreshold` | Failure threshold for startup probe | `30` |
|
||||
| `probes.liveness.enabled` | Enable liveness probe | `true` |
|
||||
| `probes.liveness.initialDelaySeconds` | Initial delay for liveness probe | `30` |
|
||||
| `probes.liveness.periodSeconds` | Period for liveness probe | `10` |
|
||||
| `probes.readiness.enabled` | Enable readiness probe | `true` |
|
||||
| `probes.readiness.initialDelaySeconds` | Initial delay for readiness probe | `5` |
|
||||
| `probes.readiness.periodSeconds` | Period for readiness probe | `5` |
|
||||
|
||||
### Application Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.name` | Application name | `selfhosted` |
|
||||
| `config.is_done_tick_dot_com` | Enable donetick.com features | `false` |
|
||||
| `config.is_user_creation_disabled` | Disable user registration | `false` |
|
||||
|
||||
### Real-time Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.realtime.max_connections` | Maximum WebSocket connections | `100` |
|
||||
| `config.realtime.ping_interval` | WebSocket ping interval | `30s` |
|
||||
| `config.realtime.pong_wait` | WebSocket pong wait timeout | `60s` |
|
||||
| `config.realtime.write_wait` | WebSocket write timeout | `10s` |
|
||||
| `config.realtime.max_message_size` | Maximum WebSocket message size | `512` |
|
||||
|
||||
### Database Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.database.type` | Database type (sqlite or postgres) | `sqlite` |
|
||||
| `config.database.migration` | Enable database migrations | `true` |
|
||||
| `config.database.host` | PostgreSQL host (when type=postgres) | `""` |
|
||||
| `config.database.port` | PostgreSQL port (when type=postgres) | `5432` |
|
||||
| `config.database.user` | PostgreSQL user (when type=postgres) | `""` |
|
||||
| `config.database.password` | PostgreSQL password (when type=postgres) | `""` |
|
||||
| `config.database.name` | PostgreSQL database name (when type=postgres) | `""` |
|
||||
|
||||
### JWT Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.jwt.secret` | JWT signing secret | `changeme-this-secret-should-be-at-least-32-characters-long` |
|
||||
| `config.jwt.session_time` | JWT session duration | `168h` |
|
||||
| `config.jwt.max_refresh` | JWT maximum refresh duration | `168h` |
|
||||
|
||||
### Server Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.server.port` | Server port | `2021` |
|
||||
| `config.server.read_timeout` | Server read timeout | `10s` |
|
||||
| `config.server.write_timeout` | Server write timeout | `10s` |
|
||||
| `config.server.rate_period` | Rate limiting period | `60s` |
|
||||
| `config.server.rate_limit` | Rate limiting requests per period | `300` |
|
||||
| `config.server.serve_frontend` | Serve frontend files | `true` |
|
||||
|
||||
### Feature Flags
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|------------------------------------------------------|---------------|
|
||||
| `config.features.notifications` | Enable notifications | `true` |
|
||||
| `config.features.realtime` | Enable real-time features | `true` |
|
||||
| `config.features.oauth` | Enable OAuth authentication | `false` |
|
||||
|
||||
## Database Setup
|
||||
|
||||
### PostgreSQL Requirements
|
||||
|
||||
When using PostgreSQL, ensure you have:
|
||||
|
||||
1. **Database Created**: Create a database for Donetick
|
||||
```sql
|
||||
CREATE DATABASE donetick;
|
||||
CREATE USER donetick WITH PASSWORD 'your-secure-password';
|
||||
GRANT ALL PRIVILEGES ON DATABASE donetick TO donetick;
|
||||
```
|
||||
|
||||
2. **Network Access**: Ensure Donetick can reach your PostgreSQL instance
|
||||
3. **Proper Credentials**: Configure database credentials in values or secrets
|
||||
|
||||
### Database Migration
|
||||
|
||||
Donetick automatically runs database migrations on startup when `config.database.migration: true`. For production:
|
||||
|
||||
1. **Review Migrations**: Check what migrations will be applied
|
||||
2. **Backup Database**: Always backup before running migrations
|
||||
3. **Monitor Startup**: Watch pod logs during initial deployment
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Real-time Configuration Panic
|
||||
**Error**: `Invalid real-time configuration: maxConnections must be positive, got 0`
|
||||
|
||||
**Solution**: Ensure the real-time configuration is properly set:
|
||||
```yaml
|
||||
config:
|
||||
realtime:
|
||||
max_connections: 100 # Must be > 0
|
||||
```
|
||||
|
||||
#### 2. Database Connection Issues
|
||||
**Error**: Database connection failures
|
||||
|
||||
**Solutions**:
|
||||
- Verify PostgreSQL is running and accessible
|
||||
- Check database credentials in secrets
|
||||
- Ensure database name exists
|
||||
- Verify network policies allow connection
|
||||
|
||||
#### 3. JWT Secret Issues
|
||||
**Error**: JWT authentication failures
|
||||
|
||||
**Solution**: Ensure JWT secret is at least 32 characters:
|
||||
```yaml
|
||||
config:
|
||||
jwt:
|
||||
secret: "your-very-secure-jwt-secret-at-least-32-characters-long"
|
||||
```
|
||||
|
||||
#### 4. CORS Issues
|
||||
**Error**: Cross-origin request blocked
|
||||
|
||||
**Solution**: Configure CORS origins:
|
||||
```yaml
|
||||
config:
|
||||
server:
|
||||
cors_allow_origins:
|
||||
- "https://your-domain.com"
|
||||
- "http://localhost:5173"
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
Check application logs:
|
||||
```bash
|
||||
kubectl logs deployment/donetick -f
|
||||
```
|
||||
|
||||
Check configuration:
|
||||
```bash
|
||||
kubectl get configmap donetick-configmap -o yaml
|
||||
```
|
||||
|
||||
Verify secrets:
|
||||
```bash
|
||||
kubectl get secret donetick-secrets -o yaml
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please feel free to contribute by opening issues or pull requests at:
|
||||
https://github.com/rtomik/helm-charts
|
||||
|
||||
## License
|
||||
|
||||
This Helm chart is licensed under the MIT License.
|
||||
|
||||
@ -22,15 +22,18 @@ data:
|
||||
{{- if .Values.config.database.migration_retry }}
|
||||
migration_retry: {{ .Values.config.database.migration_retry }}
|
||||
{{- end }}
|
||||
migration_timeout: {{ .Values.config.database.migration_timeout | default "300s" | quote }}
|
||||
{{- if eq .Values.config.database.type "postgres" }}
|
||||
{{- if not .Values.config.database.existingSecret }}
|
||||
host: {{ .Values.config.database.host | quote }}
|
||||
port: {{ .Values.config.database.port }}
|
||||
name: {{ .Values.config.database.name | quote }}
|
||||
{{- if not .Values.config.database.secrets.existingSecret }}
|
||||
user: {{ .Values.config.database.user | quote }}
|
||||
password: {{ .Values.config.database.password | quote }}
|
||||
name: {{ .Values.config.database.name | quote }}
|
||||
{{- else }}
|
||||
# Database credentials will be injected via environment variables from Secret
|
||||
# Reference environment variables for database credentials
|
||||
user: "$DT_DATABASE_USER"
|
||||
password: "$DT_DATABASE_PASSWORD"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
jwt:
|
||||
@ -74,4 +77,20 @@ data:
|
||||
token_url: {{ .Values.config.oauth2.token_url | default "" | quote }}
|
||||
user_info_url: {{ .Values.config.oauth2.user_info_url | default "" | quote }}
|
||||
redirect_url: {{ .Values.config.oauth2.redirect_url | default "" | quote }}
|
||||
name: {{ .Values.config.oauth2.name | default "" | quote }}
|
||||
name: {{ .Values.config.oauth2.name | default "" | quote }}
|
||||
realtime:
|
||||
max_connections: {{ .Values.config.realtime.max_connections }}
|
||||
ping_interval: {{ .Values.config.realtime.ping_interval | quote }}
|
||||
pong_wait: {{ .Values.config.realtime.pong_wait | quote }}
|
||||
write_wait: {{ .Values.config.realtime.write_wait | quote }}
|
||||
max_message_size: {{ .Values.config.realtime.max_message_size }}
|
||||
logging:
|
||||
level: {{ .Values.config.logging.level | quote }}
|
||||
format: {{ .Values.config.logging.format | quote }}
|
||||
storage:
|
||||
type: {{ .Values.config.storage.type | quote }}
|
||||
path: {{ .Values.config.storage.path | quote }}
|
||||
features:
|
||||
notifications: {{ .Values.config.features.notifications }}
|
||||
realtime: {{ .Values.config.features.realtime }}
|
||||
oauth: {{ .Values.config.features.oauth }}
|
||||
@ -50,6 +50,17 @@ spec:
|
||||
- name: http
|
||||
containerPort: {{ .Values.config.server.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.probes.startup.enabled }}
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.probes.startup.path }}
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probes.startup.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.probes.startup.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.probes.startup.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.probes.startup.failureThreshold }}
|
||||
successThreshold: {{ .Values.probes.startup.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.probes.liveness.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@ -77,15 +88,44 @@ spec:
|
||||
- name: {{ .name }}
|
||||
value: {{ .value | quote }}
|
||||
{{- end }}
|
||||
{{- if or .Values.config.jwt.existingSecret .Values.config.oauth2.existingSecret .Values.config.database.existingSecret }}
|
||||
# Secret-based environment variables
|
||||
# Database configuration environment variables
|
||||
{{- if eq .Values.config.database.type "postgres" }}
|
||||
- name: DT_DATABASE_TYPE
|
||||
value: "postgres"
|
||||
- name: DT_DATABASE_HOST
|
||||
value: {{ .Values.config.database.host | quote }}
|
||||
- name: DT_DATABASE_PORT
|
||||
value: {{ .Values.config.database.port | quote }}
|
||||
- name: DT_DATABASE_NAME
|
||||
value: {{ .Values.config.database.name | quote }}
|
||||
{{- if .Values.config.database.secrets.existingSecret }}
|
||||
- name: DT_DATABASE_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.secrets.existingSecret }}
|
||||
key: {{ .Values.config.database.secrets.userKey }}
|
||||
- name: DT_DATABASE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.secrets.existingSecret }}
|
||||
key: {{ .Values.config.database.secrets.passwordKey }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- name: DT_DATABASE_TYPE
|
||||
value: {{ .Values.config.database.type | quote }}
|
||||
{{- end }}
|
||||
# JWT configuration
|
||||
{{- if .Values.config.jwt.existingSecret }}
|
||||
- name: DT_JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.jwt.existingSecret }}
|
||||
key: {{ .Values.config.jwt.secretKey }}
|
||||
{{- else }}
|
||||
- name: DT_JWT_SECRET
|
||||
value: {{ .Values.config.jwt.secret | quote }}
|
||||
{{- end }}
|
||||
# OAuth2 configuration
|
||||
{{- if .Values.config.oauth2.existingSecret }}
|
||||
- name: DT_OAUTH2_CLIENT_ID
|
||||
valueFrom:
|
||||
@ -98,34 +138,6 @@ spec:
|
||||
name: {{ .Values.config.oauth2.existingSecret }}
|
||||
key: {{ .Values.config.oauth2.clientSecretKey }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config.database.existingSecret (eq .Values.config.database.type "postgres") }}
|
||||
- name: DT_DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.existingSecret }}
|
||||
key: {{ .Values.config.database.hostKey }}
|
||||
- name: DT_DB_PORT
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.existingSecret }}
|
||||
key: {{ .Values.config.database.portKey }}
|
||||
- name: DT_DB_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.existingSecret }}
|
||||
key: {{ .Values.config.database.userKey }}
|
||||
- name: DT_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.existingSecret }}
|
||||
key: {{ .Values.config.database.passwordKey }}
|
||||
- name: DT_DB_NAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.database.existingSecret }}
|
||||
key: {{ .Values.config.database.nameKey }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnv }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
@ -148,9 +160,14 @@ spec:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "donetick.fullname" . }}-configmap
|
||||
{{- if .Values.persistence.enabled }}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "donetick.fullname" . }}-data
|
||||
{{- else }}
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if not .Values.containerSecurityContext.readOnlyRootFilesystem }}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{{- if or (not .Values.config.jwt.existingSecret) (and (not .Values.config.oauth2.existingSecret) (or .Values.config.oauth2.client_id .Values.config.oauth2.client_secret)) (and (eq .Values.config.database.type "postgres") (not .Values.config.database.existingSecret)) }}
|
||||
{{- if or (not .Values.config.jwt.existingSecret) (and (not .Values.config.oauth2.existingSecret) (or .Values.config.oauth2.client_id .Values.config.oauth2.client_secret)) (and (eq .Values.config.database.type "postgres") (not .Values.config.database.secrets.existingSecret)) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@ -10,8 +10,8 @@ data:
|
||||
{{- if not .Values.config.jwt.existingSecret }}
|
||||
{{ .Values.config.jwt.secretKey }}: {{ .Values.config.jwt.secret | b64enc }}
|
||||
{{- end }}
|
||||
{{- if and (eq .Values.config.database.type "postgres") (not .Values.config.database.existingSecret) }}
|
||||
{{ .Values.config.database.passwordKey }}: {{ .Values.config.database.password | b64enc }}
|
||||
{{- if and (eq .Values.config.database.type "postgres") (not .Values.config.database.secrets.existingSecret) }}
|
||||
{{ .Values.config.database.secrets.passwordKey }}: {{ .Values.config.database.password | b64enc }}
|
||||
{{- end }}
|
||||
{{- if and (not .Values.config.oauth2.existingSecret) .Values.config.oauth2.client_id }}
|
||||
{{ .Values.config.oauth2.clientIdKey }}: {{ .Values.config.oauth2.client_id | b64enc }}
|
||||
|
||||
@ -4,6 +4,10 @@ metadata:
|
||||
name: {{ include "donetick.fullname" . }}
|
||||
labels:
|
||||
{{- include "donetick.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
|
||||
@ -5,8 +5,10 @@ fullnameOverride: ""
|
||||
## Image settings
|
||||
image:
|
||||
repository: donetick/donetick
|
||||
tag: "v0.1.38"
|
||||
tag: "v0.1.60"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
## Deployment settings
|
||||
replicaCount: 1
|
||||
@ -34,10 +36,14 @@ nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
## Pod annotations
|
||||
podAnnotations: {}
|
||||
|
||||
## Service settings
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 2021
|
||||
annotations: {}
|
||||
|
||||
## Ingress settings
|
||||
ingress:
|
||||
@ -85,16 +91,28 @@ extraVolumeMounts: []
|
||||
extraVolumes: []
|
||||
|
||||
## Resource limits and requests
|
||||
# resources:
|
||||
# limits:
|
||||
# cpu: 500m
|
||||
# memory: 512Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 500m
|
||||
# memory: 512Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
## Application health checks
|
||||
probes:
|
||||
startup:
|
||||
enabled: true
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 15
|
||||
failureThreshold: 80
|
||||
successThreshold: 1
|
||||
path: /health
|
||||
liveness:
|
||||
enabled: true
|
||||
initialDelaySeconds: 30
|
||||
@ -139,21 +157,18 @@ config:
|
||||
# Migration options
|
||||
migration_skip: false # Set to true to skip database migrations
|
||||
migration_retry: 3 # Number of retries for failed migrations
|
||||
|
||||
# These are only required for postgres - direct configuration
|
||||
migration_timeout: "600s" # Timeout for database migrations (default: 10 minutes)
|
||||
|
||||
# These are only required for postgres
|
||||
host: ""
|
||||
port: 5432
|
||||
user: ""
|
||||
password: ""
|
||||
name: ""
|
||||
|
||||
# Secret configuration for database credentials
|
||||
existingSecret: "" # Name of existing Kubernetes secret
|
||||
hostKey: "db-host" # Key in the secret for database host
|
||||
portKey: "db-port" # Key in the secret for database port
|
||||
userKey: "db-user" # Key in the secret for database user
|
||||
passwordKey: "db-password" # Key in the secret for database password
|
||||
nameKey: "db-name" # Key in the secret for database name
|
||||
|
||||
# Secret configuration for postgres credentials
|
||||
secrets:
|
||||
existingSecret: "" # Name of existing Kubernetes secret containing postgres credentials
|
||||
userKey: "username" # Key in the secret for database username
|
||||
passwordKey: "password" # Key in the secret for database password
|
||||
|
||||
# Security settings
|
||||
# For production, use a generated secret and store in a Kubernetes Secret
|
||||
@ -207,4 +222,28 @@ config:
|
||||
token_url: ""
|
||||
user_info_url: ""
|
||||
redirect_url: ""
|
||||
name: ""
|
||||
name: ""
|
||||
|
||||
# Real-time configuration
|
||||
realtime:
|
||||
max_connections: 100
|
||||
ping_interval: "30s"
|
||||
pong_wait: "60s"
|
||||
write_wait: "10s"
|
||||
max_message_size: 512
|
||||
|
||||
# Logging configuration
|
||||
logging:
|
||||
level: "info"
|
||||
format: "json"
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
type: "local"
|
||||
path: "/donetick-data/uploads"
|
||||
|
||||
# Feature flags
|
||||
features:
|
||||
notifications: true
|
||||
realtime: true
|
||||
oauth: false
|
||||
@ -2,8 +2,8 @@ apiVersion: v2
|
||||
name: mealie
|
||||
description: Mealie helm chart for Kubernetes - Recipe management and meal planning
|
||||
type: application
|
||||
version: 0.0.1
|
||||
appVersion: "v3.1.1"
|
||||
version: 0.0.2
|
||||
appVersion: "v3.2.1"
|
||||
maintainers:
|
||||
- name: Richard Tomik
|
||||
email: no@m.com
|
||||
|
||||
@ -18,4 +18,10 @@ spec:
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.selector }}
|
||||
{{- with .Values.persistence.selector }}
|
||||
selector:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@ -5,7 +5,7 @@ fullnameOverride: ""
|
||||
## Image settings
|
||||
image:
|
||||
repository: ghcr.io/mealie-recipes/mealie
|
||||
tag: "v3.1.1"
|
||||
tag: "v3.2.1"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
## Deployment settings
|
||||
|
||||
18
charts/paperless-ngx/Chart.yaml
Normal file
18
charts/paperless-ngx/Chart.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
apiVersion: v2
|
||||
name: paperless-ngx
|
||||
description: Paperless-ngx helm chart for Kubernetes
|
||||
type: application
|
||||
version: 0.0.2
|
||||
appVersion: "latest"
|
||||
maintainers:
|
||||
- name: Richard Tomik
|
||||
email: no@m.com
|
||||
keywords:
|
||||
- productivity
|
||||
- document-management
|
||||
- paperless
|
||||
- paperless-ngx
|
||||
- ocr
|
||||
home: https://github.com/rtomik/helm-charts
|
||||
sources:
|
||||
- https://github.com/paperless-ngx/paperless-ngx
|
||||
92
charts/paperless-ngx/NOTES.txt
Normal file
92
charts/paperless-ngx/NOTES.txt
Normal file
@ -0,0 +1,92 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "paperless-ngx.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "paperless-ngx.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "paperless-ngx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "paperless-ngx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8000 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8000:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
|
||||
2. Application is accessible at port {{ .Values.service.port }}
|
||||
|
||||
3. Paperless-ngx is configured with:
|
||||
- Database: PostgreSQL (external)
|
||||
- Redis: External service
|
||||
- OCR Language: {{ .Values.config.ocr.language }}
|
||||
- Time Zone: {{ .Values.config.timeZone }}
|
||||
|
||||
4. External Dependencies Required:
|
||||
- PostgreSQL server: {{ include "paperless-ngx.postgresql.host" . }}:{{ include "paperless-ngx.postgresql.port" . }}
|
||||
- Redis server: {{ include "paperless-ngx.redis.host" . }}:{{ include "paperless-ngx.redis.port" . }}
|
||||
|
||||
{{- if or .Values.persistence.data.enabled .Values.persistence.media.enabled .Values.persistence.consume.enabled .Values.persistence.export.enabled }}
|
||||
5. Persistent Storage:
|
||||
{{- if .Values.persistence.data.enabled }}
|
||||
- Data directory: {{ include "paperless-ngx.fullname" . }}-data ({{ .Values.persistence.data.size }})
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.media.enabled }}
|
||||
- Media directory: {{ include "paperless-ngx.fullname" . }}-media ({{ .Values.persistence.media.size }})
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.consume.enabled }}
|
||||
- Consume directory: {{ include "paperless-ngx.fullname" . }}-consume ({{ .Values.persistence.consume.size }})
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.export.enabled }}
|
||||
- Export directory: {{ include "paperless-ngx.fullname" . }}-export ({{ .Values.persistence.export.size }})
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
5. WARNING: No persistent storage enabled. Data will be lost when pods are restarted.
|
||||
Enable persistence in values.yaml for production use.
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.config.admin.user }}
|
||||
6. Admin User: {{ .Values.config.admin.user }}
|
||||
The admin user will be created automatically on first startup.
|
||||
{{- else }}
|
||||
6. No admin user configured. You'll need to create a superuser manually:
|
||||
kubectl exec -it deployment/{{ include "paperless-ngx.fullname" . }} -- python manage.py createsuperuser
|
||||
{{- end }}
|
||||
|
||||
{{- if or .Values.config.secretKey.existingSecret .Values.postgresql.external.existingSecret .Values.config.admin.existingSecret }}
|
||||
7. Using external secrets for sensitive information:
|
||||
{{- if .Values.config.secretKey.existingSecret }}
|
||||
- Secret key from: {{ .Values.config.secretKey.existingSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.postgresql.external.existingSecret }}
|
||||
- PostgreSQL password from: {{ .Values.postgresql.external.existingSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.config.admin.existingSecret }}
|
||||
- Admin credentials from: {{ .Values.config.admin.existingSecret }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
7. SECURITY NOTE: For production use, it's recommended to store sensitive data in Kubernetes Secrets.
|
||||
- Set config.secretKey.existingSecret to use an external secret for the secret key
|
||||
- Set postgresql.external.existingSecret to use an external secret for database credentials
|
||||
- Set config.admin.existingSecret to use an external secret for admin credentials
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.config.consumer.barcodes.enabled }}
|
||||
8. Barcode processing is enabled with scanner: {{ .Values.config.consumer.barcodeScanner }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.config.tika.enabled }}
|
||||
9. Tika integration is enabled for Office document processing
|
||||
- Tika endpoint: {{ .Values.config.tika.endpoint }}
|
||||
- Gotenberg endpoint: {{ .Values.config.tika.gotenbergEndpoint }}
|
||||
{{- end }}
|
||||
|
||||
For more information about using this Helm chart and Paperless-ngx configuration,
|
||||
please refer to the README.md file and the official Paperless-ngx documentation.
|
||||
313
charts/paperless-ngx/readme.md
Normal file
313
charts/paperless-ngx/readme.md
Normal file
@ -0,0 +1,313 @@
|
||||
# Paperless-ngx Helm Chart
|
||||
|
||||
A Helm chart for deploying Paperless-ngx document management system on Kubernetes.
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart deploys [Paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) on a Kubernetes cluster using the Helm package manager.
|
||||
|
||||
Paperless-ngx is a community-supported supercharged version of paperless: scan, index and archive all your physical documents.
|
||||
|
||||
Source code can be found here:
|
||||
- https://github.com/rtomik/helm-charts/tree/main/charts/paperless-ngx
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.19+
|
||||
- Helm 3.0+
|
||||
- PV provisioner support in the underlying infrastructure
|
||||
- **External PostgreSQL database** (required)
|
||||
- **External Redis server** (required)
|
||||
|
||||
## External Dependencies
|
||||
|
||||
This chart requires external PostgreSQL and Redis services. It does not deploy these dependencies to avoid resource conflicts on centralized servers.
|
||||
|
||||
### PostgreSQL Setup
|
||||
Paperless-ngx requires PostgreSQL 11+ as its database backend. Ensure you have:
|
||||
- A PostgreSQL database created for Paperless-ngx
|
||||
- Database credentials configured in values.yaml or via secrets
|
||||
|
||||
### Redis Setup
|
||||
Redis is required for background task processing. Ensure you have:
|
||||
- A Redis server accessible from the cluster
|
||||
- Connection details configured in values.yaml
|
||||
- Optional: Redis authentication credentials (username/password)
|
||||
- Optional: Redis key prefix for sharing one Redis server among multiple Paperless instances
|
||||
|
||||
The chart supports all Redis authentication methods:
|
||||
- No authentication: `redis://host:port/database`
|
||||
- Password only (requirepass): `redis://:password@host:port/database`
|
||||
- Username and password (Redis 6.0+ ACL): `redis://username:password@host:port/database`
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `paperless-ngx`:
|
||||
|
||||
```bash
|
||||
$ helm repo add paperless-chart https://rtomik.github.io/helm-charts
|
||||
$ helm install paperless-ngx paperless-chart/paperless-ngx
|
||||
```
|
||||
|
||||
Or install directly from this repository:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/rtomik/helm-charts.git
|
||||
$ cd helm-charts/charts/paperless-ngx
|
||||
$ helm install paperless-ngx .
|
||||
```
|
||||
|
||||
> **Tip**: List all releases using `helm list`
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters and their default values.
|
||||
|
||||
### Global Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|------------------------|-------------------------------------------------------------------------------------|-------|
|
||||
| `nameOverride` | String to partially override the release name | `""` |
|
||||
| `fullnameOverride` | String to fully override the release name | `""` |
|
||||
|
||||
### Image Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|-------------------------|--------------------------------------------------------------------------------------|--------------------|
|
||||
| `image.repository` | Paperless-ngx image repository | `ghcr.io/paperless-ngx/paperless-ngx` |
|
||||
| `image.tag` | Paperless-ngx image tag | `latest` |
|
||||
| `image.pullPolicy` | Paperless-ngx image pull policy | `IfNotPresent` |
|
||||
|
||||
### External Dependencies
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|--------------------------------------------------------------------|-------------------------------------------|
|
||||
| `postgresql.external.enabled` | Enable external PostgreSQL configuration | `true` |
|
||||
| `postgresql.external.host` | External PostgreSQL host | `postgresql.default.svc.cluster.local` |
|
||||
| `postgresql.external.port` | External PostgreSQL port | `5432` |
|
||||
| `postgresql.external.database` | External PostgreSQL database name | `paperless` |
|
||||
| `postgresql.external.username` | External PostgreSQL username | `paperless` |
|
||||
| `postgresql.external.existingSecret` | Existing secret with PostgreSQL credentials | `""` |
|
||||
| `postgresql.external.passwordKey` | Key in existing secret for PostgreSQL password | `postgresql-password` |
|
||||
| `redis.external.enabled` | Enable external Redis configuration | `true` |
|
||||
| `redis.external.host` | External Redis host | `redis.default.svc.cluster.local` |
|
||||
| `redis.external.port` | External Redis port | `6379` |
|
||||
| `redis.external.database` | External Redis database number | `0` |
|
||||
| `redis.external.username` | Redis username (Redis 6.0+ with ACL) | `""` |
|
||||
| `redis.external.password` | Redis password (leave empty if no auth required) | `""` |
|
||||
| `redis.external.existingSecret` | Existing secret with Redis credentials | `""` |
|
||||
| `redis.external.passwordKey` | Key in existing secret for Redis password | `redis-password` |
|
||||
| `redis.external.prefix` | Prefix for Redis keys/channels (for multi-instance) | `""` |
|
||||
|
||||
### Security Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|--------------------------------------------------------------------|---------------------|
|
||||
| `config.secretKey.existingSecret` | Name of existing secret for Django secret key | `""` |
|
||||
| `config.secretKey.secretKey` | Key in the existing secret for Django secret key | `secret-key` |
|
||||
| `config.admin.user` | Admin username to create on startup | `""` |
|
||||
| `config.admin.password` | Admin password (use existingSecret for production) | `""` |
|
||||
| `config.admin.email` | Admin email address | `root@localhost` |
|
||||
| `config.admin.existingSecret` | Name of existing secret for admin credentials | `""` |
|
||||
|
||||
### Application Configuration
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|--------------------------------------------------------------------|---------------------|
|
||||
| `config.url` | External URL for Paperless-ngx (e.g., https://paperless.domain.com) | `""` |
|
||||
| `config.allowedHosts` | Comma-separated list of allowed hosts | `*` |
|
||||
| `config.timeZone` | Application timezone | `UTC` |
|
||||
| `config.ocr.language` | OCR language (3-letter code) | `eng` |
|
||||
| `config.ocr.mode` | OCR mode (skip, redo, force) | `skip` |
|
||||
| `config.consumer.recursive` | Enable recursive consumption directory watching | `false` |
|
||||
| `config.consumer.subdirsAsTags` | Use subdirectory names as tags | `false` |
|
||||
|
||||
### Persistence Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------------------|--------------------------------------------------------------------|---------------------|
|
||||
| `persistence.data.enabled` | Enable persistence for data directory | `true` |
|
||||
| `persistence.data.size` | Size of data PVC | `1Gi` |
|
||||
| `persistence.media.enabled` | Enable persistence for media directory | `true` |
|
||||
| `persistence.media.size` | Size of media PVC | `10Gi` |
|
||||
| `persistence.consume.enabled` | Enable persistence for consume directory | `true` |
|
||||
| `persistence.consume.size` | Size of consume PVC | `5Gi` |
|
||||
| `persistence.export.enabled` | Enable persistence for export directory | `true` |
|
||||
| `persistence.export.size` | Size of export PVC | `1Gi` |
|
||||
|
||||
### Service Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------|------------------------------------------------------|-------------|
|
||||
| `service.type` | Kubernetes Service type | `ClusterIP` |
|
||||
| `service.port` | Service HTTP port | `8000` |
|
||||
|
||||
### Ingress Parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
|----------------------------|------------------------------------------------------|----------------------|
|
||||
| `ingress.enabled` | Enable ingress record generation | `false` |
|
||||
| `ingress.className` | IngressClass name | `""` |
|
||||
| `ingress.annotations` | Additional annotations for the Ingress resource | See values.yaml |
|
||||
| `ingress.hosts` | Array of host and path objects | See values.yaml |
|
||||
| `ingress.tls` | TLS configuration | See values.yaml |
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Installation
|
||||
|
||||
```bash
|
||||
helm install paperless-ngx . \
|
||||
--set postgresql.external.host=my-postgres.example.com \
|
||||
--set postgresql.external.password=secretpassword \
|
||||
--set redis.external.host=my-redis.example.com
|
||||
```
|
||||
|
||||
### Production Installation with External Secrets
|
||||
|
||||
```yaml
|
||||
# values-production.yaml
|
||||
config:
|
||||
url: "https://paperless.example.com"
|
||||
allowedHosts: "paperless.example.com"
|
||||
secretKey:
|
||||
existingSecret: "paperless-secrets"
|
||||
secretKey: "django-secret-key"
|
||||
admin:
|
||||
user: "admin"
|
||||
existingSecret: "paperless-admin-secrets"
|
||||
|
||||
postgresql:
|
||||
# External PostgreSQL connection details
|
||||
external:
|
||||
enabled: true
|
||||
host: "postgres-cluster-pooler.dbs.svc.cluster.local"
|
||||
port: 5432
|
||||
database: "paperless"
|
||||
username: "paperless"
|
||||
# Use existingSecret for credentials
|
||||
existingSecret: "paperless-db-credentials"
|
||||
passwordKey: "password"
|
||||
|
||||
redis:
|
||||
external:
|
||||
host: "redis.cache.svc.cluster.local"
|
||||
port: 6379
|
||||
database: 0
|
||||
# Use existingSecret for Redis credentials
|
||||
existingSecret: "paperless-redis-credentials"
|
||||
passwordKey: "password"
|
||||
# Optional: Use prefix to share Redis among multiple instances
|
||||
prefix: "paperless-prod"
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
hosts:
|
||||
- host: paperless.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: paperless-tls
|
||||
hosts:
|
||||
- paperless.example.com
|
||||
```
|
||||
|
||||
```bash
|
||||
helm install paperless-ngx . -f values-production.yaml
|
||||
```
|
||||
|
||||
### Redis Authentication Examples
|
||||
|
||||
#### Redis with Password Only (requirepass)
|
||||
|
||||
```bash
|
||||
helm install paperless-ngx . \
|
||||
--set redis.external.host=redis.example.com \
|
||||
--set redis.external.password=myredispassword
|
||||
```
|
||||
|
||||
Or with existing secret:
|
||||
|
||||
```yaml
|
||||
redis:
|
||||
external:
|
||||
host: "redis.example.com"
|
||||
existingSecret: "redis-auth-secret"
|
||||
passwordKey: "redis-password"
|
||||
```
|
||||
|
||||
#### Redis with Username and Password (Redis 6.0+ ACL)
|
||||
|
||||
```bash
|
||||
helm install paperless-ngx . \
|
||||
--set redis.external.host=redis.example.com \
|
||||
--set redis.external.username=paperless-user \
|
||||
--set redis.external.password=myredispassword
|
||||
```
|
||||
|
||||
#### Multiple Paperless Instances on One Redis Server
|
||||
|
||||
Use the `prefix` parameter to avoid key collisions:
|
||||
|
||||
```yaml
|
||||
# Instance 1
|
||||
redis:
|
||||
external:
|
||||
host: "shared-redis.example.com"
|
||||
password: "sharedpassword"
|
||||
prefix: "paperless-prod"
|
||||
|
||||
# Instance 2
|
||||
redis:
|
||||
external:
|
||||
host: "shared-redis.example.com"
|
||||
password: "sharedpassword"
|
||||
prefix: "paperless-staging"
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Use external secrets** for production deployments to store sensitive data like database passwords, Redis passwords, and the Django secret key.
|
||||
2. **Set a proper PAPERLESS_URL** when exposing the application externally.
|
||||
3. **Configure ALLOWED_HOSTS** to restrict which hosts can access the application.
|
||||
4. **Use HTTPS** when exposing the application to the internet.
|
||||
5. **Secure Redis**: Always use authentication (password or username/password) for Redis in production environments. Use `existingSecret` instead of plain text passwords.
|
||||
6. **Container Security**: The container runs as root initially to allow s6-overlay to set up the runtime environment, then drops privileges to UID 1000. This is required for the Paperless-ngx Docker image to function properly.
|
||||
|
||||
## Volumes and Data
|
||||
|
||||
Paperless-ngx uses several directories:
|
||||
|
||||
- **Data directory**: Contains the search index, classification model, and SQLite database (if used)
|
||||
- **Media directory**: Contains all uploaded documents and thumbnails
|
||||
- **Consume directory**: Drop documents here for automatic processing
|
||||
- **Export directory**: Used for document exports
|
||||
|
||||
All directories can be configured with separate PVCs and storage classes.
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
To uninstall/delete the `paperless-ngx` deployment:
|
||||
|
||||
```bash
|
||||
helm uninstall paperless-ngx
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please feel free to contribute by opening issues or pull requests at:
|
||||
https://github.com/rtomik/helm-charts
|
||||
|
||||
## License
|
||||
|
||||
This Helm chart is licensed under the MIT License.
|
||||
|
||||
## Links
|
||||
|
||||
- [Paperless-ngx Documentation](https://docs.paperless-ngx.com/)
|
||||
- [Paperless-ngx GitHub Repository](https://github.com/paperless-ngx/paperless-ngx)
|
||||
- [Docker Hub](https://hub.docker.com/r/ghcr.io/paperless-ngx/paperless-ngx)
|
||||
109
charts/paperless-ngx/templates/_helpers.tpl
Normal file
109
charts/paperless-ngx/templates/_helpers.tpl
Normal file
@ -0,0 +1,109 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "paperless-ngx.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
*/}}
|
||||
{{- define "paperless-ngx.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- printf "%s" $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "paperless-ngx.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "paperless-ngx.labels" -}}
|
||||
helm.sh/chart: {{ include "paperless-ngx.chart" . }}
|
||||
{{ include "paperless-ngx.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "paperless-ngx.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "paperless-ngx.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL host
|
||||
*/}}
|
||||
{{- define "paperless-ngx.postgresql.host" -}}
|
||||
{{- if .Values.postgresql.external.enabled }}
|
||||
{{- .Values.postgresql.external.host }}
|
||||
{{- else }}
|
||||
{{- printf "%s-postgresql" (include "paperless-ngx.fullname" .) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL port
|
||||
*/}}
|
||||
{{- define "paperless-ngx.postgresql.port" -}}
|
||||
{{- if .Values.postgresql.external.enabled }}
|
||||
{{- .Values.postgresql.external.port | toString }}
|
||||
{{- else }}
|
||||
{{- "5432" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis host
|
||||
*/}}
|
||||
{{- define "paperless-ngx.redis.host" -}}
|
||||
{{- if .Values.redis.external.enabled }}
|
||||
{{- .Values.redis.external.host }}
|
||||
{{- else }}
|
||||
{{- printf "%s-redis" (include "paperless-ngx.fullname" .) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis port
|
||||
*/}}
|
||||
{{- define "paperless-ngx.redis.port" -}}
|
||||
{{- if .Values.redis.external.enabled }}
|
||||
{{- .Values.redis.external.port | toString }}
|
||||
{{- else }}
|
||||
{{- "6379" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis URL
|
||||
Constructs the Redis URL with optional authentication.
|
||||
Format: redis://[username]:[password]@host:port/database
|
||||
*/}}
|
||||
{{- define "paperless-ngx.redis.url" -}}
|
||||
{{- $host := include "paperless-ngx.redis.host" . }}
|
||||
{{- $port := include "paperless-ngx.redis.port" . }}
|
||||
{{- $database := .Values.redis.external.database | toString }}
|
||||
{{- $username := .Values.redis.external.username | default "" }}
|
||||
{{- $password := .Values.redis.external.password | default "" }}
|
||||
{{- if and $username $password }}
|
||||
{{- printf "redis://%s:%s@%s:%s/%s" $username $password $host $port $database }}
|
||||
{{- else if $password }}
|
||||
{{- printf "redis://:%s@%s:%s/%s" $password $host $port $database }}
|
||||
{{- else }}
|
||||
{{- printf "redis://%s:%s/%s" $host $port $database }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
13
charts/paperless-ngx/templates/configmap.yaml
Normal file
13
charts/paperless-ngx/templates/configmap.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-configmap
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
data:
|
||||
# Additional configuration files can be added here if needed
|
||||
# Most Paperless-ngx configuration is handled via environment variables
|
||||
README.txt: |
|
||||
This ConfigMap can be used to store additional configuration files
|
||||
for Paperless-ngx if needed. The main configuration is handled via
|
||||
environment variables in the deployment.
|
||||
370
charts/paperless-ngx/templates/deployment.yaml
Normal file
370
charts/paperless-ngx/templates/deployment.yaml
Normal file
@ -0,0 +1,370 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "paperless-ngx.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
maxSurge: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "paperless-ngx.selectorLabels" . | nindent 8 }}
|
||||
annotations:
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
{{- if .Values.probes.liveness.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.probes.liveness.path }}
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
|
||||
successThreshold: {{ .Values.probes.liveness.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.probes.readiness.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: {{ .Values.probes.readiness.path }}
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
|
||||
successThreshold: {{ .Values.probes.readiness.successThreshold }}
|
||||
{{- end }}
|
||||
env:
|
||||
# Required services
|
||||
- name: PAPERLESS_REDIS
|
||||
value: {{ include "paperless-ngx.redis.url" . | quote }}
|
||||
{{- if .Values.redis.external.prefix }}
|
||||
- name: PAPERLESS_REDIS_PREFIX
|
||||
value: {{ .Values.redis.external.prefix | quote }}
|
||||
{{- end }}
|
||||
- name: PAPERLESS_DBHOST
|
||||
value: {{ include "paperless-ngx.postgresql.host" . | quote }}
|
||||
- name: PAPERLESS_DBPORT
|
||||
value: {{ include "paperless-ngx.postgresql.port" . | quote }}
|
||||
- name: PAPERLESS_DBNAME
|
||||
value: {{ .Values.postgresql.external.database | quote }}
|
||||
- name: PAPERLESS_DBUSER
|
||||
value: {{ .Values.postgresql.external.username | quote }}
|
||||
|
||||
# Database password from secret
|
||||
- name: PAPERLESS_DBPASS
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.postgresql.external.existingSecret | default (printf "%s-secrets" (include "paperless-ngx.fullname" .)) }}
|
||||
key: {{ .Values.postgresql.external.passwordKey | default "postgresql-password" }}
|
||||
|
||||
# Security
|
||||
- name: PAPERLESS_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.secretKey.existingSecret | default (printf "%s-secrets" (include "paperless-ngx.fullname" .)) }}
|
||||
key: {{ .Values.config.secretKey.secretKey | default "secret-key" }}
|
||||
|
||||
# Basic configuration
|
||||
{{- if .Values.config.url }}
|
||||
- name: PAPERLESS_URL
|
||||
value: {{ .Values.config.url | quote }}
|
||||
{{- end }}
|
||||
- name: PAPERLESS_ALLOWED_HOSTS
|
||||
value: {{ .Values.config.allowedHosts | quote }}
|
||||
{{- if .Values.config.csrfTrustedOrigins }}
|
||||
- name: PAPERLESS_CSRF_TRUSTED_ORIGINS
|
||||
value: {{ .Values.config.csrfTrustedOrigins | quote }}
|
||||
{{- end }}
|
||||
- name: PAPERLESS_CORS_ALLOWED_HOSTS
|
||||
value: {{ .Values.config.corsAllowedHosts | quote }}
|
||||
{{- if .Values.config.forceScriptName }}
|
||||
- name: PAPERLESS_FORCE_SCRIPT_NAME
|
||||
value: {{ .Values.config.forceScriptName | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Paths
|
||||
- name: PAPERLESS_DATA_DIR
|
||||
value: "/usr/src/paperless/data"
|
||||
- name: PAPERLESS_MEDIA_ROOT
|
||||
value: "/usr/src/paperless/media"
|
||||
- name: PAPERLESS_CONSUMPTION_DIR
|
||||
value: "/usr/src/paperless/consume"
|
||||
|
||||
# Docker/User settings (s6-overlay compatible)
|
||||
- name: USERMAP_UID
|
||||
value: "1000"
|
||||
- name: USERMAP_GID
|
||||
value: "1000"
|
||||
|
||||
# OCR settings
|
||||
- name: PAPERLESS_OCR_LANGUAGE
|
||||
value: {{ .Values.config.ocr.language | quote }}
|
||||
- name: PAPERLESS_OCR_MODE
|
||||
value: {{ .Values.config.ocr.mode | quote }}
|
||||
- name: PAPERLESS_OCR_SKIP_ARCHIVE_FILE
|
||||
value: {{ .Values.config.ocr.skipArchiveFile | quote }}
|
||||
- name: PAPERLESS_OCR_CLEAN
|
||||
value: {{ .Values.config.ocr.clean | quote }}
|
||||
- name: PAPERLESS_OCR_DESKEW
|
||||
value: {{ .Values.config.ocr.deskew | quote }}
|
||||
- name: PAPERLESS_OCR_ROTATE_PAGES
|
||||
value: {{ .Values.config.ocr.rotatePages | quote }}
|
||||
- name: PAPERLESS_OCR_ROTATE_PAGES_THRESHOLD
|
||||
value: {{ .Values.config.ocr.rotatePagesThreshold | quote }}
|
||||
- name: PAPERLESS_OCR_OUTPUT_TYPE
|
||||
value: {{ .Values.config.ocr.outputType | quote }}
|
||||
{{- if ne (.Values.config.ocr.pages | int) 0 }}
|
||||
- name: PAPERLESS_OCR_PAGES
|
||||
value: {{ .Values.config.ocr.pages | quote }}
|
||||
{{- end }}
|
||||
{{- if ne (.Values.config.ocr.imageDpi | int) 0 }}
|
||||
- name: PAPERLESS_OCR_IMAGE_DPI
|
||||
value: {{ .Values.config.ocr.imageDpi | quote }}
|
||||
{{- end }}
|
||||
{{- if ne (.Values.config.ocr.maxImagePixels | int) 0 }}
|
||||
- name: PAPERLESS_OCR_MAX_IMAGE_PIXELS
|
||||
value: {{ .Values.config.ocr.maxImagePixels | quote }}
|
||||
{{- end }}
|
||||
{{- if ne .Values.config.ocr.userArgs "{}" }}
|
||||
- name: PAPERLESS_OCR_USER_ARGS
|
||||
value: {{ .Values.config.ocr.userArgs | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Time and locale
|
||||
- name: PAPERLESS_TIME_ZONE
|
||||
value: {{ .Values.config.timeZone | quote }}
|
||||
|
||||
# Consumer settings
|
||||
- name: PAPERLESS_CONSUMER_RECURSIVE
|
||||
value: {{ .Values.config.consumer.recursive | quote }}
|
||||
- name: PAPERLESS_CONSUMER_SUBDIRS_AS_TAGS
|
||||
value: {{ .Values.config.consumer.subdirsAsTags | quote }}
|
||||
- name: PAPERLESS_CONSUMER_DELETE_DUPLICATES
|
||||
value: {{ .Values.config.consumer.deleteDocumentDuplicates | quote }}
|
||||
- name: PAPERLESS_CONSUMER_IGNORE_PATTERNS
|
||||
value: {{ .Values.config.consumer.ignorePatterns | quote }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_SCANNER
|
||||
value: {{ .Values.config.consumer.barcodeScanner | quote }}
|
||||
|
||||
# Barcode settings
|
||||
{{- if .Values.config.consumer.barcodes.enabled }}
|
||||
- name: PAPERLESS_CONSUMER_ENABLE_BARCODES
|
||||
value: "true"
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_TIFF_SUPPORT
|
||||
value: {{ .Values.config.consumer.barcodes.tiffSupport | quote }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_STRING
|
||||
value: {{ .Values.config.consumer.barcodes.string | quote }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_RETAIN_SPLIT_PAGES
|
||||
value: {{ .Values.config.consumer.barcodes.retainSplitPages | quote }}
|
||||
{{- if ne (.Values.config.consumer.barcodes.upscale | float64) 0.0 }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_UPSCALE
|
||||
value: {{ .Values.config.consumer.barcodes.upscale | quote }}
|
||||
{{- end }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_DPI
|
||||
value: {{ .Values.config.consumer.barcodes.dpi | quote }}
|
||||
{{- if ne (.Values.config.consumer.barcodes.maxPages | int) 0 }}
|
||||
- name: PAPERLESS_CONSUMER_BARCODE_MAX_PAGES
|
||||
value: {{ .Values.config.consumer.barcodes.maxPages | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
# ASN barcode settings
|
||||
{{- if .Values.config.consumer.barcodes.asnEnabled }}
|
||||
- name: PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE
|
||||
value: "true"
|
||||
- name: PAPERLESS_CONSUMER_ASN_BARCODE_PREFIX
|
||||
value: {{ .Values.config.consumer.barcodes.asnPrefix | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Tag barcode settings
|
||||
{{- if .Values.config.consumer.barcodes.tagEnabled }}
|
||||
- name: PAPERLESS_CONSUMER_ENABLE_TAG_BARCODE
|
||||
value: "true"
|
||||
- name: PAPERLESS_CONSUMER_TAG_BARCODE_MAPPING
|
||||
value: {{ .Values.config.consumer.barcodes.tagMapping | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Tika settings
|
||||
{{- if .Values.config.tika.enabled }}
|
||||
- name: PAPERLESS_TIKA_ENABLED
|
||||
value: "true"
|
||||
- name: PAPERLESS_TIKA_ENDPOINT
|
||||
value: {{ .Values.config.tika.endpoint | quote }}
|
||||
- name: PAPERLESS_TIKA_GOTENBERG_ENDPOINT
|
||||
value: {{ .Values.config.tika.gotenbergEndpoint | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Admin user
|
||||
{{- if .Values.config.admin.user }}
|
||||
- name: PAPERLESS_ADMIN_USER
|
||||
value: {{ .Values.config.admin.user | quote }}
|
||||
- name: PAPERLESS_ADMIN_MAIL
|
||||
value: {{ .Values.config.admin.email | quote }}
|
||||
- name: PAPERLESS_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.admin.existingSecret | default (printf "%s-secrets" (include "paperless-ngx.fullname" .)) }}
|
||||
key: {{ .Values.config.admin.passwordKey | default "admin-password" }}
|
||||
{{- end }}
|
||||
|
||||
# Email settings
|
||||
{{- if .Values.config.email.host }}
|
||||
- name: PAPERLESS_EMAIL_HOST
|
||||
value: {{ .Values.config.email.host | quote }}
|
||||
- name: PAPERLESS_EMAIL_PORT
|
||||
value: {{ .Values.config.email.port | quote }}
|
||||
{{- if .Values.config.email.user }}
|
||||
- name: PAPERLESS_EMAIL_HOST_USER
|
||||
value: {{ .Values.config.email.user | quote }}
|
||||
- name: PAPERLESS_EMAIL_HOST_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.config.email.existingSecret | default (printf "%s-secrets" (include "paperless-ngx.fullname" .)) }}
|
||||
key: {{ .Values.config.email.passwordKey | default "email-password" }}
|
||||
{{- end }}
|
||||
{{- if .Values.config.email.from }}
|
||||
- name: PAPERLESS_EMAIL_FROM
|
||||
value: {{ .Values.config.email.from | quote }}
|
||||
{{- end }}
|
||||
- name: PAPERLESS_EMAIL_USE_TLS
|
||||
value: {{ .Values.config.email.useTls | quote }}
|
||||
- name: PAPERLESS_EMAIL_USE_SSL
|
||||
value: {{ .Values.config.email.useSsl | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Task processing
|
||||
- name: PAPERLESS_TASK_WORKERS
|
||||
value: {{ .Values.config.taskWorkers | quote }}
|
||||
- name: PAPERLESS_THREADS_PER_WORKER
|
||||
value: {{ .Values.config.threadsPerWorker | quote }}
|
||||
- name: PAPERLESS_WORKER_TIMEOUT
|
||||
value: {{ .Values.config.workerTimeout | quote }}
|
||||
|
||||
# Advanced settings
|
||||
- name: PAPERLESS_ENABLE_NLTK
|
||||
value: {{ .Values.config.enableNltk | quote }}
|
||||
{{- if .Values.config.filenameFormat }}
|
||||
- name: PAPERLESS_FILENAME_FORMAT
|
||||
value: {{ .Values.config.filenameFormat | quote }}
|
||||
- name: PAPERLESS_FILENAME_FORMAT_REMOVE_NONE
|
||||
value: {{ .Values.config.filenameFormatRemoveNone | quote }}
|
||||
{{- end }}
|
||||
{{- if ne (.Values.config.convertMemoryLimit | int) 0 }}
|
||||
- name: PAPERLESS_CONVERT_MEMORY_LIMIT
|
||||
value: {{ .Values.config.convertMemoryLimit | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.config.convertTmpDir }}
|
||||
- name: PAPERLESS_CONVERT_TMPDIR
|
||||
value: {{ .Values.config.convertTmpDir | quote }}
|
||||
{{- end }}
|
||||
{{- if ne (.Values.config.maxImagePixels | int) 0 }}
|
||||
- name: PAPERLESS_MAX_IMAGE_PIXELS
|
||||
value: {{ .Values.config.maxImagePixels | quote }}
|
||||
{{- end }}
|
||||
|
||||
# Custom environment variables
|
||||
{{- range .Values.env }}
|
||||
- name: {{ .name }}
|
||||
value: {{ .value | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnv }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/src/paperless/data
|
||||
- name: media
|
||||
mountPath: /usr/src/paperless/media
|
||||
- name: export
|
||||
mountPath: /usr/src/paperless/export
|
||||
- name: consume
|
||||
mountPath: /usr/src/paperless/consume
|
||||
{{- with .Values.extraVolumeMounts }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumes:
|
||||
{{- if .Values.persistence.data.enabled }}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "paperless-ngx.fullname" . }}-data
|
||||
{{- else }}
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.media.enabled }}
|
||||
- name: media
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "paperless-ngx.fullname" . }}-media
|
||||
{{- else }}
|
||||
- name: media
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.export.enabled }}
|
||||
- name: export
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "paperless-ngx.fullname" . }}-export
|
||||
{{- else }}
|
||||
- name: export
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.persistence.consume.enabled }}
|
||||
- name: consume
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "paperless-ngx.fullname" . }}-consume
|
||||
{{- else }}
|
||||
- name: consume
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- with .Values.extraVolumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
43
charts/paperless-ngx/templates/ingress.yaml
Normal file
43
charts/paperless-ngx/templates/ingress.yaml
Normal file
@ -0,0 +1,43 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- if .secretName }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "paperless-ngx.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
90
charts/paperless-ngx/templates/pvc.yaml
Normal file
90
charts/paperless-ngx/templates/pvc.yaml
Normal file
@ -0,0 +1,90 @@
|
||||
{{- if .Values.persistence.data.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-data
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.data.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.data.accessMode | quote }}
|
||||
{{- if .Values.persistence.data.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.data.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.data.size | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.persistence.media.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-media
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.media.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.media.accessMode | quote }}
|
||||
{{- if .Values.persistence.media.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.media.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.media.size | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.persistence.export.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-export
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.export.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.export.accessMode | quote }}
|
||||
{{- if .Values.persistence.export.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.export.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.export.size | quote }}
|
||||
---
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.persistence.consume.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-consume
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.consume.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.consume.accessMode | quote }}
|
||||
{{- if .Values.persistence.consume.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.consume.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.consume.size | quote }}
|
||||
{{- end }}
|
||||
44
charts/paperless-ngx/templates/secret.yaml
Normal file
44
charts/paperless-ngx/templates/secret.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
{{- $needsSecret := false -}}
|
||||
{{- if not .Values.config.secretKey.existingSecret -}}
|
||||
{{- $needsSecret = true -}}
|
||||
{{- end -}}
|
||||
{{- if not .Values.postgresql.external.existingSecret -}}
|
||||
{{- $needsSecret = true -}}
|
||||
{{- end -}}
|
||||
{{- if and .Values.redis.external.password (not .Values.redis.external.existingSecret) -}}
|
||||
{{- $needsSecret = true -}}
|
||||
{{- end -}}
|
||||
{{- if and .Values.config.admin.user (not .Values.config.admin.existingSecret) -}}
|
||||
{{- $needsSecret = true -}}
|
||||
{{- end -}}
|
||||
{{- if and .Values.config.email.host .Values.config.email.user (not .Values.config.email.existingSecret) -}}
|
||||
{{- $needsSecret = true -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $needsSecret }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}-secrets
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{- if not .Values.config.secretKey.existingSecret }}
|
||||
{{ .Values.config.secretKey.secretKey | default "secret-key" }}: {{ .Values.config.secretKey.value | default "change-me-paperless-secret-key-at-least-32-characters-long" | b64enc }}
|
||||
{{- end }}
|
||||
{{- if not .Values.postgresql.external.existingSecret }}
|
||||
{{ .Values.postgresql.external.passwordKey | default "postgresql-password" }}: {{ .Values.postgresql.external.password | default "paperless" | b64enc }}
|
||||
{{- end }}
|
||||
{{- if and .Values.redis.external.password (not .Values.redis.external.existingSecret) }}
|
||||
{{ .Values.redis.external.passwordKey | default "redis-password" }}: {{ .Values.redis.external.password | b64enc }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config.admin.user (not .Values.config.admin.existingSecret) }}
|
||||
{{ .Values.config.admin.userKey | default "admin-user" }}: {{ .Values.config.admin.user | b64enc }}
|
||||
{{ .Values.config.admin.passwordKey | default "admin-password" }}: {{ .Values.config.admin.password | default "changeme" | b64enc }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config.email.host .Values.config.email.user (not .Values.config.email.existingSecret) }}
|
||||
{{ .Values.config.email.userKey | default "email-user" }}: {{ .Values.config.email.user | b64enc }}
|
||||
{{ .Values.config.email.passwordKey | default "email-password" }}: {{ .Values.config.email.password | default "" | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
charts/paperless-ngx/templates/service.yaml
Normal file
15
charts/paperless-ngx/templates/service.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "paperless-ngx.fullname" . }}
|
||||
labels:
|
||||
{{- include "paperless-ngx.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "paperless-ngx.selectorLabels" . | nindent 4 }}
|
||||
294
charts/paperless-ngx/values.yaml
Normal file
294
charts/paperless-ngx/values.yaml
Normal file
@ -0,0 +1,294 @@
|
||||
## Global settings
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
## Image settings
|
||||
image:
|
||||
repository: ghcr.io/paperless-ngx/paperless-ngx
|
||||
tag: "2.18.4"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
## Deployment settings
|
||||
replicaCount: 1
|
||||
revisionHistoryLimit: 3
|
||||
|
||||
# Pod security settings
|
||||
# Note: Paperless-ngx uses s6-overlay which requires root access during initialization
|
||||
# The container will drop privileges after setup
|
||||
podSecurityContext:
|
||||
runAsNonRoot: false
|
||||
runAsUser: 0
|
||||
fsGroup: 1000
|
||||
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
- FOWNER
|
||||
- SETGID
|
||||
- SETUID
|
||||
|
||||
## Pod scheduling
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
## Service settings
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8000
|
||||
|
||||
## Ingress settings
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
hosts:
|
||||
- host: paperless.domain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- hosts:
|
||||
- paperless.domain.com
|
||||
# Optional: specify the name of an existing TLS secret
|
||||
# secretName: "existing-tls-secret"
|
||||
|
||||
## Persistence settings
|
||||
persistence:
|
||||
# Paperless data directory (search index, classification model, etc.)
|
||||
data:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
accessMode: ReadWriteOnce
|
||||
size: 1Gi
|
||||
annotations: {}
|
||||
# Paperless media directory (documents and thumbnails)
|
||||
media:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
accessMode: ReadWriteOnce
|
||||
size: 10Gi
|
||||
annotations: {}
|
||||
# Export directory (for exporting documents)
|
||||
export:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
accessMode: ReadWriteOnce
|
||||
size: 1Gi
|
||||
annotations: {}
|
||||
# Consume directory (for importing documents)
|
||||
consume:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
accessMode: ReadWriteOnce
|
||||
size: 5Gi
|
||||
annotations: {}
|
||||
|
||||
# Extra volume mounts
|
||||
extraVolumeMounts: []
|
||||
|
||||
# Extra volumes
|
||||
extraVolumes: []
|
||||
|
||||
## Resource limits and requests
|
||||
# resources:
|
||||
# limits:
|
||||
# cpu: 1000m
|
||||
# memory: 1Gi
|
||||
# requests:
|
||||
# cpu: 200m
|
||||
# memory: 512Mi
|
||||
|
||||
## Application health checks
|
||||
probes:
|
||||
liveness:
|
||||
enabled: true
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
successThreshold: 1
|
||||
path: /
|
||||
readiness:
|
||||
enabled: true
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
path: /
|
||||
|
||||
## Autoscaling configuration
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 3
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
## External Dependencies Configuration
|
||||
## These should point to external PostgreSQL and Redis services
|
||||
|
||||
# External PostgreSQL database configuration
|
||||
postgresql:
|
||||
# External PostgreSQL connection details
|
||||
external:
|
||||
enabled: true
|
||||
host: "postgresql.default.svc.cluster.local"
|
||||
port: 5432
|
||||
database: "paperless"
|
||||
username: "paperless"
|
||||
# Use existingSecret for credentials
|
||||
existingSecret: ""
|
||||
passwordKey: "postgresql-password"
|
||||
# Or set password directly (not recommended for production)
|
||||
password: ""
|
||||
|
||||
# External Redis configuration
|
||||
redis:
|
||||
external:
|
||||
enabled: true
|
||||
host: "redis.default.svc.cluster.local"
|
||||
port: 6379
|
||||
database: 0
|
||||
# Authentication (leave empty if Redis has no auth)
|
||||
username: "" # Optional: Redis username (Redis 6.0+)
|
||||
# Use existingSecret for credentials if Redis has auth
|
||||
existingSecret: ""
|
||||
passwordKey: "redis-password"
|
||||
# Or set password directly (leave empty if no auth)
|
||||
password: ""
|
||||
# Optional: Prefix for Redis keys and channels
|
||||
# Useful for sharing one Redis server among multiple Paperless instances
|
||||
prefix: ""
|
||||
|
||||
## Paperless-ngx Configuration
|
||||
config:
|
||||
# Basic server configuration
|
||||
url: "" # Set to your external URL, e.g., https://paperless.domain.com
|
||||
allowedHosts: "*" # Comma-separated list of allowed hosts
|
||||
csrfTrustedOrigins: "" # Comma-separated list of trusted origins
|
||||
corsAllowedHosts: "http://localhost:8000"
|
||||
forceScriptName: "" # For hosting under subpath, e.g., /paperless
|
||||
|
||||
# Security settings
|
||||
secretKey:
|
||||
# Use existingSecret for production
|
||||
existingSecret: ""
|
||||
secretKey: "secret-key"
|
||||
# Or set directly (not recommended for production)
|
||||
value: ""
|
||||
|
||||
# OCR Configuration
|
||||
ocr:
|
||||
language: "eng" # OCR language (3-letter code)
|
||||
mode: "skip" # skip, redo, or force
|
||||
skipArchiveFile: "never" # never, with_text, always
|
||||
clean: "clean" # clean, clean-final, none
|
||||
deskew: true
|
||||
rotatePages: true
|
||||
rotatePagesThreshold: 12
|
||||
outputType: "pdfa"
|
||||
pages: 0 # 0 = all pages
|
||||
imageDpi: 0 # 0 = auto
|
||||
maxImagePixels: 0 # 0 = use Pillow default
|
||||
userArgs: "{}" # JSON string of additional OCRmyPDF arguments
|
||||
|
||||
# Time and locale settings
|
||||
timeZone: "UTC"
|
||||
|
||||
# Consumer settings
|
||||
consumer:
|
||||
recursive: false
|
||||
subdirsAsTags: false
|
||||
deleteDocumentDuplicates: false
|
||||
ignorePatterns: '[".DS_Store", ".DS_STORE", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini", "@eaDir/*", "Thumbs.db"]'
|
||||
barcodeScanner: "PYZBAR"
|
||||
|
||||
# Barcode processing
|
||||
barcodes:
|
||||
enabled: false
|
||||
tiffSupport: false
|
||||
string: "PATCHT"
|
||||
retainSplitPages: false
|
||||
upscale: 0.0
|
||||
dpi: 300
|
||||
maxPages: 0
|
||||
|
||||
# ASN barcode settings
|
||||
asnEnabled: false
|
||||
asnPrefix: "ASN"
|
||||
|
||||
# Tag barcode settings
|
||||
tagEnabled: false
|
||||
tagMapping: '{"TAG:(.*)": "\\g<1>"}'
|
||||
|
||||
# Optional Tika settings (for Office documents)
|
||||
tika:
|
||||
enabled: false
|
||||
endpoint: "http://tika:9998"
|
||||
gotenbergEndpoint: "http://gotenberg:3000"
|
||||
|
||||
# Admin user creation (optional)
|
||||
admin:
|
||||
user: "" # Set to create admin user on startup
|
||||
password: "" # Required if admin.user is set
|
||||
email: "root@localhost"
|
||||
|
||||
# Use existingSecret for credentials
|
||||
existingSecret: ""
|
||||
userKey: "admin-user"
|
||||
passwordKey: "admin-password"
|
||||
|
||||
# Email configuration (optional)
|
||||
email:
|
||||
host: ""
|
||||
port: 25
|
||||
user: ""
|
||||
password: ""
|
||||
from: ""
|
||||
useTls: false
|
||||
useSsl: false
|
||||
|
||||
# Use existingSecret for credentials
|
||||
existingSecret: ""
|
||||
userKey: "email-user"
|
||||
passwordKey: "email-password"
|
||||
|
||||
# Logging
|
||||
logging:
|
||||
dir: "" # Uses PAPERLESS_DATA_DIR/log/ if empty
|
||||
|
||||
# Task processing
|
||||
taskWorkers: 1
|
||||
threadsPerWorker: 1
|
||||
workerTimeout: 1800
|
||||
|
||||
# Advanced settings
|
||||
filenameFormat: ""
|
||||
filenameFormatRemoveNone: false
|
||||
enableNltk: true
|
||||
convertMemoryLimit: 0
|
||||
convertTmpDir: ""
|
||||
maxImagePixels: 0
|
||||
|
||||
# Environment variables
|
||||
env: []
|
||||
# Example additional env vars:
|
||||
# - name: PAPERLESS_ENABLE_HTTP_REMOTE_USER
|
||||
# value: "false"
|
||||
|
||||
# Extra environment variables from secrets
|
||||
extraEnvFrom: []
|
||||
# - secretRef:
|
||||
# name: paperless-extra-secrets
|
||||
|
||||
# Extra environment variables (for advanced use cases)
|
||||
extraEnv: []
|
||||
Reference in New Issue
Block a user