services: clearflask-connect: image: "ghcr.io/clearflask/clearflask-connect:2.6.3" container_name: ${CONTAINER_NAME} restart: always depends_on: clearflask-server: condition: service_healthy networks: - 1panel-network - clearflask-network ports: - "${PANEL_APP_PORT_HTTP}:9080" entrypoint: - /bin/sh - -c command: - | set -eu install -d -m 755 /opt/clearflask /opt/clearflask-shared i=0 while [ ! -s /opt/clearflask-shared/secrets.env ] && [ "$$i" -lt 120 ]; do i=$$((i + 1)) sleep 1 done if [ ! -s /opt/clearflask-shared/secrets.env ]; then echo "ClearFlask shared secrets were not generated by clearflask-server" >&2 exit 1 fi . /opt/clearflask-shared/secrets.env { printf '%s\n' '{' printf '%s\n' ' "listenPort": 9080,' printf ' "connectToken": "%s",\n' "$$CLEARFLASK_CONNECT_TOKEN" printf '%s\n' ' "disableAutoFetchCertificate": true,' printf ' "forceRedirectHttpToHttps": %s,\n' "$$CLEARFLASK_AUTH_COOKIE_SECURE" printf ' "parentDomain": "%s",\n' "$$CLEARFLASK_DOMAIN" printf '%s\n' ' "apiBasePath": "http://clearflask-server:8080",' printf '%s\n' ' "publicPath": "/srv/clearflask-connect/public",' printf '%s\n' ' "gitlabClientId": null,' printf '%s\n' ' "jiraClientId": null,' printf '%s\n' ' "slackClientId": null' printf '%s\n' '}' } > /opt/clearflask/connect.config.json exec ./start.sh environment: - TZ=${TZ} - NODE_ENV=production - ENV=selfhost - CLEARFLASK_DOMAIN=${CLEARFLASK_DOMAIN} - CLEARFLASK_AUTH_COOKIE_SECURE=${CLEARFLASK_AUTH_COOKIE_SECURE} volumes: - "${APP_DATA_DIR}/connect:/opt/clearflask" - "${APP_DATA_DIR}/shared:/opt/clearflask-shared" healthcheck: test: ["CMD-SHELL", "node -e \"require('http').get('http://127.0.0.1:9080/', r => process.exit(r.statusCode < 500 ? 0 : 1)).on('error', () => process.exit(1))\""] interval: 10s timeout: 5s retries: 20 start_period: 30s labels: createdBy: "Apps" clearflask-server: image: "ghcr.io/clearflask/clearflask-server:2.6.3" container_name: ${CONTAINER_NAME}-server restart: always depends_on: clearflask-mysql: condition: service_healthy clearflask-localstack: condition: service_started clearflask-mailpit: condition: service_started networks: - clearflask-network entrypoint: - /bin/sh - -c command: - | set -eu install -d -m 755 /opt/clearflask /opt/clearflask-shared if [ ! -s /opt/clearflask-shared/secrets.env ]; then umask 077 tmp=/opt/clearflask-shared/secrets.env.tmp { printf 'CLEARFLASK_TOKEN_SIGNER=%s\n' "$$(openssl rand -base64 172 | tr -d '\n')" printf 'CLEARFLASK_CURSOR_KEY=%s\n' "$$(openssl rand -base64 16)" printf 'CLEARFLASK_SSO_SECRET=%s\n' "$$(cat /proc/sys/kernel/random/uuid)" printf 'CLEARFLASK_CONNECT_TOKEN=%s\n' "$$(cat /proc/sys/kernel/random/uuid)" } > "$$tmp" mv "$$tmp" /opt/clearflask-shared/secrets.env fi . /opt/clearflask-shared/secrets.env { printf '%s\n' 'com.smotana.clearflask.security.limiter.challenge.CaptchaChallenger$$Config.enabled=false' printf '%s\n' 'com.smotana.clearflask.store.dynamo.DefaultDynamoDbProvider$$Config.serviceEndpoint=http://localstack:4566' printf '%s\n' 'com.smotana.clearflask.store.dynamo.DefaultDynamoDbProvider$$Config.signingRegion=us-east-1' printf '%s\n' 'com.smotana.clearflask.store.dynamo.DefaultDynamoDbProvider$$Config.productionRegion=us-east-1' printf '%s\n' 'com.smotana.clearflask.store.mysql.DefaultMysqlProvider$$Config.host=clearflask-mysql' printf '%s\n' 'com.smotana.clearflask.store.mysql.DefaultMysqlProvider$$Config.port=3306' printf '%s\n' 'com.smotana.clearflask.store.mysql.DefaultMysqlProvider$$Config.databaseName=clearflask' printf '%s\n' 'com.smotana.clearflask.store.mysql.DefaultMysqlProvider$$Config.user=root' printf 'com.smotana.clearflask.store.mysql.DefaultMysqlProvider$$Config.pass=%s\n' "$$MYSQL_ROOT_PASSWORD" printf '%s\n' 'com.smotana.clearflask.core.push.provider.BrowserPushServiceImpl$$Config.publicKey=BI_27q_GDMSYPCoLc5rPUyBMQ3CMUCmjfblbqVoDNcl2CRCAUmtCSgU2-g8SdaJlCqTFBi0Z1eU4maehFNX595M=' printf '%s\n' 'com.smotana.clearflask.core.push.provider.BrowserPushServiceImpl$$Config.privateKey=AKBBxKqCjroXt2ohL8yHSEpREoRzmtBb6Zk0g4zEDp4H' printf 'com.smotana.clearflask.util.DefaultServerSecret$$Config.sharedKey:cursor=%s\n' "$$CLEARFLASK_CURSOR_KEY" printf 'com.smotana.clearflask.store.impl.DynamoElasticUserStore$$Config.tokenSignerPrivKey=%s\n' "$$CLEARFLASK_TOKEN_SIGNER" printf 'com.smotana.clearflask.web.Application$$Config.domain=%s\n' "$$CLEARFLASK_DOMAIN" printf '%s\n' 'com.smotana.clearflask.web.Application$$Config.defaultSearchEngine=READWRITE_MYSQL' printf 'com.smotana.clearflask.web.security.AuthCookieImpl$$Config.authCookieSecure=%s\n' "$$CLEARFLASK_AUTH_COOKIE_SECURE" printf '%s\n' 'com.smotana.clearflask.web.Application$$Config.startupWaitUntilDeps=true' printf '%s\n' 'com.smotana.clearflask.web.Application$$Config.createIndexesOnStartup=true' printf 'com.smotana.clearflask.security.ClearFlaskSso$$Config.secretKey=%s\n' "$$CLEARFLASK_SSO_SECRET" printf 'com.smotana.clearflask.web.security.SuperAdminPredicate$$Config.superAdminEmailRegex=%s\n' "$$CLEARFLASK_SUPER_ADMIN_EMAIL_REGEX" printf 'com.smotana.clearflask.web.resource.AccountResource$$Config.signupEnabled=%s\n' "$$CLEARFLASK_SIGNUP_ENABLED" printf 'com.smotana.clearflask.web.security.AuthenticationFilter$$Config.connectToken=%s\n' "$$CLEARFLASK_CONNECT_TOKEN" if [ "$$EMAIL_SERVICE" = "smtp" ]; then printf '%s\n' 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.useService=smtp' printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.smtpStrategy=%s\n' "$$SMTP_STRATEGY" printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.smtpHost=%s\n' "$$SMTP_HOST" printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.smtpPort=%s\n' "$$SMTP_PORT" if [ -n "$$SMTP_USER" ]; then printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.smtpUser=%s\n' "$$SMTP_USER" fi if [ -n "$$SMTP_PASSWORD" ]; then printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.smtpPassword=%s\n' "$$SMTP_PASSWORD" fi printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.emailDisplayName=%s\n' "$$SMTP_DISPLAY_NAME" printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.fromEmailLocalPart=%s\n' "$$SMTP_FROM_LOCAL_PART" printf 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.fromEmailDomainOverride=%s\n' "$$SMTP_FROM_DOMAIN_OVERRIDE" else printf '%s\n' 'com.smotana.clearflask.core.push.provider.EmailServiceImpl$$Config.useService=ses' printf '%s\n' 'com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$$Config.region=us-east-1' printf '%s\n' 'com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$$Config.serviceEndpoint=http://localstack:4566' fi printf '%s\n' 'com.smotana.clearflask.store.s3.DefaultS3ClientProvider$$Config.serviceEndpoint=http://s3.localhost.localstack.cloud:4566' printf '%s\n' 'com.smotana.clearflask.store.s3.DefaultS3ClientProvider$$Config.signingRegion=us-east-1' printf '%s\n' 'com.smotana.clearflask.store.s3.DefaultS3ClientProvider$$Config.dnsResolverTo=localstack' printf '%s\n' 'com.smotana.clearflask.store.s3.DefaultS3ClientProvider$$Config.productionRegion=us-east-1' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.hostname=local-upload.s3.localhost.localstack.cloud:4566' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.bucketName=local-upload' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.scheme=http' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.createBucket=true' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.proxyEnabled=true' printf '%s\n' 'com.smotana.clearflask.store.impl.S3ContentStore$$Config.proxyResolveTo=localstack' printf '%s\n' 'com.smotana.clearflask.store.ConfigAwsCredentialsProvider$$Config.awsAccessKeyId=test' printf '%s\n' 'com.smotana.clearflask.store.ConfigAwsCredentialsProvider$$Config.awsSecretKey=test' printf '%s\n' 'com.smotana.clearflask.store.github.GitHubStoreImpl$$Config.enabled=false' } > /opt/clearflask/config-selfhost.cfg chmod 600 /opt/clearflask-shared/secrets.env /opt/clearflask/config-selfhost.cfg exec catalina.sh run environment: - TZ=${TZ} - CLEARFLASK_ENVIRONMENT=PRODUCTION_SELF_HOST - CLEARFLASK_DOMAIN=${CLEARFLASK_DOMAIN} - CLEARFLASK_SUPER_ADMIN_EMAIL_REGEX=${CLEARFLASK_SUPER_ADMIN_EMAIL_REGEX} - CLEARFLASK_SIGNUP_ENABLED=${CLEARFLASK_SIGNUP_ENABLED} - CLEARFLASK_AUTH_COOKIE_SECURE=${CLEARFLASK_AUTH_COOKIE_SECURE} - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - EMAIL_SERVICE=${EMAIL_SERVICE} - SMTP_STRATEGY=${SMTP_STRATEGY} - SMTP_HOST=${SMTP_HOST} - SMTP_PORT=${SMTP_PORT} - SMTP_USER=${SMTP_USER} - SMTP_PASSWORD=${SMTP_PASSWORD} - SMTP_DISPLAY_NAME=${SMTP_DISPLAY_NAME} - SMTP_FROM_LOCAL_PART=${SMTP_FROM_LOCAL_PART} - SMTP_FROM_DOMAIN_OVERRIDE=${SMTP_FROM_DOMAIN_OVERRIDE} volumes: - "${APP_DATA_DIR}/server:/opt/clearflask" - "${APP_DATA_DIR}/shared:/opt/clearflask-shared" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"] interval: 10s timeout: 15s retries: 30 start_period: 60s labels: createdBy: "Apps" clearflask-mysql: image: "mariadb:10.5" container_name: ${CONTAINER_NAME}-mysql restart: always networks: - clearflask-network command: - mysqld - --port=3306 - --sql-mode=IGNORE_SPACE - --explicit-defaults-for-timestamp - --secure-file-priv=/tmp environment: - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} volumes: - "${APP_DATA_DIR}/mysql:/var/lib/mysql" healthcheck: test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p\"$${MYSQL_ROOT_PASSWORD}\" --silent"] interval: 10s timeout: 5s retries: 20 labels: createdBy: "Apps" clearflask-localstack: image: "localstack/localstack:0.14.3" container_name: ${CONTAINER_NAME}-localstack restart: always networks: clearflask-network: aliases: - localstack - s3.localhost.localstack.cloud - local-upload.s3.localhost.localstack.cloud expose: - 4566 - 4571 environment: - DEFAULT_REGION=us-east-1 - LOCALSTACK_HOSTNAME=localstack - HOSTNAME_EXTERNAL=localstack - SERVICES=dynamodb,ses,s3 - LS_LOG=warn - START_WEB=0 - USE_SSL=0 - FORCE_NONINTERACTIVE=true - DATA_DIR=/tmp/localstack/data - LEGACY_PERSISTENCE=1 volumes: - "${APP_DATA_DIR}/localstack:/tmp/localstack" labels: createdBy: "Apps" clearflask-mailpit: image: "axllent/mailpit:v1.30.3" container_name: ${CONTAINER_NAME}-mailpit restart: always networks: clearflask-network: aliases: - clearflask-mailpit ports: - "${PANEL_APP_PORT_MAILPIT}:8025" labels: createdBy: "Apps" networks: 1panel-network: external: true clearflask-network: driver: bridge