Skip to content

Apache Answer

Deploy Apache Answer on Kubernetes — an open-source Q&A platform for teams and communities. Supports SQLite (zero-configuration default), PostgreSQL, and MySQL, with automatic unattended installation and database-aware scheduled backups.

SQLite is the default — no database configuration required for small teams

With the default configuration (database.mode: auto and no subchart enabled), Answer uses SQLite stored in the /data PVC. No external database is needed for teams under a few hundred users. Migrate to PostgreSQL or MySQL when you need concurrent write performance or replication.

Key Features

  • Three database backends — SQLite (default), PostgreSQL, MySQL
  • Auto-detection — mode is inferred from which subchart or external host is configured
  • Auto-install — unattended first-boot setup via environment variables (autoInstall: true)
  • Database-aware backuptar for SQLite, pg_dump for PostgreSQL, mysqldump for MySQL
  • Admin credentialsexistingSecret for GitOps-safe secret management

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install answer helmforge/answer -f values.yaml

OCI registry:

helm install answer oci://ghcr.io/helmforgedev/helm/answer -f values.yaml

Deployment Examples

# values.yaml — Apache Answer with SQLite (zero database configuration)
answer:
  siteName: 'My Q&A'
  siteUrl: 'https://qa.example.com'
  language: en-US
  autoInstall: true

admin:
  name: admin
  email: [email protected]
  existingSecret: answer-admin-credentials # key: admin-password
  existingSecretPasswordKey: admin-password

persistence:
  enabled: true
  size: 10Gi # covers both SQLite file (/data/answer.db) and uploads

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: qa.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: answer-tls
      hosts:
        - qa.example.com
# values.yaml — Apache Answer with bundled PostgreSQL
answer:
  siteName: 'My Q&A'
  siteUrl: 'https://qa.example.com'
  autoInstall: true

admin:
  name: admin
  email: [email protected]
  password: 'change-me'

postgresql:
  enabled: true
  auth:
    database: answer
    username: answer
    password: 'strong-db-password'
  primary:
    persistence:
      enabled: true
      size: 20Gi

persistence:
  enabled: true
  size: 10Gi # uploads only (SQLite not used when PostgreSQL is active)

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: qa.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Apache Answer with bundled MySQL
answer:
  siteName: 'My Q&A'
  siteUrl: 'https://qa.example.com'
  autoInstall: true

admin:
  name: admin
  email: [email protected]
  password: 'change-me'

mysql:
  enabled: true
  auth:
    database: answer
    username: answer
    password: 'strong-db-password'
    rootPassword: 'strong-root-password'
  primary:
    persistence:
      enabled: true
      size: 20Gi

persistence:
  enabled: true
  size: 10Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: qa.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Apache Answer with external PostgreSQL
answer:
  siteName: 'My Q&A'
  siteUrl: 'https://qa.example.com'
  autoInstall: true

admin:
  existingSecret: answer-admin-credentials

postgresql:
  enabled: false

database:
  mode: external
  external:
    vendor: postgres # or: mysql
    host: postgres.database.svc.cluster.local
    port: '5432'
    name: answer
    username: answer
    existingSecret: answer-db-credentials
    existingSecretPasswordKey: database-password

persistence:
  enabled: true
  size: 10Gi

backup:
  enabled: true
  schedule: '0 3 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: answer-backups
    existingSecret: answer-s3-credentials

Configuration Reference

Core

Parameter Type Default Description
nameOverride string "" Override the chart name.
fullnameOverride string "" Override the full release name.
commonLabels object {} Extra labels added to all resources.

Image

Parameter Type Default Description
image.repository string docker.io/apache/answer Apache Answer container image.
image.tag string "2.0.0" Image tag.
image.pullPolicy string IfNotPresent Image pull policy.

Answer Configuration

Parameter Type Default Description
answer.siteUrl string "" Full public URL. Auto-detected from Ingress if empty.
answer.siteName string Apache Answer Site name shown in browser tab and header.
answer.language string en-US Default UI language.
answer.contactEmail string [email protected] Contact email shown in the site footer.
answer.autoInstall boolean true Enable unattended first-boot setup using admin credentials from values.
answer.logLevel string INFO Log level: DEBUG, INFO, WARN, ERROR.
answer.extraEnv array [] Extra environment variables for the container.

Admin Credentials

