Skip to content

Gophish

Gophish is an open-source phishing awareness platform for authorized security training and simulation programs. The HelmForge chart installs Gophish 0.12.1 with separate admin and phishing Services, private-by-default access, SQLite persistence, optional HelmForge MySQL, external MySQL support, NetworkPolicy, and SQLite backup.

Authorized use only

Keep Gophish deployments limited to approved security awareness and testing workflows. The chart keeps the admin UI private by default and requires explicit values before exposing it through ingress.

Key Features

  • Separated traffic — dedicated admin and phishing Services and ingresses
  • Safe defaults — admin ingress disabled, phishing ingress disabled, one replica, PVC-backed SQLite
  • Secret-backed config — generated config.json is rendered as a Secret with an existing Secret override
  • Database choices — SQLite default, HelmForge MySQL dependency, or external MySQL DSN Secret
  • NetworkPolicy — separate admin, phishing, database, DNS, and SMTP egress controls
  • SQLite backup — optional CronJob uploads archive and checksum to S3-compatible storage

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install gophish helmforge/gophish --namespace gophish --create-namespace

OCI registry:

helm install gophish oci://ghcr.io/helmforgedev/helm/gophish --namespace gophish --create-namespace

Access

The admin UI is private by default:

kubectl port-forward svc/gophish-gophish-admin 3333:3333 -n gophish

Open http://127.0.0.1:3333.

The generated initial admin password is written to first-start logs:

kubectl logs deploy/gophish-gophish -n gophish | grep "Please login with the username admin"

Change the password immediately after the first login and avoid copying it into tickets, values files, or PRs.

Deployment Examples

replicaCount: 1

persistence:
  enabled: true
  size: 5Gi
phishIngress:
  enabled: true
  hosts:
    - host: training.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: gophish-phish-tls
      hosts:
        - training.example.com
database:
  mode: external
  external:
    host: mysql.database.svc.cluster.local
    port: 3306
    name: gophish
    username: gophish
    existingSecret: gophish-db
    existingSecretDsnKey: dsn
database:
  mode: external
  external:
    host: mysql.database.svc.cluster.local
    name: gophish
    username: gophish
    existingSecret: gophish-db
    existingSecretDsnKey: dsn

phishIngress:
  enabled: true
  hosts:
    - host: training.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: gophish-phish-tls
      hosts:
        - training.example.com

networkPolicy:
  enabled: true
  admin:
    ipBlocks:
      - cidr: 10.10.0.0/16
  phish:
    namespaceSelectors:
      - matchLabels:
          kubernetes.io/metadata.name: ingress-system
  egress:
    externalDatabase:
      enabled: true
      cidrs:
        - 10.0.0.0/8
backup:
  enabled: true
  schedule: '0 3 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: gophish-backups
    prefix: gophish
    existingSecret: gophish-backup

Admin Ingress

Admin ingress is disabled by default and requires TLS when enabled:

adminIngress:
  enabled: true
  tls:
    - secretName: gophish-admin-tls
      hosts:
        - gophish-admin.example.com
  hosts:
    - host: gophish-admin.example.com
      paths:
        - path: /
          pathType: Prefix

Use gophish.adminServer.trustedOrigins when a proxy or ingress terminates TLS and Gophish must trust the external origin.

Database Notes

SQLite is the default and requires replicaCount: 1. Embedded MySQL uses the HelmForge MySQL dependency and sets mysql.config.myCnf to sql_mode=NO_ENGINE_SUBSTITUTION because Gophish 0.12.1 bootstraps zero-date values that MySQL 8.4 rejects under strict zero-date modes.

External MySQL should use database.external.existingSecret with a complete DSN. Inline external passwords are blocked unless database.external.allowInlinePassword=true, which is intended only for local tests.

Backup Notes

Chart-managed backup covers SQLite mode only. It archives the chart-managed PVC path containing the SQLite database, writes a SHA256 checksum, and uploads both files with docker.io/helmforge/mc:1.0.0.

Embedded MySQL and external MySQL backup are delegated to MySQL-specific backup tooling.

Values Reference

