module main import os // install_docker_stack generates a docker-compose.yml + config files in target_dir. // When with_prometheus is true, also generates prometheus.yml and adds a prometheus service. fn install_docker_stack(target_dir string, with_prometheus bool) ! { os.mkdir_all(target_dir) or { return error('Cannot create ${target_dir}: ${err}') } // ntfy-bridge config example_cfg := '# ntfy-bridge configuration server: port: 9090 hmac_secret: "change-me-to-a-random-string" defaults: priority: 3 tags: ["bell"] sources: generic: [] gitea: [] uptime_kuma: [] docker: [] http_poll: [] cron: [] dedup: enabled: false filters: rules: [] outgoing: webhooks: [] state: file: "/data/state.json" ' os.write_file('${target_dir}/ntfy-bridge.yaml', example_cfg) or { return error('Failed to write config: ${err}') } println(' Wrote: ${target_dir}/ntfy-bridge.yaml') // Copy dashboard if os.exists('dashboard.html') { os.cp('dashboard.html', '${target_dir}/dashboard.html') or { println(' Warning: could not copy dashboard.html') } println(' Wrote: ${target_dir}/dashboard.html') } // Dockerfile for reference (binary must be built separately) if os.exists('Dockerfile') { os.cp('Dockerfile', '${target_dir}/Dockerfile') or {} println(' Wrote: ${target_dir}/Dockerfile') } println(' Note: Place a Linux binary named "ntfy-bridge" in ${target_dir}/ to build.') println(' Build: v -os linux -o ${target_dir}/ntfy-bridge . (requires Linux or WSL)') // docker-compose.yml mut compose := 'services: ntfy-bridge: build: . container_name: ntfy-bridge restart: unless-stopped ports: - "9090:9090" volumes: - ./ntfy-bridge.yaml:/etc/ntfy-bridge/ntfy-bridge.yaml:ro - ./dashboard.html:/etc/ntfy-bridge/dashboard.html:ro - ntfy-data:/data environment: - NTFY_TOKEN=\${NTFY_TOKEN:-} - NTFY_HMAC_SECRET=\${NTFY_HMAC_SECRET:-} healthcheck: test: ["CMD", "wget", "--spider", "http://localhost:9090/health"] interval: 30s timeout: 5s retries: 3 ' if with_prometheus { compose += ' prometheus: image: prom/prometheus:latest container_name: ntfy-prometheus restart: unless-stopped ports: - "9091:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - prom-data:/prometheus command: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" volumes: ntfy-data: ' if with_prometheus { compose += ' prom-data: ' } } else { compose += ' volumes: ntfy-data: ' } os.write_file('${target_dir}/docker-compose.yml', compose) or { return error('Failed to write docker-compose.yml: ${err}') } println(' Wrote: ${target_dir}/docker-compose.yml') // Prometheus config if with_prometheus { prom_cfg := '# Prometheus configuration for ntfy-bridge monitoring global: scrape_interval: 15s scrape_configs: - job_name: "ntfy-bridge" metrics_path: /metrics static_configs: - targets: ["ntfy-bridge:9090"] ' os.write_file('${target_dir}/prometheus.yml', prom_cfg) or { return error('Failed to write prometheus.yml: ${err}') } println(' Wrote: ${target_dir}/prometheus.yml') } println('') println('Stack generated in ${target_dir}/') println('') println('Next steps:') println(' 1. Edit ${target_dir}/ntfy-bridge.yaml to configure your sources') println(' 2. cd ${target_dir} && docker compose up -d') if with_prometheus { println(' 3. Prometheus: http://localhost:9091/') println(' 4. Add Prometheus as a Grafana data source') } }