Parameter Type Default Description
admin.name string admin Admin username for initial setup.
admin.password string "" Admin password. Auto-generated if empty.
admin.email string [email protected] Admin email address.
admin.existingSecret string "" Existing secret with admin credentials.
admin.existingSecretPasswordKey string admin-password Key inside the existing secret for the password.

Database

Auto-detection precedence (database.mode: auto):

Priority Condition Result
1 database.external.host or external.existingSecret set External DB
2 postgresql.enabled: true PostgreSQL subchart
3 mysql.enabled: true MySQL subchart
4 None of the above SQLite (default)
Parameter Type Default Description
database.mode string auto Database mode: auto, sqlite, external, postgresql, mysql.
database.sqlite.file string /data/answer.db SQLite file path inside the data volume.
database.external.vendor string postgres External DB vendor: postgres or mysql.
database.external.host string "" External database hostname.
database.external.port string "" External database port. Auto-detected from vendor if empty.
database.external.name string answer Database name.
database.external.username string answer Database username.
database.external.existingSecret string "" Existing secret with database password.
database.external.existingSecretPasswordKey string database-password Key for the password in the existing secret.

Subcharts

Parameter Type Default Description
postgresql.enabled boolean false Deploy the bundled PostgreSQL subchart.
postgresql.auth.database string answer Database name.
postgresql.auth.password string "" Password. Auto-generated if empty.
postgresql.primary.persistence.size string 8Gi PVC size.
mysql.enabled boolean false Deploy the bundled MySQL subchart.
mysql.auth.database string answer Database name.
mysql.auth.password string "" Password. Auto-generated if empty.
mysql.primary.persistence.size string 8Gi PVC size.

Persistence

Parameter Type Default Description
persistence.enabled boolean true Enable PVC for /data (SQLite DB file + uploads).
persistence.size string 5Gi PVC size. Increase if using SQLite as the primary database.
persistence.storageClass string "" StorageClass for the PVC.
persistence.accessMode string ReadWriteOnce PVC access mode.
persistence.existingClaim string "" Use an existing PVC.

Backup

Backup mode is automatically selected based on the active database vendor

The backup CronJob detects which database is in use and runs the appropriate tool:

  • SQLitetar archive of the full /data directory (Alpine image)
  • PostgreSQLpg_dump (PostgreSQL Alpine image)
  • MySQLmysqldump (MySQL image)

Only the images needed for the active database vendor are used.

Parameter Type Default Description
backup.enabled boolean false Enable scheduled S3 backup CronJob.
backup.schedule string "0 3 * * *" Cron schedule.
backup.archivePrefix string answer Prefix for backup archive filenames.
backup.images.sqlite string alpine:3.22 Image for SQLite backup (tar).
backup.images.postgresql string postgres:18.3-alpine Image for PostgreSQL backup (pg_dump).
backup.images.mysql string mysql:8.4 Image for MySQL backup (mysqldump).
backup.images.uploader string helmforge/mc:1.0.0 Image for S3 upload (MinIO client).
backup.s3.endpoint string "" S3-compatible endpoint URL.
backup.s3.bucket string "" Target bucket name.
backup.s3.existingSecret string "" Existing secret with S3 credentials.
backup.database.postgresDumpArgs string "" Extra arguments for pg_dump.
backup.database.mysqlDumpArgs string --single-transaction ... Extra arguments for mysqldump.

Service and Ingress

Parameter Type Default Description
service.type string ClusterIP Service type.
service.port integer 80 Service port.
ingress.enabled boolean false Enable an Ingress resource.
ingress.ingressClassName string "" Ingress class name.
ingress.annotations object {} Ingress annotations.
ingress.hosts array [] Host and path rules.
ingress.tls array [] TLS configuration.

Probes

All probes use /healthz as the HTTP path.

Parameter Type Default Description
startupProbe.enabled boolean true Enable startup probe.
startupProbe.failureThreshold integer 30 Startup probe failure threshold.
livenessProbe.enabled boolean true Enable liveness probe.
readinessProbe.enabled boolean true Enable readiness probe.

Resources and Scheduling

Parameter Type Default Description
resources object {} CPU and memory requests/limits.
terminationGracePeriodSeconds integer 30 Termination grace period.
nodeSelector object {} Node selector for scheduling.
tolerations array [] Tolerations for scheduling.
extraVolumes array [] Extra volumes.
extraVolumeMounts array [] Extra volume mounts.
extraManifests array [] Extra Kubernetes manifests.

More Information