Adds formbricks app.

This commit is contained in:
2026-06-19 21:33:01 +00:00
parent 8a2539e527
commit b42f048f5c
10 changed files with 301 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
# Formbricks
Formbricks is an open-source survey and feedback platform for building in-app microsurveys, NPS scores, and user research forms.
## Dependencies
- **PostgreSQL** - Database for storing surveys and responses
- **Redis** - Used for caching and background jobs
## Configuration
Key settings in `config.yaml`:
- **domain** - Where Formbricks will be accessible
- **storage** - Persistent volume size (default: `2Gi`)
- **db.name** - Database name (default: `formbricks`)
## First-Time Setup
1. Add and deploy the app:
```bash
wild app add formbricks
wild app deploy formbricks
```
2. Visit the app URL and sign up to create your admin account.
3. The first user to sign up becomes the organization owner.
4. Create your first survey from the dashboard and embed it in your apps using the provided JavaScript snippet.
## Notes
- Formbricks can be embedded in web apps or used as a standalone survey link
- The `nextauthSecret` and `encryptionKey` are auto-generated in `secrets.yaml`
- The `cronSecret` secures the internal cron endpoint used for scheduled tasks

View File

@@ -0,0 +1,61 @@
apiVersion: batch/v1
kind: Job
metadata:
name: formbricks-db-init
namespace: {{ .namespace }}
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
seccompProfile:
type: RuntimeDefault
containers:
- name: db-init
image: postgres:17
command: ["/bin/bash", "-c"]
args:
- |
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres <<EOF
DO \$\$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = '${DB_USER}') THEN
CREATE USER ${DB_USER} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
ELSE
ALTER USER ${DB_USER} WITH ENCRYPTED PASSWORD '${DB_PASSWORD}';
END IF;
END
\$\$;
SELECT 'CREATE DATABASE ${DB_NAME}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '${DB_NAME}')\gexec
ALTER DATABASE ${DB_NAME} OWNER TO ${DB_USER};
GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};
EOF
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres -d ${DB_NAME} -c "GRANT ALL ON SCHEMA public TO ${DB_USER};"
PGPASSWORD=${POSTGRES_ADMIN_PASSWORD} psql -h ${DB_HOST} -U postgres -d ${DB_NAME} -c "CREATE EXTENSION IF NOT EXISTS vector;"
env:
- name: POSTGRES_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: postgres.password
- name: DB_HOST
value: "{{ .db.host }}"
- name: DB_NAME
value: "{{ .db.name }}"
- name: DB_USER
value: "{{ .db.user }}"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: dbPassword
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
restartPolicy: OnFailure

View File

@@ -0,0 +1,102 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: formbricks
namespace: {{ .namespace }}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
component: web
template:
metadata:
labels:
component: web
spec:
securityContext:
runAsNonRoot: false
runAsUser: 0
seccompProfile:
type: RuntimeDefault
containers:
- name: formbricks
image: formbricks/formbricks:3.6.0
ports:
- name: http
containerPort: 3000
protocol: TCP
env:
- name: NODE_OPTIONS
value: "--max-old-space-size=768"
- name: WEBAPP_URL
value: "https://{{ .domain }}"
- name: NEXTAUTH_URL
value: "https://{{ .domain }}"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: dbUrl
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: nextauthSecret
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: encryptionKey
- name: CRON_SECRET
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: cronSecret
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: formbricks-secrets
key: redis.password
- name: REDIS_URL
value: "redis://:$(REDIS_PASSWORD)@{{ .redis.host }}:6379"
- name: EMAIL_VERIFICATION_DISABLED
value: "1"
- name: PASSWORD_RESET_DISABLED
value: "1"
resources:
limits:
cpu: "1"
ephemeral-storage: 1Gi
memory: 1Gi
requests:
cpu: 50m
ephemeral-storage: 50Mi
memory: 256Mi
volumeMounts:
- name: formbricks-uploads
mountPath: /home/nextjs/apps/web/uploads
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 90
timeoutSeconds: 5
periodSeconds: 15
failureThreshold: 6
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 60
timeoutSeconds: 3
periodSeconds: 10
failureThreshold: 3
securityContext:
readOnlyRootFilesystem: false
volumes:
- name: formbricks-uploads
persistentVolumeClaim:
claimName: formbricks-uploads
restartPolicy: Always

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: formbricks
namespace: {{ .namespace }}
annotations:
external-dns.alpha.kubernetes.io/target: {{ .externalDnsDomain }}
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
external-dns.alpha.kubernetes.io/ttl: "60"
spec:
ingressClassName: traefik
rules:
- host: {{ .domain }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: formbricks
port:
number: 80
tls:
- hosts:
- {{ .domain }}
secretName: {{ .tlsSecretName }}

View File

@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: {{ .namespace }}
labels:
- includeSelectors: true
pairs:
app: formbricks
managedBy: kustomize
partOf: wild-cloud
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- pvc.yaml
- db-init-job.yaml

View File

@@ -0,0 +1,27 @@
version: 3.6.0-1
requires:
- name: postgres
- name: redis
defaultConfig:
namespace: formbricks
externalDnsDomain: "{{ .cloud.domain }}"
domain: formbricks.{{ .cloud.domain }}
tlsSecretName: wildcard-wild-cloud-tls
storage: 2Gi
db:
host: "{{ .apps.postgres.host }}"
port: "{{ .apps.postgres.port }}"
name: formbricks
user: formbricks
redis:
host: "{{ .apps.redis.host }}"
defaultSecrets:
- key: dbPassword
- key: dbUrl
default: "postgresql://{{ .app.db.user }}:{{ .secrets.dbPassword }}@{{ .app.db.host }}:{{ .app.db.port }}/{{ .app.db.name }}?sslmode=disable"
- key: nextauthSecret
- key: encryptionKey
- key: cronSecret
requiredSecrets:
- postgres.password
- redis.password

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .namespace }}

View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: formbricks-uploads
namespace: {{ .namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .storage }}

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: formbricks
namespace: {{ .namespace }}
spec:
selector:
component: web
ports:
- name: http
port: 80
targetPort: 3000
protocol: TCP