mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-19 03:04:39 -05:00
939fedfca4
Signed-off-by: gulshank0 <gulshanbahadur002@gmail.com> Co-authored-by: Tiago Farto <tiago@formbricks.com> Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com> Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Tiago <1585571+xernobyl@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Theodór Tómas <theodortomas@gmail.com> Co-authored-by: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com> Co-authored-by: Bhagya Amarasinghe <b.sithumini@yahoo.com> Co-authored-by: Chowdhury Tafsir Ahmed Siddiki <ctafsiras@gmail.com> Co-authored-by: neila <40727091+neila@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Harsh Bhat <90265455+harshsbhat@users.noreply.github.com> Co-authored-by: Harsh Bhat <harshbhat@Harshs-MacBook-Air.local> Co-authored-by: Johannes <johannes@formbricks.com> Co-authored-by: Balázs Úr <balazs@urbalazs.hu> Co-authored-by: Gulshan <gulshanbahadur002@gmail.com> Co-authored-by: Harsh Bhat <harsh121102@gmail.com> Co-authored-by: Javi Aguilar <122741+itsjavi@users.noreply.github.com> Co-authored-by: Johannes <jobenjada@users.noreply.github.com>
485 lines
19 KiB
Plaintext
485 lines
19 KiB
Plaintext
---
|
||
title: "Docker Setup"
|
||
description: "Set up Formbricks quickly using our ready-to-use Docker image."
|
||
icon: "docker"
|
||
---
|
||
|
||
The image is pre-built and requires minimal setup—just download it and start the container.
|
||
|
||
### Requirements
|
||
|
||
Make sure Docker and Docker Compose are installed on your system. These are usually included in tools like Docker Desktop and Rancher Desktop.
|
||
|
||
<Note>
|
||
`docker compose` without the hyphen is now the primary method of using docker-compose, according to the
|
||
Docker documentation.
|
||
</Note>
|
||
|
||
<Info>
|
||
Starting with Formbricks v5, the production Docker Compose stack includes Formbricks Hub and the XM Suite v5
|
||
Cube.js services. Generate `HUB_API_KEY` and `CUBEJS_API_SECRET` during setup, keep `HUB_API_URL` at its
|
||
internal default unless Hub runs elsewhere, and use the [migration guide](/self-hosting/advanced/migration#v5)
|
||
when upgrading an existing 4.x instance.
|
||
</Info>
|
||
|
||
## Start
|
||
|
||
1. **Create a New Directory for Formbricks**
|
||
|
||
Open a terminal and run the following commands to create and enter a new directory for Formbricks:
|
||
|
||
```bash
|
||
mkdir formbricks-quickstart && cd formbricks-quickstart
|
||
```
|
||
|
||
1. **Download the Docker Files**
|
||
|
||
Get the Docker Compose file plus the Cube.js configuration shipped with the XM Suite v5 stack:
|
||
|
||
```bash
|
||
mkdir -p cube/schema
|
||
curl -o docker-compose.yml https://raw.githubusercontent.com/formbricks/formbricks/stable/docker/docker-compose.yml
|
||
curl -o cube/cube.js https://raw.githubusercontent.com/formbricks/formbricks/stable/docker/cube/cube.js
|
||
curl -o cube/schema/FeedbackRecords.js https://raw.githubusercontent.com/formbricks/formbricks/stable/docker/cube/schema/FeedbackRecords.js
|
||
```
|
||
|
||
1. **Generate Hub Secret and Optional Cube Secret**
|
||
|
||
Formbricks Hub requires an API key. XM Suite v5 analytics also requires Cube.js; set the optional `xm`
|
||
Compose profile and Cube secret when you want to run the bundled Cube service. For a Hub-only stack, create
|
||
`.env` with just `HUB_API_KEY` and omit `COMPOSE_PROFILES` and `CUBEJS_API_SECRET`.
|
||
|
||
```bash
|
||
cat <<EOF > .env
|
||
COMPOSE_PROFILES=xm
|
||
HUB_API_KEY=$(openssl rand -hex 32)
|
||
CUBEJS_API_SECRET=$(openssl rand -hex 32)
|
||
CUBEJS_JWT_ISSUER=formbricks-web
|
||
CUBEJS_JWT_AUDIENCE=formbricks-cube
|
||
EOF
|
||
```
|
||
|
||
1. **Generate NextAuth Secret**
|
||
|
||
You need a NextAuth secret for session signing and encryption. Run one of the commands below based on your operating system:
|
||
|
||
For Linux:
|
||
|
||
```bash
|
||
sed -i "/NEXTAUTH_SECRET:$/s/NEXTAUTH_SECRET:.*/NEXTAUTH_SECRET: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
For macOS:
|
||
|
||
```bash
|
||
sed -i '' "s/NEXTAUTH_SECRET:.*/NEXTAUTH_SECRET: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
1. **Generate Encryption Key**
|
||
|
||
Next, you need to generate an Encryption Key. This will be used for authenticating and verifying 2 Factor Authentication. Run one of the commands below based on your operating system:
|
||
|
||
For Linux:
|
||
|
||
```bash
|
||
sed -i "/ENCRYPTION_KEY:$/s/ENCRYPTION_KEY:.*/ENCRYPTION_KEY: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
For macOS:
|
||
|
||
```bash
|
||
sed -i '' "s/ENCRYPTION_KEY:.*/ENCRYPTION_KEY: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
1. **Generate Cron Secret**
|
||
|
||
You require a Cron secret to secure API access for running cron jobs. Run one of the commands below based on your operating system:
|
||
|
||
For Linux:
|
||
|
||
```bash
|
||
sed -i "/CRON_SECRET:$/s/CRON_SECRET:.*/CRON_SECRET: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
For macOS:
|
||
|
||
```bash
|
||
sed -i '' "s/CRON_SECRET:.*/CRON_SECRET: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
1. **Generate Hub API Key**
|
||
|
||
Formbricks v5 requires a Hub API key for the bundled Hub service.
|
||
|
||
For Linux:
|
||
|
||
```bash
|
||
sed -i "/HUB_API_KEY:$/s/HUB_API_KEY:.*/HUB_API_KEY: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
For macOS:
|
||
|
||
```bash
|
||
sed -i '' "s/HUB_API_KEY:.*/HUB_API_KEY: $(openssl rand -hex 32)/" docker-compose.yml
|
||
```
|
||
|
||
<Info>
|
||
The bundled production stack already sets <code>HUB_API_URL</code> to <code>http://hub:8080</code>. Only
|
||
change that value if your Formbricks app needs to reach Hub at a different address. If your deployment also
|
||
resolves Compose variables from a shell environment or <code>.env</code> file, keep the same
|
||
<code>HUB_API_KEY</code> available there as well.
|
||
</Info>
|
||
|
||
1. **Start the Docker Setup**
|
||
|
||
Now, you're ready to run Formbricks with Docker. Use the command below to start Formbricks together with
|
||
PostgreSQL, Redis, and Formbricks Hub. If the `xm` profile is set in `.env`, Docker Compose also starts Cube.js
|
||
for XM Suite v5 analytics.
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
The `-d` flag runs the containers in the background, so they keep running even after you close the terminal.
|
||
|
||
1. **Open Formbricks in Your Browser**
|
||
|
||
Once the setup is running, open [**http://localhost:3000**](http://localhost:3000) in your browser to access Formbricks. The first time you visit, you'll see a setup wizard. Follow the steps to create your first user and start using Formbricks.
|
||
|
||
<Note>
|
||
The bundled Docker stack keeps Formbricks Hub internal to the compose network. When the `xm` profile is
|
||
enabled, Cube.js is internal too. The app reaches them through `http://hub:8080` and `http://cube:4000`.
|
||
</Note>
|
||
|
||
<Info>
|
||
If you use the one-click Traefik setup, FeedbackRecords are available on the Formbricks origin at
|
||
`/api/v3/feedbackRecords` and `/v1/feedback-records`. Custom Docker reverse proxies need equivalent wiring:
|
||
run gateway auth against the Formbricks app, rewrite `/api/v3/feedbackRecords` to Hub's
|
||
`/v1/feedback-records`, and inject `Authorization: Bearer <HUB_API_KEY>` only on the Hub-bound hop.
|
||
</Info>
|
||
|
||
## Update
|
||
|
||
Please take a look at our [migration guide](/self-hosting/advanced/migration) for version specific steps to update Formbricks.
|
||
|
||
<Info>
|
||
For a major migration such as Formbricks 4.x to 5.0, update your compose structure and configuration first.
|
||
Pulling images alone is not enough if your stack does not yet include Hub, `HUB_API_KEY`, the bundled
|
||
`cube/` config files plus `CUBEJS_API_SECRET`, or the new edge rate-limiting setup.
|
||
</Info>
|
||
|
||
1. Pull the latest Formbricks image
|
||
|
||
```bash
|
||
docker compose pull
|
||
```
|
||
|
||
1. Stop the Formbricks stack
|
||
|
||
```bash
|
||
docker compose down
|
||
```
|
||
|
||
1. Re-start the Formbricks stack with the updated image
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
## Optional: Adding RustFS for File Storage
|
||
|
||
RustFS provides S3-compatible object storage for file uploads in Formbricks. If you want to enable features
|
||
like image uploads, survey file uploads, or custom logos, you can run RustFS alongside Formbricks while
|
||
keeping the existing `S3_*` environment variables.
|
||
|
||
<Note>
|
||
For a broader overview of file storage options and required environment variables, see our [File Uploads
|
||
Configuration](/self-hosting/configuration/file-uploads) guide.
|
||
</Note>
|
||
|
||
<Warning>
|
||
**For production deployments with HTTPS**, use the [one-click setup script](/self-hosting/setup/one-click)
|
||
which automatically configures RustFS with Traefik, SSL certificates, a dedicated `files.` subdomain, and
|
||
least-privilege service credentials. The examples below are best suited for development, testing, or custom
|
||
local setups.
|
||
</Warning>
|
||
|
||
<Warning>
|
||
The bundled RustFS examples on this page are convenience-oriented single-server setups. They work well for
|
||
development, evaluation, and smaller self-hosted deployments, but they are not the ideal RustFS architecture
|
||
for high-availability or larger-scale production storage. For stricter production requirements, use external
|
||
object storage or run a dedicated RustFS deployment separately.
|
||
</Warning>
|
||
|
||
### Quick Start: Using docker-compose.dev.yml
|
||
|
||
The fastest way to test file uploads locally is to use the included `docker-compose.dev.yml`, which already
|
||
starts RustFS and auto-creates the `formbricks` bucket.
|
||
|
||
1. **Start the local stack**
|
||
|
||
From the repository root:
|
||
|
||
```bash
|
||
docker compose -f docker-compose.dev.yml up -d
|
||
```
|
||
|
||
This starts PostgreSQL, Valkey (Redis), Mailhog, RustFS, a permissions helper, a one-time bucket
|
||
bootstrap job, Formbricks Hub, and a local Cube instance for analytics testing.
|
||
|
||
2. **Access the RustFS console**
|
||
|
||
Open http://localhost:9001 in your browser and sign in with:
|
||
- Username: `devrustfs`
|
||
- Password: `devrustfs123`
|
||
|
||
3. **Configure Formbricks**
|
||
|
||
Update your `.env` file or environment variables:
|
||
|
||
```bash
|
||
S3_ACCESS_KEY="devrustfs"
|
||
S3_SECRET_KEY="devrustfs123"
|
||
S3_REGION="us-east-1"
|
||
S3_BUCKET_NAME="formbricks"
|
||
S3_ENDPOINT_URL="http://localhost:9000"
|
||
S3_FORCE_PATH_STYLE="1"
|
||
```
|
||
|
||
4. **Verify uploads**
|
||
|
||
After uploading a file in Formbricks, open http://localhost:9001 and navigate to **Buckets → formbricks**
|
||
to confirm the object was stored successfully.
|
||
|
||
<Note>
|
||
The development compose file also runs a `rustfs-init` job so you do not need to create the bucket manually.
|
||
</Note>
|
||
|
||
### Manual RustFS Setup (Custom Configuration)
|
||
|
||
<Note>
|
||
<strong>Recommended:</strong> Prefer <code>docker-compose.dev.yml</code> for local development unless you
|
||
need to fold RustFS into an existing custom Compose stack.
|
||
</Note>
|
||
|
||
If you want to add RustFS to your own `docker-compose.yml`, use a pinned RustFS image plus two helper
|
||
services:
|
||
|
||
```yaml
|
||
services:
|
||
rustfs-perms:
|
||
image: busybox:1.36.1
|
||
user: "0:0"
|
||
command: ["sh", "-c", "mkdir -p /data && chown -R 10001:10001 /data"]
|
||
volumes:
|
||
- rustfs-data:/data
|
||
|
||
rustfs:
|
||
image: rustfs/rustfs:1.0.0-alpha.93
|
||
restart: always
|
||
depends_on:
|
||
rustfs-perms:
|
||
condition: service_completed_successfully
|
||
command: /data
|
||
environment:
|
||
RUSTFS_ACCESS_KEY: "${FORMBRICKS_RUSTFS_ADMIN_USER}"
|
||
RUSTFS_SECRET_KEY: "${FORMBRICKS_RUSTFS_ADMIN_PASSWORD}"
|
||
RUSTFS_ADDRESS: ":9000"
|
||
RUSTFS_CONSOLE_ENABLE: "true"
|
||
RUSTFS_CONSOLE_ADDRESS: ":9001"
|
||
ports:
|
||
- "9000:9000"
|
||
- "9001:9001"
|
||
volumes:
|
||
- rustfs-data:/data
|
||
|
||
rustfs-init:
|
||
image: minio/mc@sha256:95b5f3f7969a5c5a9f3a700ba72d5c84172819e13385aaf916e237cf111ab868
|
||
depends_on:
|
||
- rustfs
|
||
environment:
|
||
RUSTFS_ADMIN_USER: "${FORMBRICKS_RUSTFS_ADMIN_USER}"
|
||
RUSTFS_ADMIN_PASSWORD: "${FORMBRICKS_RUSTFS_ADMIN_PASSWORD}"
|
||
RUSTFS_SERVICE_USER: "${FORMBRICKS_RUSTFS_SERVICE_USER}"
|
||
RUSTFS_SERVICE_PASSWORD: "${FORMBRICKS_RUSTFS_SERVICE_PASSWORD}"
|
||
RUSTFS_BUCKET_NAME: "${FORMBRICKS_RUSTFS_BUCKET_NAME}"
|
||
RUSTFS_POLICY_NAME: "${FORMBRICKS_RUSTFS_POLICY_NAME}"
|
||
entrypoint:
|
||
- /bin/sh
|
||
- -c
|
||
- |
|
||
set -e
|
||
until mc alias set rustfs http://rustfs:9000 "$RUSTFS_ADMIN_USER" "$RUSTFS_ADMIN_PASSWORD" >/dev/null 2>&1 \
|
||
&& mc ls rustfs >/dev/null 2>&1; do
|
||
sleep 2
|
||
done
|
||
mc mb rustfs/"$RUSTFS_BUCKET_NAME" --ignore-existing
|
||
cat > /tmp/formbricks-policy.json << EOF
|
||
{
|
||
"Version": "2012-10-17",
|
||
"Statement": [
|
||
{
|
||
"Effect": "Allow",
|
||
"Action": ["s3:DeleteObject", "s3:GetObject", "s3:PutObject"],
|
||
"Resource": ["arn:aws:s3:::$RUSTFS_BUCKET_NAME/*"]
|
||
},
|
||
{
|
||
"Effect": "Allow",
|
||
"Action": ["s3:ListBucket"],
|
||
"Resource": ["arn:aws:s3:::$RUSTFS_BUCKET_NAME"]
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
if ! mc admin policy info rustfs "$RUSTFS_POLICY_NAME" >/dev/null 2>&1; then
|
||
mc admin policy create rustfs "$RUSTFS_POLICY_NAME" /tmp/formbricks-policy.json || \
|
||
mc admin policy add rustfs "$RUSTFS_POLICY_NAME" /tmp/formbricks-policy.json
|
||
fi
|
||
if ! mc admin user info rustfs "$RUSTFS_SERVICE_USER" >/dev/null 2>&1; then
|
||
mc admin user add rustfs "$RUSTFS_SERVICE_USER" "$RUSTFS_SERVICE_PASSWORD"
|
||
fi
|
||
mc admin policy attach rustfs "$RUSTFS_POLICY_NAME" --user "$RUSTFS_SERVICE_USER"
|
||
```
|
||
|
||
Declare the corresponding volume:
|
||
|
||
```yaml
|
||
volumes:
|
||
rustfs-data:
|
||
driver: local
|
||
```
|
||
|
||
Store the generated RustFS credentials in a local `.env` file next to your `docker-compose.yml` instead of
|
||
hardcoding them in Compose:
|
||
|
||
```bash
|
||
FORMBRICKS_RUSTFS_ADMIN_USER=formbricks-root
|
||
FORMBRICKS_RUSTFS_ADMIN_PASSWORD=change-this-secure-password
|
||
FORMBRICKS_RUSTFS_SERVICE_USER=formbricks-service
|
||
FORMBRICKS_RUSTFS_SERVICE_PASSWORD=change-this-service-password
|
||
FORMBRICKS_RUSTFS_BUCKET_NAME=formbricks
|
||
FORMBRICKS_RUSTFS_POLICY_NAME=formbricks-policy
|
||
FORMBRICKS_RUSTFS_REGION=us-east-1
|
||
```
|
||
|
||
Then configure Formbricks to use the RustFS service credentials:
|
||
|
||
```bash
|
||
S3_ACCESS_KEY="${FORMBRICKS_RUSTFS_SERVICE_USER}"
|
||
S3_SECRET_KEY="${FORMBRICKS_RUSTFS_SERVICE_PASSWORD}"
|
||
S3_REGION="${FORMBRICKS_RUSTFS_REGION}"
|
||
S3_BUCKET_NAME="${FORMBRICKS_RUSTFS_BUCKET_NAME}"
|
||
S3_ENDPOINT_URL="http://rustfs:9000"
|
||
S3_FORCE_PATH_STYLE="1"
|
||
```
|
||
|
||
Start the stack:
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
The bucket and service account are created automatically by the `rustfs-init` job defined above, so no manual RustFS console step is required.
|
||
|
||
<Note>
|
||
Restrict the `.env` file to `0600` and do not commit it to source control. For production, prefer the
|
||
[one-click setup script](/self-hosting/setup/one-click), which creates a separate least-privilege service
|
||
account automatically.
|
||
</Note>
|
||
|
||
#### Tips & Common Gotchas
|
||
|
||
- **Permission denied on `/data`**: Ensure the mounted directory or volume is owned by UID `10001`. The
|
||
`rustfs-perms` helper handles this for Compose-managed volumes.
|
||
- **Storage medium matters**: Prefer local SSD or NVMe storage for `rustfs-data`, use XFS on dedicated
|
||
host-managed disks where possible, and avoid NFS or other network filesystems for RustFS data.
|
||
- **Connection refused**: Ensure the `rustfs` container is running and port `9000` is reachable from the
|
||
Formbricks container.
|
||
- **Bucket not found**: Confirm that `rustfs-init` completed successfully or create the bucket manually with
|
||
`mc`.
|
||
- **Auth failed**: Confirm that `S3_ACCESS_KEY` and `S3_SECRET_KEY` match the RustFS credentials configured on
|
||
the server.
|
||
- **Backups**: Back up the `rustfs-data` volume regularly, especially for single-server deployments.
|
||
- **Console exposure**: Do not expose the RustFS console port publicly in production. Keep it on a private
|
||
network or behind admin-only controls.
|
||
- **Health check**: From the Formbricks container:
|
||
|
||
```bash
|
||
docker compose exec formbricks sh -c 'wget -O- http://rustfs:9000/health'
|
||
```
|
||
|
||
### Production Setup with Traefik
|
||
|
||
For production deployments, use the [one-click setup script](/self-hosting/setup/one-click), which
|
||
automatically configures:
|
||
|
||
- RustFS behind Traefik on a dedicated `files.yourdomain.com` subdomain
|
||
- Automatic SSL certificate generation via Let's Encrypt
|
||
- CORS configuration scoped to your Formbricks domain
|
||
- Rate limiting middleware
|
||
- Separate RustFS admin and Formbricks service credentials
|
||
- A `rustfs-init` job that creates the bucket and access policy
|
||
|
||
The production setup from [formbricks.sh](https://github.com/formbricks/formbricks/blob/main/docker/formbricks.sh)
|
||
adds the reverse proxy wiring and bootstrap automation needed for long-lived deployments.
|
||
|
||
<Note>
|
||
Even in the one-click flow, bundled RustFS remains a convenience-oriented single-server deployment. For
|
||
higher availability, stricter operational requirements, or larger storage footprints, prefer external object
|
||
storage or a dedicated RustFS deployment managed separately from Formbricks.
|
||
</Note>
|
||
|
||
## Debug
|
||
|
||
If you encounter any issues, you can check the logs of the container with this command:
|
||
|
||
```bash
|
||
docker compose logs -f
|
||
```
|
||
|
||
In an ideal case, you should see this:
|
||
|
||
```bash
|
||
[+] Running 9/16
|
||
⠹ formbricks 15 layers [⣿⣤⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀] 29.78MB/47.76MB Pulling 13.3s
|
||
✔ 7264a8db6415 Already exists 0.0s
|
||
⠋ 751194035c36 Downloading [===============================> ] 29.78MB/47.76... 8.1s
|
||
✔ eff5dce73b38 Download complete 1.7s
|
||
✔ c8ce5be43019 Download complete 1.2s
|
||
✔ a2f33c630af5 Download complete 5.1s
|
||
✔ e3b64e437860 Download complete 3.3s
|
||
✔ a6551ac5f976 Download complete 4.9s
|
||
✔ 4f4fb700ef54 Download complete 6.0s
|
||
✔ 22163889e16b Download complete 6.7s
|
||
✔ dc647bb9eb13 Download complete 7.8s
|
||
⠋ 49c2ad494720 Waiting 8.1s
|
||
⠋ 5c797a842dcb Waiting 8.1s
|
||
⠋ 1f231213db04 Waiting 8.1s
|
||
⠋ e407294bdcda Waiting 8.1s
|
||
⠋ 6fd8358dca47 Pulling fs layer 8.1s
|
||
|
||
[+] Running 2/2
|
||
✔ Container formbricks-quickstart-postgres-1 Created 0.0s
|
||
✔ Container formbricks-quickstart-formbricks-1 Created 0.0s
|
||
```
|
||
|
||
And at the tail of the output, you should see this:
|
||
|
||
```bash
|
||
formbricks-quickstart-formbricks-1 | All migrations have been successfully applied.
|
||
formbricks-quickstart-formbricks-1 |
|
||
formbricks-quickstart-formbricks-1 | - info Loaded env from /home/nextjs/apps/web/.env
|
||
formbricks-quickstart-formbricks-1 | Listening on port 3000 url: http://<random-string>:3000
|
||
```
|
||
|
||
You can close the logs again by hitting `CTRL + C`.
|
||
|
||
<Note>
|
||
**Customizing environment variables**
|
||
|
||
To edit any of the available environment variables, check out our [Configuration](/self-hosting/configuration/environment-variables) section!
|
||
|
||
</Note>
|
||
|
||
If you have any questions or require help, feel free to reach out to us on [**GitHub Discussions**](https://github.com/formbricks/formbricks/discussions). 😃
|