Joplin Server Helm Chart
A Helm chart for deploying Joplin Server on Kubernetes.
Introduction
This chart deploys Joplin Server, the synchronization server for the Joplin note-taking application, on a Kubernetes cluster. Joplin Server allows syncing notes across devices and supports filesystem or S3 storage, email notifications, and an optional AI transcription service.
Source code: https://github.com/rtomik/helm-charts/tree/main/charts/joplin-server
Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
- External PostgreSQL database (required — Joplin Server does not support SQLite)
- PV provisioner support (if using filesystem storage)
Installing the Chart
Uninstalling the Chart
Configuration Examples
Minimal Installation
Production with Existing Secrets
S3 Storage
Email Notifications
Transcribe Service (AI Transcription)
Parameters
Global Parameters
| Name |
Description |
Default |
nameOverride |
Override the release name |
"" |
fullnameOverride |
Fully override the release name |
"" |
Image Parameters
| Name |
Description |
Default |
image.repository |
Joplin Server image repository |
joplin/server |
image.tag |
Image tag |
3.4.2 |
image.pullPolicy |
Image pull policy |
IfNotPresent |
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 |
1001 |
podSecurityContext.fsGroup |
Filesystem group ID |
1001 |
nodeSelector |
Node selector |
{} |
tolerations |
Tolerations |
[] |
affinity |
Affinity rules |
{} |
Service Parameters
| Name |
Description |
Default |
service.type |
Service type |
ClusterIP |
service.port |
Service port |
22300 |
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 |
PostgreSQL Configuration (Required)
| Name |
Description |
Default |
postgresql.external.enabled |
Use external PostgreSQL |
true |
postgresql.external.host |
PostgreSQL host |
"" |
postgresql.external.port |
PostgreSQL port |
5432 |
postgresql.external.database |
Database name |
joplin |
postgresql.external.user |
Username |
joplin |
postgresql.external.password |
Password |
"" |
postgresql.external.existingSecret |
Existing secret name |
"" |
postgresql.external.userKey |
Key for username in secret |
username |
postgresql.external.passwordKey |
Key for password in secret |
password |
postgresql.external.hostKey |
Key for host in secret (optional) |
"" |
postgresql.external.portKey |
Key for port in secret (optional) |
"" |
postgresql.external.databaseKey |
Key for database in secret (optional) |
"" |
Admin Settings
| Name |
Description |
Default |
joplin.admin.email |
Admin user email |
"" |
joplin.admin.password |
Admin user password |
"" |
joplin.admin.existingSecret |
Existing secret for admin credentials |
"" |
joplin.admin.emailKey |
Key for email in secret |
admin-email |
joplin.admin.passwordKey |
Key for password in secret |
admin-password |
Server Settings
| Name |
Description |
Default |
joplin.server.maxRequestBodySize |
Max request body size |
200mb |
joplin.server.sessionTimeout |
Session timeout (seconds) |
86400 |
joplin.server.enableUserRegistration |
Enable user registration |
false |
joplin.server.enableSharing |
Enable sharing |
true |
joplin.server.enablePublicNotes |
Enable public notes |
true |
Storage Settings
| Name |
Description |
Default |
joplin.storage.driver |
Storage driver (filesystem, s3, azure) |
filesystem |
joplin.storage.filesystemPath |
Filesystem storage path |
/var/lib/joplin |
joplin.storage.s3.bucket |
S3 bucket name |
"" |
joplin.storage.s3.region |
S3 region |
"" |
joplin.storage.s3.endpoint |
S3 endpoint (for S3-compatible services) |
"" |
joplin.storage.s3.accessKeyId |
S3 access key ID |
"" |
joplin.storage.s3.secretAccessKey |
S3 secret access key |
"" |
joplin.storage.s3.existingSecret |
Existing secret for S3 credentials |
"" |
joplin.storage.s3.accessKeyIdKey |
Key for access key in secret |
access-key-id |
joplin.storage.s3.secretAccessKeyKey |
Key for secret access key in secret |
secret-access-key |
Email Settings
| Name |
Description |
Default |
joplin.email.enabled |
Enable email |
false |
joplin.email.host |
SMTP host |
"" |
joplin.email.port |
SMTP port |
587 |
joplin.email.username |
SMTP username |
"" |
joplin.email.password |
SMTP password |
"" |
joplin.email.fromEmail |
From email address |
"" |
joplin.email.fromName |
From name |
Joplin Server |
joplin.email.secure |
Use TLS/SSL |
true |
joplin.email.existingSecret |
Existing secret for credentials |
"" |
joplin.email.usernameKey |
Key for username in secret |
email-username |
joplin.email.passwordKey |
Key for password in secret |
email-password |
Logging Settings
| Name |
Description |
Default |
joplin.logging.level |
Log level (error, warn, info, debug) |
info |
joplin.logging.target |
Log target (console, file) |
console |
Persistence Parameters
| Name |
Description |
Default |
persistence.enabled |
Enable persistence |
true |
persistence.storageClass |
Storage class |
"" |
persistence.accessMode |
Access mode |
ReadWriteOnce |
persistence.size |
PVC size |
10Gi |
persistence.annotations |
PVC annotations |
{} |
Transcribe Service
| Name |
Description |
Default |
transcribe.enabled |
Enable transcribe service |
false |
transcribe.image.repository |
Transcribe image repository |
joplin/transcribe |
transcribe.image.tag |
Transcribe image tag |
latest |
transcribe.api.key |
Shared API key |
"" |
transcribe.api.existingSecret |
Existing secret for API key |
"" |
transcribe.api.keyName |
Key name in secret |
transcribe-api-key |
transcribe.service.type |
Transcribe service type |
ClusterIP |
transcribe.service.port |
Transcribe service port |
4567 |
transcribe.database.host |
Transcribe DB host |
"" |
transcribe.database.port |
Transcribe DB port |
5432 |
transcribe.database.database |
Transcribe DB name |
transcribe |
transcribe.database.user |
Transcribe DB user |
transcribe |
transcribe.database.password |
Transcribe DB password |
"" |
transcribe.database.existingSecret |
Existing secret for transcribe DB |
"" |
transcribe.database.userKey |
Key for username in secret |
username |
transcribe.database.passwordKey |
Key for password in secret |
password |
Security Settings
| Name |
Description |
Default |
security.httpsRedirect |
Enable HTTPS redirect |
false |
security.tls.enabled |
Enable custom TLS certificate |
false |
security.tls.existingSecret |
Secret with TLS certificate |
"" |
security.tls.certificateKey |
Key for TLS certificate in secret |
tls.crt |
security.tls.privateKeyKey |
Key for TLS private key in secret |
tls.key |
Resource Parameters
| Name |
Description |
Default |
resources |
Resource limits and requests |
{} |
Health Check Parameters
| Name |
Description |
Default |
probes.liveness.enabled |
Enable liveness probe |
true |
probes.liveness.path |
Liveness probe path |
/api/ping |
probes.liveness.initialDelaySeconds |
Liveness initial delay |
60 |
probes.liveness.periodSeconds |
Liveness period |
30 |
probes.liveness.httpHeaders |
Liveness HTTP headers |
Host matching ingress |
probes.readiness.enabled |
Enable readiness probe |
true |
probes.readiness.path |
Readiness probe path |
/api/ping |
probes.readiness.initialDelaySeconds |
Readiness initial delay |
30 |
probes.readiness.periodSeconds |
Readiness period |
10 |
probes.readiness.httpHeaders |
Readiness HTTP headers |
Host matching ingress |
Autoscaling Parameters
| Name |
Description |
Default |
autoscaling.enabled |
Enable HPA |
false |
autoscaling.minReplicas |
Min replicas |
1 |
autoscaling.maxReplicas |
Max replicas |
3 |
autoscaling.targetCPUUtilizationPercentage |
Target CPU |
80 |
autoscaling.targetMemoryUtilizationPercentage |
Target memory |
80 |
Troubleshooting
Health Check Failures / "No Available Server"
Health checks require the correct Host header matching your ingress domain:
Database Connection Issues
Verify PostgreSQL credentials, network connectivity, and that env.APP_BASE_URL matches your ingress host.
Origin Validation Errors
Ensure env.APP_BASE_URL matches your ingress hostname exactly.
Debugging
Links