KeyTypeDefaultDescription
nameOverridestring""Override chart name in resource names
fullnameOverridestring""Override full resource name
commonLabelsobject{}Labels added to chart resources
replicaCountinteger1Gophish replicas; SQLite requires 1
clusterDomainstringcluster.localKubernetes cluster domain
image.repositorystringdocker.io/gophish/gophishOfficial Gophish image repository
image.tagstring0.12.1Pinned Gophish image tag
image.pullPolicystringIfNotPresentImage pull policy
imagePullSecretsarray[]Private registry pull secrets
gophish.config.existingSecretstring""Existing Secret with complete config.json
gophish.config.existingSecretKeystringconfig.jsonKey for config.json
gophish.adminServer.listenUrlstring0.0.0.0:3333Admin listener inside the container
gophish.adminServer.useTlsbooleanfalseEnable native Gophish admin TLS
gophish.adminServer.certSecretstring""Secret for native admin TLS
gophish.adminServer.trustedOriginsarray[]Trusted admin origins behind ingress
gophish.phishServer.listenUrlstring0.0.0.0:80Phishing listener inside the container
gophish.phishServer.useTlsbooleanfalseEnable native Gophish phishing TLS
gophish.phishServer.certSecretstring""Secret for native phishing TLS
gophish.logging.filenamestring""Optional log filename
gophish.logging.levelstring""Optional log level
gophish.contactAddressstring""Optional contact address in Gophish config
database.modestringautoauto, sqlite, mysql, or external
database.sqlite.pathstring/opt/gophish/data/gophish.dbSQLite database path
database.external.hoststring""External MySQL host
database.external.portinteger3306External MySQL port
database.external.namestringgophishExternal database name
database.external.usernamestringgophishExternal database username
database.external.passwordstring""Inline password for local tests only
database.external.allowInlinePasswordbooleanfalseExplicit opt-in for inline external password
database.external.existingSecretstring""Secret containing complete DSN
database.external.existingSecretDsnKeystringdsnSecret key for DSN
database.external.parametersstringcharset=utf8&parseTime=True&loc=UTCDSN query parameters
mysql.enabledbooleanfalseEnable HelmForge MySQL dependency
mysql.config.myCnfstringGophish-compatible sql_modeExtra embedded MySQL config
mysql.auth.databasestringgophishEmbedded MySQL database
mysql.auth.usernamestringgophishEmbedded MySQL user
mysql.auth.passwordstring""Embedded MySQL password, generated when empty
mysql.auth.existingSecretstring""Existing MySQL credential Secret
persistence.enabledbooleantrueCreate chart-managed PVC
persistence.existingClaimstring""Existing PVC name
persistence.storageClassstring""PVC storage class
persistence.accessModesarray["ReadWriteOnce"]PVC access modes
persistence.sizestring5GiPVC size
serviceAccount.createbooleantrueCreate ServiceAccount
serviceAccount.automountServiceAccountTokenbooleanfalseAutomount API token
adminService.typestringClusterIPAdmin Service type
adminService.portinteger3333Admin Service port
adminService.ipFamilyPolicystringomittedOptional Service IP family policy
adminService.ipFamiliesarrayomittedOptional ordered Service IP families
phishService.typestringClusterIPPhishing Service type
phishService.portinteger80Phishing Service port
phishService.ipFamilyPolicystringomittedOptional Service IP family policy
phishService.ipFamiliesarrayomittedOptional ordered Service IP families
adminIngress.enabledbooleanfalseEnable admin ingress
adminIngress.hostsarray[]Admin ingress hosts
adminIngress.tlsarray[]Admin ingress TLS, required when enabled
phishIngress.enabledbooleanfalseEnable phishing ingress
phishIngress.hostsarray[]Phishing ingress hosts
phishIngress.tlsarray[]Phishing ingress TLS
networkPolicy.enabledbooleanfalseEnable NetworkPolicy
networkPolicy.admin.*objectsee valuesAdmin ingress allow rules
networkPolicy.phish.*objectsee valuesPhishing ingress allow rules
networkPolicy.egress.allowDnsbooleantrueAllow DNS egress
networkPolicy.egress.externalDatabase.*objectsee valuesExternal DB egress allow rules
networkPolicy.egress.smtp.*objectsee valuesSMTP egress allow rules
backup.enabledbooleanfalseEnable SQLite backup CronJob
backup.schedulestring0 3 * * *Backup schedule
backup.images.archive.repositorystringdocker.io/library/busyboxArchive image
backup.images.uploader.repositorystringdocker.io/helmforge/mcHelmForge S3 uploader image
backup.s3.endpointstring""S3-compatible endpoint
backup.s3.bucketstring""Backup bucket
backup.s3.existingSecretstring""S3 credential Secret
probes.*objectsee valuesStartup, liveness, readiness probes
resourcesobjectsee valuesGophish container resources
podSecurityContextobjectsee valuesPod security context
containerSecurityContextobjectsee valuesContainer security context
nodeSelectorobject{}Node selector
tolerationsarray[]Pod tolerations
affinityobject{}Pod affinity
topologySpreadConstraintsarray[]Pod spread constraints
priorityClassNamestring""PriorityClass name
podLabelsobject{}Extra pod labels
podAnnotationsobject{}Extra pod annotations
extraEnvarray[]Extra container environment
extraVolumesarray[]Extra pod volumes
extraVolumeMountsarray[]Extra container volume mounts
extraManifestsarray[]Extra manifests rendered with the chart

Troubleshooting

Admin UI exposed unintentionally

Disable adminIngress.enabled and use port-forward until trusted ingress, TLS, DNS, and gophish.adminServer.trustedOrigins are reviewed.

Initial password not found

The generated password is emitted on first boot. If logs have rotated, reset the admin account through an operator-approved Gophish recovery process.

  • Admin UI not reachable — check the admin Service, port-forward command, ingress host, and TLS Secret.
  • Phishing endpoint not reachable — check phishIngress, DNS, ingress controller namespace policy, and the phish Service.
  • SQLite PVC permission problems — confirm the PVC is bound and the pod runs with the default fsGroup.
  • MySQL DSN errors — confirm the DSN Secret key and MySQL sql_mode compatibility.
  • Ingress TLS mismatch — align ingress TLS termination with native Gophish TLS settings.
  • Trusted origins or CSRF errors — add the external admin origin to gophish.adminServer.trustedOrigins.
  • Backup failures — inspect backup Job logs, S3 endpoint reachability, and the S3 credential Secret.
  • Image pull errors — confirm access to docker.io/gophish/gophish:0.12.1 and the HelmForge uploader image.

More Information