Support our open-source development by choosing cloud hosting with scalable pricing, check us out on our website.
For a quick start using Docker, download
the Docker Compose service file
as docker-compose.yml, and run the following:
docker-compose --profile with-deps upPoint your browser at http://localhost and create an account using email admin@localhost.
You also want to setup outgoing mail, read the Email section.
If you wish to host it on your domain other than localhost, read the DNS section and then
setup SSL/TLS certificates.
For self-hosting, we provide Kubernetes Helm charts.
- Add the Helm repository:
helm repo add clearflask https://clearflask.github.io/clearflask
helm repo update- Install dependencies (MySQL + LocalStack):
helm install clearflask-deps clearflask/clearflask-dependencies \
--set mysql.enabled=true \
--set localstack.enabled=true- Generate secrets and install ClearFlask:
TOKEN_SIGNER=$(openssl rand -base64 172 | tr -d '\n')
CURSOR_KEY=$(openssl rand -base64 16)
SSO_SECRET=$(uuidgen)
CONNECT_TOKEN=$(uuidgen)
helm install clearflask clearflask/clearflask \
--set global.domain=yourdomain.com \
--set server.config.searchEngine=READWRITE_MYSQL \
--set server.secrets.tokenSignerPrivKey="$TOKEN_SIGNER" \
--set server.secrets.cursorSharedKey="$CURSOR_KEY" \
--set server.secrets.ssoSecretKey="$SSO_SECRET" \
--set server.secrets.connectToken="$CONNECT_TOKEN"- Access your instance:
kubectl port-forward svc/clearflask-connect 3000:80
# Visit http://localhost:3000See the Helm Chart documentation for more information.
There are several dependencies that you can swap out for ClearFlask:
- AWS DynamoDB or Localstack or API-compatible alternative (ScyllaDB is not fully compatible)
- MinIO or AWS S3 or API-compatible alternative
- One of:
- MySQL or Aurora
- ElasticSearch or OpenSearch
- Email service via SMTP or AWS SES
And a few optional:
- Google ReCaptcha
- Let's Encrypt automagic certificate management
- CloudFront as a CDN (Use in front of
clearflask-connect)
You can spin up all dependencies via Docker.
Simply add the --profile with-deps to your docker-compose command when starting ClearFlask.
All database content will be persisted to local filesystem under data folder.
Production-ready Helm charts are available:
helm repo add clearflask https://clearflask.github.io/clearflask
helm repo update
helm install clearflask-deps clearflask/clearflask-dependencies \
--set mysql.enabled=true \
--set localstack.enabled=trueThis deploys:
- MySQL/MariaDB for search and filtering with persistent storage (20Gi default)
- LocalStack for DynamoDB, S3, and SES emulation with persistent storage (10Gi default)
- ElasticSearch (optional) for advanced search with persistent storage (50Gi default)
All databases are persistent by default using PersistentVolumeClaims. See the Helm Chart documentation for configuration options.
For production workload, you will want to spin up these dependencies yourself and point ClearFlask to their endpoints.
For AWS services, clearflask-server auto-detects Access Keys using either a configuration property or the default
locations. If you are running in EC2 or ECS, keys detection is automated, you just need to create the appropriate IAM
role.
Provide IAM access including create table permission as table is created automatically by ClearFlask on startup.
IAM actions:
- CreateTable
- BatchGetItem
- GetItem
- Query
- BatchWriteItem
- DeleteItem
- PutItem
- UpdateItem
Create a private bucket with IAM access to ClearFlask.
IAM actions:
- ListBucket
- GetObject
- DeleteObject
- PutObject
You can also use an API-compatible alternative service such as Wasabi, MinIO...
Recommended is AWS ES, give the proper IAM access
IAM actions, all in these categories:
- List
- Read
- Write
- Tagging
Alternatively you can deploy it yourself (cheaper) or host it on Elastic. Or you can choose to use MySQL/Aurora as a cheaper alternative.
In order to setup SES, you need to seek limit increase via AWS support.
Change the config property ...EmailServiceImpl$Config.useService to ses and give the proper IAM access.
IAM actions:
- SendEmail
- SendRawEmail
Alternatively use any other email provider and fill out the SMTP settings
ClearFlask consists of two components:
- clearflask-server: Tomcat application for serving API requests
- clearflask-connect: NodeJS for SSR, dynamic cert management and serving static files
No build required - uses pre-built Docker images.
# Add Helm repository
helm repo add clearflask https://clearflask.github.io/clearflask
helm repo update
# Generate required secrets
TOKEN_SIGNER=$(openssl rand -base64 172 | tr -d '\n')
CURSOR_KEY=$(openssl rand -base64 16)
SSO_SECRET=$(uuidgen)
CONNECT_TOKEN=$(uuidgen)
# Install ClearFlask
helm install clearflask clearflask/clearflask \
--set global.domain=yourdomain.com \
--set server.config.searchEngine=READWRITE_MYSQL \
--set server.secrets.tokenSignerPrivKey="$TOKEN_SIGNER" \
--set server.secrets.cursorSharedKey="$CURSOR_KEY" \
--set server.secrets.ssoSecretKey="$SSO_SECRET" \
--set server.secrets.connectToken="$CONNECT_TOKEN"Features:
- Horizontal Pod Autoscaling
- Zero-downtime rolling updates
- Built-in health checks
- TLS certificate management
For detailed configuration options, deployment scenarios (AWS EKS, GKE, AKS), and troubleshooting, see the Helm Chart documentation.
- Download the Docker Compose service file
- Run it with
docker-compose --profile with-deps upwhich creates few configuration files in your local directory - Carefully read and modify
server/config-selfhost.cfg. - Carefully read and modify
connect/connect.config.json. - Adjust the Docker Compose service file to add/remove dependencies if you are hosting them outside of Docker
By default, email is configured for AWS SES pointing to your Localstack (which doesn't do anything).
You can choose to setup your own SMTP server or use AWS SES.
Change the configuration to SMTP:
com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.useService:smtp
Then you need to gather your SMTP settings and fill out the following:
com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpStrategy:SMTP_TLS(SMTP_TLS, SMTPS, SMTP)com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpHost:smtp.gmail.com(e.g. smtp.gmail.com)com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpPort:587(587 for SMTP_TLS, 465 for SMTPS, 25 for SMTP)com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpUser:[email protected](e.g. [email protected])com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpPassword:asdfqwerzxcvasdf(To get this working, you need to enable IMAP if not enabled. If you use 2FA, you need to generate an app password and use it here)com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.emailDisplayName:ClearFlask(e.g. 'ClearFlask for MyCompany')com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.fromEmailLocalPart:my.name(first part of your email, for [email protected], it would be 'my.name')com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.fromEmailDomainOverride:gmail.com(domain part of your email, for [email protected], it would be 'gmail.com')
Change the configuration to SMTP:
com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.useService:ses
Then fill out the SES settings:
com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$Config.region:us-east-1com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$Config.serviceEndpoint: (Leave blank, unless you need to override)
By default, everything is assumed to be on localhost. If you wish to host your portal on yoursite.com
or 192.168.1.123, set the following properties:
connect.config.json:parentDomain:yoursite.comconfig-selfhost.cfg:com.smotana.clearflask.web.Application$Config.domain:yoursite.com
If you wish to have certificates fetched and renewed for you automagically using Let's Encrypt, ensure your DNS is correctly pointing to your server, it is publicly accessible, and set the following config parameters:
connect.config.json:disableAutoFetchCertificate:falseconnect.config.json:forceRedirectHttpToHttps:trueconfig-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure:true
Once you load your site for the first time, a Certificate is auto-magically fetched for you.
If you wish to use your own certificate, set the following properties:
connect.config.json:disableAutoFetchCertificate:falseconnect.config.json:forceRedirectHttpToHttps:trueconfig-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure:trueconfig-selfhost.cfg:com.smotana.clearflask.security.CertFetcherImpl$Config.staticCert:<SEE BELOW>
For the staticCert property value, this has to be a JSON object with the following structure, but you need to put it
in a single line:
{
"cert": {
"cert": "-----BEGIN CERTIFICATE-----\nMIIFFjCC...",
"chain": "-----BEGIN CERTIFICATE-----\nMIIE/jCC",
"subject": "feedback.example.com",
"altnames": [
"feedback.example.com"
],
"issuedAt": 1709572939000,
"expiresAt": 1741108939000
},
"keypair": {
"privateKeyPem": "-----BEGIN PRIVATE KEY-----\nMIIEvwIB..."
}
}Note that you have to put this into a single line. The cert, chain and keypair will replace any literal \n into a
newline.
This approach is not recommended as you will have to update this certificate manually.
ClearFlask wasn't designed to be deployed on a subpath (e.g. example.com/clearflask/), rather it is
intended to be deployed either directly on a domain or a subdomain. (e.g. examplefeedback.com or
feedback.example.com)
If you are managing TLS certificates behind a reverse proxy, redirect all http requests to https, set the following
config:
connect.config.json:disableAutoFetchCertificate:trueconnect.config.json:forceRedirectHttpToHttps:trueconfig-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure:true
Although discouraged, you can run ClearFlask over HTTP only. Ensure these settings are set:
connect.config.json:disableAutoFetchCertificate:trueconnect.config.json:forceRedirectHttpToHttps:falseconfig-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure:false