From 31bff09eaaf3f0ca134579013f3591c249d7f843 Mon Sep 17 00:00:00 2001 From: luolink <97769040+abel-yelin@users.noreply.github.com> Date: Wed, 8 Jul 2026 05:44:36 +0800 Subject: [PATCH] Add Marketing Dashboard template (#861) --- .../marketing-dashboard/docker-compose.yml | 47 +++++++++++++++++++ blueprints/marketing-dashboard/logo.svg | 8 ++++ blueprints/marketing-dashboard/template.toml | 30 ++++++++++++ meta.json | 19 ++++++++ 4 files changed, 104 insertions(+) create mode 100644 blueprints/marketing-dashboard/docker-compose.yml create mode 100644 blueprints/marketing-dashboard/logo.svg create mode 100644 blueprints/marketing-dashboard/template.toml diff --git a/blueprints/marketing-dashboard/docker-compose.yml b/blueprints/marketing-dashboard/docker-compose.yml new file mode 100644 index 00000000..637849e7 --- /dev/null +++ b/blueprints/marketing-dashboard/docker-compose.yml @@ -0,0 +1,47 @@ +services: + marketing-dashboard: + image: ghcr.io/abel-yelin/marketing-dashboard:latest + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + environment: + DATABASE_URL: ${DATABASE_URL} + DIRECT_URL: ${DIRECT_URL} + MARKETING_APP_URL: ${MARKETING_APP_URL} + MARKETING_COLLECTOR_UPSTREAM_URL: ${MARKETING_COLLECTOR_UPSTREAM_URL} + MARKETING_SESSION_TIMEOUT_MINUTES: ${MARKETING_SESSION_TIMEOUT_MINUTES} + MARKETING_PROXY_TIMEOUT_MS: ${MARKETING_PROXY_TIMEOUT_MS} + MARKETING_INGEST_MAX_BODY_BYTES: ${MARKETING_INGEST_MAX_BODY_BYTES} + MARKETING_INGEST_IP_RATE_LIMIT: ${MARKETING_INGEST_IP_RATE_LIMIT} + MARKETING_INGEST_CLIENT_RATE_LIMIT: ${MARKETING_INGEST_CLIENT_RATE_LIMIT} + MARKETING_INGEST_RATE_LIMIT_WINDOW_MS: ${MARKETING_INGEST_RATE_LIMIT_WINDOW_MS} + MARKETING_ENABLE_PILOT_API: ${MARKETING_ENABLE_PILOT_API} + MARKETING_DASHBOARD_ADMIN_USER: ${MARKETING_DASHBOARD_ADMIN_USER} + MARKETING_DASHBOARD_ADMIN_PASSWORD: ${MARKETING_DASHBOARD_ADMIN_PASSWORD} + ports: + - 3000 + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://localhost:3000/api/health > /dev/null || exit 1"] + interval: 15s + timeout: 5s + retries: 10 + start_period: 30s + + postgres: + image: postgres:16 + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - marketing-dashboard-postgres:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U \"$${POSTGRES_USER}\" -d \"$${POSTGRES_DB}\""] + interval: 10s + timeout: 5s + retries: 10 + +volumes: + marketing-dashboard-postgres: diff --git a/blueprints/marketing-dashboard/logo.svg b/blueprints/marketing-dashboard/logo.svg new file mode 100644 index 00000000..07a4ae88 --- /dev/null +++ b/blueprints/marketing-dashboard/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/blueprints/marketing-dashboard/template.toml b/blueprints/marketing-dashboard/template.toml new file mode 100644 index 00000000..531874ea --- /dev/null +++ b/blueprints/marketing-dashboard/template.toml @@ -0,0 +1,30 @@ +[variables] +main_domain = "${domain}" +postgres_password = "${password:32}" +admin_password = "${password:32}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "marketing-dashboard" +port = 3000 +host = "${main_domain}" + +[config.env] +POSTGRES_DB = "marketing_dashboard" +POSTGRES_USER = "marketing_dashboard" +POSTGRES_PASSWORD = "${postgres_password}" +DATABASE_URL = "postgresql://marketing_dashboard:${postgres_password}@postgres:5432/marketing_dashboard?schema=public" +DIRECT_URL = "postgresql://marketing_dashboard:${postgres_password}@postgres:5432/marketing_dashboard?schema=public" +MARKETING_APP_URL = "https://${main_domain}" +MARKETING_COLLECTOR_UPSTREAM_URL = "https://${main_domain}/api/ingest/browser" +MARKETING_SESSION_TIMEOUT_MINUTES = "30" +MARKETING_PROXY_TIMEOUT_MS = "4000" +MARKETING_INGEST_MAX_BODY_BYTES = "65536" +MARKETING_INGEST_IP_RATE_LIMIT = "300" +MARKETING_INGEST_CLIENT_RATE_LIMIT = "1200" +MARKETING_INGEST_RATE_LIMIT_WINDOW_MS = "60000" +MARKETING_ENABLE_PILOT_API = "false" +MARKETING_DASHBOARD_ADMIN_USER = "admin" +MARKETING_DASHBOARD_ADMIN_PASSWORD = "${admin_password}" diff --git a/meta.json b/meta.json index 653a7985..6e2a3a34 100644 --- a/meta.json +++ b/meta.json @@ -4245,6 +4245,25 @@ "smtp" ] }, + { + "id": "marketing-dashboard", + "name": "Marketing Dashboard", + "version": "latest", + "description": "Self-hosted marketing operations dashboard for product-led growth, checkout analytics, paid media, SEO signals, and Stripe readiness.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/abel-yelin/marketing-dashboard", + "website": "https://github.com/abel-yelin/marketing-dashboard", + "docs": "https://github.com/abel-yelin/marketing-dashboard/blob/main/docs/production-deployment.md" + }, + "tags": [ + "analytics", + "marketing", + "self-hosted", + "postgresql", + "nextjs" + ] + }, { "id": "mattermost", "name": "Mattermost",