diff --git a/.gitignore b/.gitignore index c0cadd7c..2f8606a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ node_modules package-lock.json meta.json.backup.* - diff --git a/AGENTS.md b/AGENTS.md index c34d6beb..753da746 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -170,6 +170,16 @@ This document provides essential context for AI models interacting with this pro - **Env:** Array of strings: `env = ["KEY=VALUE", "DB_PASSWORD=${db_pass}"]` - **Available helpers:** `${domain}`, `${password:length}`, `${base64:length}`, `${hash:length}`, `${uuid}`, `${randomPort}`, `${email}`, `${username}`, `${timestamp}`, `${timestamps:datetime}`, `${timestampms:datetime}`, `${jwt:secret_var:payload_var}` - **JWT helper example:** `${jwt:mysecret:mypayload}` with payload containing `exp: ${timestamps:2030-01-01T00:00:00Z}` + - **Volume bind mounts (in docker-compose.yml):** When mounting host paths, do NOT use absolute paths like `"/folder:/path/in/container"`. Use relative paths instead: + ```yaml + # Invalid + volumes: + - "/folder:/path/in/container" ❌ + # Valid + volumes: + - "../files/my-database:/var/lib/mysql" ✅ + - "../files/my-configs:/etc/my-app/config" ✅ + ``` - **meta.json Requirements:** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2671d5af..967ef6f2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,11 @@ This project adheres to the [Contributor Covenant Code of Conduct](https://www.c For larger changes or questions, open an issue first to discuss your ideas. +### Pull Request Guidelines + +- **Keep PRs small and focused.** Avoid very large PRs; prefer several smaller PRs (e.g., one template or one logical change per PR). This speeds up review and keeps the history clear. +- **Test before submitting.** Any PR that has not been tested by the contributor will be closed. This keeps the PR queue tidy and ensures that only contributions that have been verified by their authors are considered. + ## Adding a New Template To add a new template, follow these steps: diff --git a/blueprints/ackee/instructions.md b/blueprints/ackee/instructions.md new file mode 100644 index 00000000..b107d360 --- /dev/null +++ b/blueprints/ackee/instructions.md @@ -0,0 +1,4 @@ + +## Instructions + +We don't have nothing to show here.... diff --git a/blueprints/appwrite/docker-compose.yml b/blueprints/appwrite/docker-compose.yml index 130bb5d3..cb622284 100644 --- a/blueprints/appwrite/docker-compose.yml +++ b/blueprints/appwrite/docker-compose.yml @@ -6,31 +6,32 @@ x-logging: &x-logging options: max-file: "5" max-size: "10m" - services: appwrite: - image: appwrite/appwrite:1.6.1 - container_name: appwrite + image: appwrite/appwrite:1.8.0 <<: *x-logging restart: unless-stopped - networks: - - dokploy-network labels: - traefik.enable=true - traefik.constraint-label-stack=appwrite volumes: - appwrite-uploads:/storage/uploads:rw + - appwrite-imports:/storage/imports:rw - appwrite-cache:/storage/cache:rw - appwrite-config:/storage/config:rw - appwrite-certificates:/storage/certificates:rw - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw + - appwrite-builds:/storage/builds:rw depends_on: - mariadb - redis + # - clamav environment: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_LOCALE + - _APP_COMPRESSION_MIN_SIZE_BYTES - _APP_CONSOLE_WHITELIST_ROOT - _APP_CONSOLE_WHITELIST_EMAILS - _APP_CONSOLE_SESSION_ALERTS @@ -43,10 +44,14 @@ services: - _APP_OPTIONS_ABUSE - _APP_OPTIONS_ROUTER_PROTECTION - _APP_OPTIONS_FORCE_HTTPS - - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS + - _APP_OPTIONS_ROUTER_FORCE_HTTPS - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - - _APP_DOMAIN_TARGET + - _APP_DOMAIN_TARGET_CNAME + - _APP_DOMAIN_TARGET_AAAA + - _APP_DOMAIN_TARGET_A + - _APP_DOMAIN_TARGET_CAA + - _APP_DNS - _APP_DOMAIN_FUNCTIONS - _APP_REDIS_HOST - _APP_REDIS_PORT @@ -73,6 +78,7 @@ services: - _APP_STORAGE_S3_SECRET - _APP_STORAGE_S3_REGION - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_S3_ENDPOINT - _APP_STORAGE_DO_SPACES_ACCESS_KEY - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION @@ -89,21 +95,26 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET - - _APP_FUNCTIONS_SIZE_LIMIT + - _APP_COMPUTE_SIZE_LIMIT - _APP_FUNCTIONS_TIMEOUT - - _APP_FUNCTIONS_BUILD_TIMEOUT - - _APP_FUNCTIONS_CPUS - - _APP_FUNCTIONS_MEMORY + - _APP_SITES_TIMEOUT + - _APP_COMPUTE_BUILD_TIMEOUT + - _APP_COMPUTE_CPUS + - _APP_COMPUTE_MEMORY - _APP_FUNCTIONS_RUNTIMES + - _APP_SITES_RUNTIMES + - _APP_DOMAIN_SITES - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST - _APP_LOGGING_CONFIG - _APP_MAINTENANCE_INTERVAL - _APP_MAINTENANCE_DELAY + - _APP_MAINTENANCE_START_TIME - _APP_MAINTENANCE_RETENTION_EXECUTION - _APP_MAINTENANCE_RETENTION_CACHE - _APP_MAINTENANCE_RETENTION_ABUSE - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - _APP_SMS_PROVIDER @@ -120,94 +131,25 @@ services: - _APP_MIGRATIONS_FIREBASE_CLIENT_ID - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET - _APP_ASSISTANT_OPENAI_API_KEY - appwrite-console: - image: appwrite/console:5.0.12 - container_name: appwrite-console <<: *x-logging + image: appwrite/console:7.4.7 restart: unless-stopped - networks: - - dokploy-network labels: - "traefik.enable=true" - "traefik.constraint-label-stack=appwrite" - environment: - - _APP_ENV - - _APP_WORKER_PER_CORE - - _APP_LOCALE - - _APP_CONSOLE_WHITELIST_ROOT - - _APP_CONSOLE_WHITELIST_EMAILS - - _APP_CONSOLE_SESSION_ALERTS - - _APP_CONSOLE_WHITELIST_IPS - - _APP_CONSOLE_HOSTNAMES - - _APP_SYSTEM_EMAIL_NAME - - _APP_SYSTEM_EMAIL_ADDRESS - - _APP_EMAIL_SECURITY - - _APP_SYSTEM_RESPONSE_FORMAT - - _APP_OPTIONS_ABUSE - - _APP_OPTIONS_ROUTER_PROTECTION - - _APP_OPTIONS_FORCE_HTTPS - - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS - - _APP_OPENSSL_KEY_V1 - - _APP_DOMAIN - - _APP_DOMAIN_TARGET - - _APP_DOMAIN_FUNCTIONS - - _APP_REDIS_HOST - - _APP_REDIS_PORT - - _APP_REDIS_USER - - _APP_REDIS_PASS - - _APP_DB_HOST - - _APP_DB_PORT - - _APP_DB_SCHEMA - - _APP_DB_USER - - _APP_DB_PASS - - _APP_SMTP_HOST - - _APP_SMTP_PORT - - _APP_SMTP_SECURE - - _APP_SMTP_USERNAME - - _APP_SMTP_PASSWORD - - _APP_USAGE_STATS - - _APP_STORAGE_LIMIT - - _APP_STORAGE_PREVIEW_LIMIT - - _APP_STORAGE_ANTIVIRUS - - _APP_STORAGE_ANTIVIRUS_HOST - - _APP_STORAGE_ANTIVIRUS_PORT - - _APP_STORAGE_DEVICE - - _APP_STORAGE_S3_ACCESS_KEY - - _APP_STORAGE_S3_SECRET - - _APP_STORAGE_S3_REGION - - _APP_STORAGE_S3_BUCKET - - _APP_STORAGE_DO_SPACES_ACCESS_KEY - - _APP_STORAGE_DO_SPACES_SECRET - - _APP_STORAGE_DO_SPACES_REGION - - _APP_STORAGE_DO_SPACES_BUCKET - - _APP_STORAGE_BACKBLAZE_ACCESS_KEY - - _APP_STORAGE_BACKBLAZE_SECRET - - _APP_STORAGE_BACKBLAZE_REGION - - _APP_STORAGE_BACKBLAZE_BUCKET - - _APP_STORAGE_LINODE_ACCESS_KEY - - _APP_STORAGE_LINODE_SECRET - - _APP_STORAGE_LINODE_REGION - - _APP_STORAGE_LINODE_BUCKET - - _APP_STORAGE_WASABI_ACCESS_KEY - - _APP_STORAGE_WASABI_SECRET - - _APP_STORAGE_WASABI_REGION - - _APP_STORAGE_WASABI_BUCKET appwrite-realtime: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: realtime - container_name: appwrite-realtime <<: *x-logging restart: unless-stopped - networks: - - dokploy-network + labels: + - "traefik.enable=true" + - "traefik.constraint-label-stack=appwrite" depends_on: - mariadb - redis - labels: - - "traefik.enable=true" - - "traefik.constraint-label-stack=appwrite" environment: - _APP_ENV - _APP_WORKER_PER_CORE @@ -227,13 +169,10 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-audits: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-audits <<: *x-logging - container_name: appwrite-worker-audits restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -253,13 +192,10 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-webhooks: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-webhooks <<: *x-logging - container_name: appwrite-worker-webhooks restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -281,13 +217,10 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-deletes: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-deletes <<: *x-logging - container_name: appwrite-worker-deletes restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -295,6 +228,7 @@ services: - appwrite-uploads:/storage/uploads:rw - appwrite-cache:/storage/cache:rw - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw - appwrite-builds:/storage/builds:rw - appwrite-certificates:/storage/certificates:rw environment: @@ -315,6 +249,7 @@ services: - _APP_STORAGE_S3_SECRET - _APP_STORAGE_S3_REGION - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_S3_ENDPOINT - _APP_STORAGE_DO_SPACES_ACCESS_KEY - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION @@ -336,16 +271,16 @@ services: - _APP_EXECUTOR_HOST - _APP_MAINTENANCE_RETENTION_ABUSE - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE - _APP_MAINTENANCE_RETENTION_EXECUTION + - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_EMAIL_CERTIFICATES appwrite-worker-databases: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-databases <<: *x-logging - container_name: appwrite-worker-databases restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -365,19 +300,18 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-builds: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-builds <<: *x-logging - container_name: appwrite-worker-builds restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb volumes: - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw - appwrite-builds:/storage/builds:rw + - appwrite-uploads:/storage/uploads:rw environment: - _APP_ENV - _APP_WORKER_PER_CORE @@ -398,18 +332,20 @@ services: - _APP_VCS_GITHUB_PRIVATE_KEY - _APP_VCS_GITHUB_APP_ID - _APP_FUNCTIONS_TIMEOUT - - _APP_FUNCTIONS_BUILD_TIMEOUT - - _APP_FUNCTIONS_CPUS - - _APP_FUNCTIONS_MEMORY - - _APP_FUNCTIONS_SIZE_LIMIT + - _APP_SITES_TIMEOUT + - _APP_COMPUTE_BUILD_TIMEOUT + - _APP_COMPUTE_CPUS + - _APP_COMPUTE_MEMORY + - _APP_COMPUTE_SIZE_LIMIT - _APP_OPTIONS_FORCE_HTTPS - - _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS + - _APP_OPTIONS_ROUTER_FORCE_HTTPS - _APP_DOMAIN - _APP_STORAGE_DEVICE - _APP_STORAGE_S3_ACCESS_KEY - _APP_STORAGE_S3_SECRET - _APP_STORAGE_S3_REGION - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_S3_ENDPOINT - _APP_STORAGE_DO_SPACES_ACCESS_KEY - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION @@ -426,15 +362,13 @@ services: - _APP_STORAGE_WASABI_SECRET - _APP_STORAGE_WASABI_REGION - _APP_STORAGE_WASABI_BUCKET + - _APP_DOMAIN_SITES appwrite-worker-certificates: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-certificates <<: *x-logging - container_name: appwrite-worker-certificates restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -446,7 +380,11 @@ services: - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - - _APP_DOMAIN_TARGET + - _APP_DOMAIN_TARGET_CNAME + - _APP_DOMAIN_TARGET_AAAA + - _APP_DOMAIN_TARGET_A + - _APP_DOMAIN_TARGET_CAA + - _APP_DNS - _APP_DOMAIN_FUNCTIONS - _APP_EMAIL_CERTIFICATES - _APP_REDIS_HOST @@ -461,13 +399,10 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-functions: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-functions <<: *x-logging - container_name: appwrite-worker-functions restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -488,9 +423,10 @@ services: - _APP_DB_USER - _APP_DB_PASS - _APP_FUNCTIONS_TIMEOUT - - _APP_FUNCTIONS_BUILD_TIMEOUT - - _APP_FUNCTIONS_CPUS - - _APP_FUNCTIONS_MEMORY + - _APP_SITES_TIMEOUT + - _APP_COMPUTE_BUILD_TIMEOUT + - _APP_COMPUTE_CPUS + - _APP_COMPUTE_MEMORY - _APP_EXECUTOR_SECRET - _APP_EXECUTOR_HOST - _APP_USAGE_STATS @@ -499,13 +435,10 @@ services: - _APP_LOGGING_CONFIG appwrite-worker-mails: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-mails <<: *x-logging - container_name: appwrite-worker-mails restart: unless-stopped - networks: - - dokploy-network depends_on: - redis environment: @@ -529,15 +462,14 @@ services: - _APP_SMTP_USERNAME - _APP_SMTP_PASSWORD - _APP_LOGGING_CONFIG + - _APP_DOMAIN + - _APP_OPTIONS_FORCE_HTTPS appwrite-worker-messaging: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-messaging - container_name: appwrite-worker-messaging <<: *x-logging restart: unless-stopped - networks: - - dokploy-network volumes: - appwrite-uploads:/storage/uploads:rw depends_on: @@ -563,6 +495,7 @@ services: - _APP_STORAGE_S3_SECRET - _APP_STORAGE_S3_REGION - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_S3_ENDPOINT - _APP_STORAGE_DO_SPACES_ACCESS_KEY - _APP_STORAGE_DO_SPACES_SECRET - _APP_STORAGE_DO_SPACES_REGION @@ -581,13 +514,12 @@ services: - _APP_STORAGE_WASABI_BUCKET appwrite-worker-migrations: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: worker-migrations <<: *x-logging - container_name: appwrite-worker-migrations restart: unless-stopped - networks: - - dokploy-network + volumes: + - appwrite-imports:/storage/imports:rw depends_on: - mariadb environment: @@ -595,7 +527,11 @@ services: - _APP_WORKER_PER_CORE - _APP_OPENSSL_KEY_V1 - _APP_DOMAIN - - _APP_DOMAIN_TARGET + - _APP_DOMAIN_TARGET_CNAME + - _APP_DOMAIN_TARGET_AAAA + - _APP_DOMAIN_TARGET_A + - _APP_DOMAIN_TARGET_CAA + - _APP_DNS - _APP_EMAIL_SECURITY - _APP_REDIS_HOST - _APP_REDIS_PORT @@ -611,20 +547,21 @@ services: - _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET appwrite-task-maintenance: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: maintenance <<: *x-logging - container_name: appwrite-task-maintenance restart: unless-stopped - networks: - - dokploy-network depends_on: - redis environment: - _APP_ENV - _APP_WORKER_PER_CORE - _APP_DOMAIN - - _APP_DOMAIN_TARGET + - _APP_DOMAIN_TARGET_CNAME + - _APP_DOMAIN_TARGET_AAAA + - _APP_DOMAIN_TARGET_A + - _APP_DOMAIN_TARGET_CAA + - _APP_DNS - _APP_DOMAIN_FUNCTIONS - _APP_OPENSSL_KEY_V1 - _APP_REDIS_HOST @@ -641,17 +578,15 @@ services: - _APP_MAINTENANCE_RETENTION_CACHE - _APP_MAINTENANCE_RETENTION_ABUSE - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY - _APP_MAINTENANCE_RETENTION_SCHEDULES - appwrite-worker-usage: - image: appwrite/appwrite:1.6.1 - entrypoint: worker-usage - container_name: appwrite-worker-usage + appwrite-task-stats-resources: + image: appwrite/appwrite:1.8.0 + entrypoint: stats-resources <<: *x-logging restart: unless-stopped - networks: - - dokploy-network depends_on: - redis - mariadb @@ -670,15 +605,39 @@ services: - _APP_REDIS_PASS - _APP_USAGE_STATS - _APP_LOGGING_CONFIG - - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_DATABASE_SHARED_TABLES + - _APP_STATS_RESOURCES_INTERVAL - appwrite-worker-usage-dump: - image: appwrite/appwrite:1.6.1 - entrypoint: worker-usage-dump - container_name: appwrite-worker-usage-dump + appwrite-worker-stats-resources: + image: appwrite/appwrite:1.8.0 + entrypoint: worker-stats-resources <<: *x-logging - networks: - - dokploy-network + restart: unless-stopped + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_USAGE_STATS + - _APP_LOGGING_CONFIG + - _APP_STATS_RESOURCES_INTERVAL + + appwrite-worker-stats-usage: + image: appwrite/appwrite:1.8.0 + entrypoint: worker-stats-usage + <<: *x-logging + restart: unless-stopped depends_on: - redis - mariadb @@ -700,13 +659,10 @@ services: - _APP_USAGE_AGGREGATION_INTERVAL appwrite-task-scheduler-functions: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: schedule-functions - container_name: appwrite-task-scheduler-functions <<: *x-logging restart: unless-stopped - networks: - - dokploy-network depends_on: - mariadb - redis @@ -725,13 +681,10 @@ services: - _APP_DB_PASS appwrite-task-scheduler-executions: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: schedule-executions - container_name: appwrite-task-scheduler-executions <<: *x-logging restart: unless-stopped - networks: - - dokploy-network depends_on: - mariadb - redis @@ -750,13 +703,10 @@ services: - _APP_DB_PASS appwrite-task-scheduler-messages: - image: appwrite/appwrite:1.6.1 + image: appwrite/appwrite:1.8.0 entrypoint: schedule-messages - container_name: appwrite-task-scheduler-messages <<: *x-logging restart: unless-stopped - networks: - - dokploy-network depends_on: - mariadb - redis @@ -775,44 +725,48 @@ services: - _APP_DB_PASS appwrite-assistant: - image: appwrite/assistant:0.4.0 - container_name: appwrite-assistant + image: appwrite/assistant:0.8.3 <<: *x-logging restart: unless-stopped - networks: - - dokploy-network environment: - _APP_ASSISTANT_OPENAI_API_KEY + appwrite-browser: + image: appwrite/browser:0.2.4 + <<: *x-logging + restart: unless-stopped + openruntimes-executor: - container_name: openruntimes-executor hostname: exc1 <<: *x-logging restart: unless-stopped stop_signal: SIGINT - image: openruntimes/executor:0.6.11 - networks: - - dokploy-network + image: openruntimes/executor:0.7.22 volumes: - /var/run/docker.sock:/var/run/docker.sock - appwrite-builds:/storage/builds:rw - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw + # Host mount necessary to share files between executor and runtimes. + # It's not possible to share mount file between 2 containers without host mount (copying is too slow) - /tmp:/tmp:rw environment: - - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD - - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL - - OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK + - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD + - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL + - OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK - OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME - OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD - OPR_EXECUTOR_ENV=$_APP_ENV - - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES + - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET + - OPR_EXECUTOR_RUNTIME_VERSIONS=v5 - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY - OPR_EXECUTOR_STORAGE_S3_SECRET=$_APP_STORAGE_S3_SECRET - OPR_EXECUTOR_STORAGE_S3_REGION=$_APP_STORAGE_S3_REGION - OPR_EXECUTOR_STORAGE_S3_BUCKET=$_APP_STORAGE_S3_BUCKET + - OPR_EXECUTOR_STORAGE_S3_ENDPOINT=$_APP_STORAGE_S3_ENDPOINT - OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=$_APP_STORAGE_DO_SPACES_ACCESS_KEY - OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=$_APP_STORAGE_DO_SPACES_SECRET - OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=$_APP_STORAGE_DO_SPACES_REGION @@ -831,12 +785,9 @@ services: - OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET mariadb: - image: mariadb:10.11 - container_name: appwrite-mariadb + image: mariadb:10.11 # fix issues when upgrading using: mysql_upgrade -u root -p <<: *x-logging restart: unless-stopped - networks: - - dokploy-network volumes: - appwrite-mariadb:/var/lib/mysql:rw environment: @@ -849,39 +800,30 @@ services: redis: image: redis:7.2.4-alpine - container_name: appwrite-redis <<: *x-logging restart: unless-stopped command: > redis-server - --maxmemory 512mb - --maxmemory-policy allkeys-lru - --maxmemory-samples 5 - networks: - - dokploy-network + --maxmemory 512mb + --maxmemory-policy allkeys-lru + --maxmemory-samples 5 volumes: - appwrite-redis:/data:rw -# Uncomment and configure if ClamAV is needed -# clamav: -# image: appwrite/clamav:1.2.0 -# container_name: appwrite-clamav -# restart: unless-stopped -# networks: -# - dokploy-network -# volumes: -# - appwrite-uploads:/storage/uploads + # clamav: + # image: appwrite/clamav:1.2.0 + # restart: unless-stopped + # volumes: + # - appwrite-uploads:/storage/uploads volumes: appwrite-mariadb: appwrite-redis: appwrite-cache: appwrite-uploads: + appwrite-imports: appwrite-certificates: appwrite-functions: + appwrite-sites: appwrite-builds: appwrite-config: - -networks: - dokploy-network: - external: true diff --git a/blueprints/appwrite/template.toml b/blueprints/appwrite/template.toml index 3188ea17..cca2d43d 100644 --- a/blueprints/appwrite/template.toml +++ b/blueprints/appwrite/template.toml @@ -1,5 +1,11 @@ [variables] main_domain = "${domain}" +functions_domain = "functions.${main_domain}" +sites_domain = "sites.${main_domain}" +openssl_key = "${password:32}" +db_root_pw = "${password:32}" +db_user_pw = "${password:32}" +executor_secret = "${password:32}" [config] env = [ @@ -8,11 +14,19 @@ env = [ "_APP_OPTIONS_ABUSE=enabled", "_APP_OPTIONS_FORCE_HTTPS=disabled", "_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled", + "_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled", "_APP_OPTIONS_ROUTER_PROTECTION=disabled", - "_APP_OPENSSL_KEY_V1=your-secret-key", + "_APP_OPENSSL_KEY_V1=${openssl_key}", "_APP_DOMAIN=${main_domain}", - "_APP_DOMAIN_FUNCTIONS=${main_domain}", - "_APP_DOMAIN_TARGET=${main_domain}", + "_APP_CUSTOM_DOMAIN_DENY_LIST=example.com,test.com,app.example.com", + "_APP_DOMAIN_FUNCTIONS=${functions_domain}", + "_APP_DOMAIN_SITES=${sites_domain}", + "_APP_DOMAIN_TARGET=localhost", + "_APP_DOMAIN_TARGET_CNAME=localhost", + "_APP_DOMAIN_TARGET_AAAA=::1", + "_APP_DOMAIN_TARGET_A=127.0.0.1", + "_APP_DOMAIN_TARGET_CAA=", + "_APP_DNS=8.8.8.8", "_APP_CONSOLE_WHITELIST_ROOT=enabled", "_APP_CONSOLE_WHITELIST_EMAILS=", "_APP_CONSOLE_WHITELIST_IPS=", @@ -32,6 +46,8 @@ env = [ "_APP_USAGE_DATABASE_INTERVAL=900", "_APP_WORKER_PER_CORE=6", "_APP_CONSOLE_SESSION_ALERTS=disabled", + "_APP_COMPRESSION_ENABLED=enabled", + "_APP_COMPRESSION_MIN_SIZE_BYTES=1024", "_APP_REDIS_HOST=redis", "_APP_REDIS_PORT=6379", "_APP_REDIS_USER=", @@ -40,8 +56,8 @@ env = [ "_APP_DB_PORT=3306", "_APP_DB_SCHEMA=appwrite", "_APP_DB_USER=user", - "_APP_DB_PASS=password", - "_APP_DB_ROOT_PASS=rootsecretpassword", + "_APP_DB_PASS=${db_user_pw}", + "_APP_DB_ROOT_PASS=${db_root_pw}", "_APP_INFLUXDB_HOST=influxdb", "_APP_INFLUXDB_PORT=8086", "_APP_STATSD_HOST=telegraf", @@ -63,6 +79,7 @@ env = [ "_APP_STORAGE_S3_SECRET=", "_APP_STORAGE_S3_REGION=us-east-1", "_APP_STORAGE_S3_BUCKET=", + "_APP_STORAGE_S3_ENDPOINT=", "_APP_STORAGE_DO_SPACES_ACCESS_KEY=", "_APP_STORAGE_DO_SPACES_SECRET=", "_APP_STORAGE_DO_SPACES_REGION=us-east-1", @@ -80,27 +97,36 @@ env = [ "_APP_STORAGE_WASABI_REGION=eu-central-1", "_APP_STORAGE_WASABI_BUCKET=", "_APP_FUNCTIONS_SIZE_LIMIT=30000000", + "_APP_COMPUTE_SIZE_LIMIT=30000000", "_APP_FUNCTIONS_BUILD_SIZE_LIMIT=2000000000", "_APP_FUNCTIONS_TIMEOUT=900", "_APP_FUNCTIONS_BUILD_TIMEOUT=900", + "_APP_COMPUTE_BUILD_TIMEOUT=900", "_APP_FUNCTIONS_CONTAINERS=10", "_APP_FUNCTIONS_CPUS=0", + "_APP_COMPUTE_CPUS=0", "_APP_FUNCTIONS_MEMORY=0", + "_APP_COMPUTE_MEMORY=0", "_APP_FUNCTIONS_MEMORY_SWAP=0", "_APP_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0", - "_APP_EXECUTOR_SECRET=your-secret-key", + "_APP_EXECUTOR_SECRET=${executor_secret}", "_APP_EXECUTOR_HOST=http://exc1/v1", "_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes", "_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0", "_APP_FUNCTIONS_INACTIVE_THRESHOLD=60", + "_APP_COMPUTE_INACTIVE_THRESHOLD=60", "DOCKERHUB_PULL_USERNAME=", "DOCKERHUB_PULL_PASSWORD=", "DOCKERHUB_PULL_EMAIL=", "OPEN_RUNTIMES_NETWORK=appwrite_runtimes", - "_APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes", + "_APP_FUNCTIONS_RUNTIMES_NETWORK=dokploy-network", + "_APP_COMPUTE_RUNTIMES_NETWORK=dokploy-network", "_APP_DOCKER_HUB_USERNAME=", "_APP_DOCKER_HUB_PASSWORD=", "_APP_FUNCTIONS_MAINTENANCE_INTERVAL=3600", + "_APP_COMPUTE_MAINTENANCE_INTERVAL=3600", + "_APP_SITES_TIMEOUT=900", + "_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29", "_APP_VCS_GITHUB_APP_NAME=", "_APP_VCS_GITHUB_PRIVATE_KEY=", "_APP_VCS_GITHUB_APP_ID=", @@ -109,9 +135,11 @@ env = [ "_APP_VCS_GITHUB_WEBHOOK_SECRET=", "_APP_MAINTENANCE_INTERVAL=86400", "_APP_MAINTENANCE_DELAY=0", + "_APP_MAINTENANCE_START_TIME=00:00", "_APP_MAINTENANCE_RETENTION_CACHE=2592000", "_APP_MAINTENANCE_RETENTION_EXECUTION=1209600", "_APP_MAINTENANCE_RETENTION_AUDIT=1209600", + "_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE=15778800", "_APP_MAINTENANCE_RETENTION_ABUSE=86400", "_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000", "_APP_MAINTENANCE_RETENTION_SCHEDULES=86400", @@ -130,6 +158,18 @@ port = 80 host = "${main_domain}" path = "/" +[[config.domains]] +serviceName = "appwrite" +port = 80 +host = "${sites_domain}" +path = "/" + +[[config.domains]] +serviceName = "appwrite" +port = 80 +host = "${functions_domain}" +path = "/" + [[config.domains]] serviceName = "appwrite-console" port = 80 diff --git a/blueprints/autobase/docker-compose.yml b/blueprints/autobase/docker-compose.yml index 07b99485..13b23d57 100644 --- a/blueprints/autobase/docker-compose.yml +++ b/blueprints/autobase/docker-compose.yml @@ -1,6 +1,6 @@ services: autobase-console: - image: autobase/console:2.3.0 + image: autobase/console:2.5.2 restart: unless-stopped ports: - "80" diff --git a/blueprints/cloudflare-ddns/cloudflare-ddns.svg b/blueprints/cloudflare-ddns/cloudflare-ddns.svg new file mode 100644 index 00000000..efe800bc --- /dev/null +++ b/blueprints/cloudflare-ddns/cloudflare-ddns.svg @@ -0,0 +1,8 @@ + + + + + + DDNS + + diff --git a/blueprints/cloudflare-ddns/docker-compose.yml b/blueprints/cloudflare-ddns/docker-compose.yml new file mode 100644 index 00000000..179139d8 --- /dev/null +++ b/blueprints/cloudflare-ddns/docker-compose.yml @@ -0,0 +1,16 @@ +# For more details, see: +# - https://github.com/favonia/cloudflare-ddns +services: + cloudflare-ddns: + image: favonia/cloudflare-ddns:1 + network_mode: host + restart: unless-stopped + user: "1000:1000" + read_only: true + cap_drop: [all] + security_opt: [no-new-privileges:true] + environment: + - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN:?} + - DOMAINS=${DOMAINS:?} + - PROXIED=false + - IP6_PROVIDER=none diff --git a/blueprints/cloudflare-ddns/template.toml b/blueprints/cloudflare-ddns/template.toml new file mode 100644 index 00000000..f40da5ad --- /dev/null +++ b/blueprints/cloudflare-ddns/template.toml @@ -0,0 +1,9 @@ +variables = {} + +[config] +domains = [] +mounts = [] + +[config.env] +CLOUDFLARE_API_TOKEN = "" +DOMAINS = "example.org,www.example.org,example.io" diff --git a/blueprints/cloudflared/docker-compose.yml b/blueprints/cloudflared/docker-compose.yml index d9fc2741..b6bf5458 100644 --- a/blueprints/cloudflared/docker-compose.yml +++ b/blueprints/cloudflared/docker-compose.yml @@ -3,14 +3,14 @@ services: image: 'cloudflare/cloudflared:latest' environment: # Don't forget to set this in your Dokploy Environment - - 'TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}' + - 'TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN:?}' network_mode: host restart: unless-stopped command: [ "tunnel", # More tunnel run parameters here: - # https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/tunnel-run-parameters/ + # https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/configure-tunnels/cloudflared-parameters/run-parameters/ "--no-autoupdate", #"--protocol", "http2", diff --git a/blueprints/cloudflared/template.toml b/blueprints/cloudflared/template.toml index 242197bd..7d2557cc 100644 --- a/blueprints/cloudflared/template.toml +++ b/blueprints/cloudflared/template.toml @@ -2,5 +2,7 @@ variables = {} [config] domains = [] -env = ["CLOUDFLARE_TUNNEL_TOKEN=\"\""] mounts = [] + +[config.env] +CLOUDFLARE_TUNNEL_TOKEN = "" diff --git a/blueprints/cloudreve/cloudreve.png b/blueprints/cloudreve/cloudreve.png new file mode 100644 index 00000000..28020b06 Binary files /dev/null and b/blueprints/cloudreve/cloudreve.png differ diff --git a/blueprints/cloudreve/docker-compose.yml b/blueprints/cloudreve/docker-compose.yml new file mode 100644 index 00000000..f90f3685 --- /dev/null +++ b/blueprints/cloudreve/docker-compose.yml @@ -0,0 +1,48 @@ +version: "3.8" + +services: + cloudreve: + image: cloudreve/cloudreve:4.10.1 + depends_on: + postgresql: + condition: service_healthy + redis: + condition: service_started + restart: unless-stopped + environment: + - CR_CONF_Database.Type=postgres + - CR_CONF_Database.Host=postgresql + - CR_CONF_Database.User=${POSTGRES_USER} + - CR_CONF_Database.Password=${POSTGRES_PASSWORD} + - CR_CONF_Database.Name=${POSTGRES_DB} + - CR_CONF_Database.Port=5432 + - CR_CONF_Redis.Server=redis:6379 + volumes: + - cloudreve_data:/cloudreve/data + + postgresql: + image: postgres:17 + restart: unless-stopped + environment: + - POSTGRES_USER + - POSTGRES_PASSWORD + - POSTGRES_DB + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + + redis: + image: redis:8.4.0 + restart: unless-stopped + volumes: + - redis_data:/data + +volumes: + cloudreve_data: + postgres_data: + redis_data: diff --git a/blueprints/cloudreve/template.toml b/blueprints/cloudreve/template.toml new file mode 100644 index 00000000..a5acf6b4 --- /dev/null +++ b/blueprints/cloudreve/template.toml @@ -0,0 +1,16 @@ +[variables] +main_domain = "${domain}" +db_password = "${password:32}" +db_user = "cloudreve" +db_name = "cloudreve" + +[config] +[[config.domains]] +serviceName = "cloudreve" +port = 5212 +host = "${main_domain}" + +[config.env] +POSTGRES_PASSWORD = "${db_password}" +POSTGRES_USER = "${db_user}" +POSTGRES_DB = "${db_name}" diff --git a/blueprints/emqx/docker-compose.yml b/blueprints/emqx/docker-compose.yml new file mode 100644 index 00000000..4b11f010 --- /dev/null +++ b/blueprints/emqx/docker-compose.yml @@ -0,0 +1,58 @@ +# This templates requires additional traefik port mapping and entry point +# for port 8883 (mqtts over TCP) +# +# For the full instructions, refer to: +# - https://github.com/Dokploy/dokploy/discussions/3126 +# +# The initial login credentials are: +# - USERNAME: admin +# - PASSWORD: public + +services: + emqx: + image: emqx/emqx-enterprise:6.0.1 + hostname: node1.emqx.com + environment: + EMQX_NODE_NAME: emqx@node1.emqx.com + expose: + - 1883 # MQTT + - 8083 # WS + - 18083 # Dashboard + volumes: + - emqx_data:/opt/emqx/data + - emqx_log:/opt/emqx/log + networks: + dokploy-network: + aliases: + - emqx-service + restart: unless-stopped + healthcheck: + test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"] + interval: 30s + timeout: 5s + retries: 3 + labels: + # MQTT over TLS + - "traefik.tcp.routers.emqx-mqtts.entrypoints=mqtts" + - "traefik.tcp.routers.emqx-mqtts.rule=HostSNI(`broker.yourdomain.com`)" # Change domain + - "traefik.tcp.routers.emqx-mqtts.tls.certresolver=letsencrypt" + - "traefik.tcp.routers.emqx-mqtts.service=emqx-service" + - "traefik.tcp.services.emqx-service.loadbalancer.server.port=1883" + + # + # Optional Web UI: + # - https://github.com/emqx/MQTTX/tree/main/web + # + # mqttx-web: + # image: emqx/mqttx-web:latest + # expose: + # - 80 + # + +volumes: + emqx_data: + emqx_log: + +networks: + dokploy-network: + external: true diff --git a/blueprints/emqx/emqx.svg b/blueprints/emqx/emqx.svg new file mode 100644 index 00000000..ce0c1ec9 --- /dev/null +++ b/blueprints/emqx/emqx.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/blueprints/emqx/template.toml b/blueprints/emqx/template.toml new file mode 100644 index 00000000..5fc03e5f --- /dev/null +++ b/blueprints/emqx/template.toml @@ -0,0 +1,11 @@ +[variables] + +[[config.domains]] +serviceName = "emqx" +port = 18083 +host = "emqx.yourdomain.com" + +[[config.domains]] +serviceName = "emqx" +port = 8083 +host = "broker.yourdomain.com" diff --git a/blueprints/habitica/docker-compose.yml b/blueprints/habitica/docker-compose.yml index af226516..3990e571 100644 --- a/blueprints/habitica/docker-compose.yml +++ b/blueprints/habitica/docker-compose.yml @@ -1,13 +1,18 @@ -version: "3.8" - services: server: image: docker.io/awinterstein/habitica-server:latest restart: unless-stopped depends_on: - - mongo + mongo: + condition: service_healthy environment: - - NODE_DB_URI=mongodb://mongo/habitica + NODE_DB_URI: "mongodb://${MONGO_HABITICA_USER}:${MONGO_HABITICA_PASSWORD}@mongo/habitica?authSource=habitica" + INVITE_ONLY: "${INVITE_ONLY}" + EMAIL_SERVER_URL: "${EMAIL_SERVER_URL}" + EMAIL_SERVER_PORT: "${EMAIL_SERVER_PORT}" + EMAIL_SERVER_AUTH_USER: "${EMAIL_SERVER_AUTH_USER}" + EMAIL_SERVER_AUTH_PASSWORD: "${EMAIL_SERVER_AUTH_PASSWORD}" + ADMIN_EMAIL: "${ADMIN_EMAIL}" client: image: docker.io/awinterstein/habitica-client:latest @@ -20,12 +25,64 @@ services: mongo: image: docker.io/mongo:latest restart: unless-stopped - command: ["--replSet", "rs", "--bind_ip_all", "--port", "27017"] + command: > + bash -c " + echo \"${MONGO_KEYFILE_CONTENT}\" > /etc/mongo-keyfile && + chown 999:999 /etc/mongo-keyfile && + chmod 400 /etc/mongo-keyfile && + exec docker-entrypoint.sh mongod --replSet rs --bind_ip_all --port 27017 --keyFile /etc/mongo-keyfile + " + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_ADMIN_USER} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ADMIN_PASSWORD} + MONGO_KEYFILE_CONTENT: ${MONGO_KEYFILE_CONTENT} + MONGO_HABITICA_USER: ${MONGO_HABITICA_USER} + MONGO_HABITICA_PASSWORD: ${MONGO_HABITICA_PASSWORD} + # --------------------------------------------------------- + # SMART HEALTHCHECK: Auto-fixes Hostname Mismatches for replicaSet + # --------------------------------------------------------- healthcheck: - test: echo "try { rs.status() } catch (err) { rs.initiate() }" | mongosh --port 27017 --quiet - interval: 10s - timeout: 30s - retries: 30 + test: | + mongosh --port 27017 --quiet -u "${MONGO_ADMIN_USER}" -p "${MONGO_ADMIN_PASSWORD}" --authenticationDatabase admin --eval " + try { + // 1. Hostname Fix + const config = rs.conf(); + const currentHost = require('os').hostname() + ':27017'; + if (config.members[0].host !== currentHost) { + config.members[0].host = currentHost; + rs.reconfig(config, { force: true }); + } + + // 2. User Creation Logic + const targetDb = db.getSiblingDB('habitica'); + const hUser = process.env.MONGO_HABITICA_USER; + const hPass = process.env.MONGO_HABITICA_PASSWORD; + + // We can only check/create users if we are Primary + if (rs.isMaster().ismaster) { + if (!targetDb.getUser(hUser)) { + print('Creating missing user ' + hUser + '...'); + targetDb.createUser({ user: hUser, pwd: hPass, roles: ['readWrite'] }); + } + // SUCCESS: User exists and we are Primary + quit(0); + } else { + // We are not Primary yet (still electing), so we cannot confirm user exists. + // Fail the check so the dependent app waits. + print('Waiting for Primary state...'); + quit(1); + } + } catch (err) { + // If not initialized, initiate and FAIL this check so we wait for the next cycle + try { + rs.initiate({ _id: 'rs', members: [{ _id: 0, host: require('os').hostname() + ':27017' }] }); + } catch (e) {} + quit(1); + } + " + interval: 5s + timeout: 10s + retries: 20 volumes: - habitica-mongo-data:/data/db diff --git a/blueprints/habitica/template.toml b/blueprints/habitica/template.toml index 3888ae24..a8cb5fc6 100644 --- a/blueprints/habitica/template.toml +++ b/blueprints/habitica/template.toml @@ -1,6 +1,9 @@ [variables] main_domain = "${domain}" mail_password = "${password:32}" +mongo_key = "${base64:756}" +mongo_admin_password = "${password}" +mongo_habitica_password = "${password}" [config] [[config.domains]] @@ -9,16 +12,21 @@ port = 80 host = "habitica.${main_domain}" [config.env] - -BASE_URL="https://habitica.${main_domain}" -INVITE_ONLY="false" -EMAIL_SERVER_URL="mail.example.com" -EMAIL_SERVER_PORT="587" -EMAIL_SERVER_AUTH_USER="mail_user" -EMAIL_SERVER_AUTH_PASSWORD="${mail_password}" +BASE_URL = "https://habitica.${main_domain}" +INVITE_ONLY = "false" +EMAIL_SERVER_URL = "mail.example.com" +EMAIL_SERVER_PORT = "587" +EMAIL_SERVER_AUTH_USER = "mail_user" +EMAIL_SERVER_AUTH_PASSWORD = "${mail_password}" +MONGO_KEYFILE_CONTENT = "${mongo_key}" +MONGO_ADMIN_USER = "admin" +MONGO_ADMIN_PASSWORD = "${mongo_admin_password}" +MONGO_HABITICA_USER = "habitica" +MONGO_HABITICA_PASSWORD = "${mongo_habitica_password}" +ADMIN_EMAIL = "no-reply@${main_domain}" [[config.mounts]] serviceName = "mongo" type = "volume" source = "habitica-mongo-data" -target = "/data/db" \ No newline at end of file +target = "/data/db" diff --git a/blueprints/instantdb/docker-compose.yml b/blueprints/instantdb/docker-compose.yml new file mode 100644 index 00000000..b40e043d --- /dev/null +++ b/blueprints/instantdb/docker-compose.yml @@ -0,0 +1,64 @@ +services: + postgres: + image: ghcr.io/instantdb/postgresql:postgresql-16-pg-hint-plan + restart: unless-stopped + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_DB: ${POSTGRES_DB} + volumes: + - backend-db:/var/lib/postgresql/data + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + command: + - "postgres" + - "-c" + - "wal_level=logical" + - "-c" + - "max_replication_slots=4" + - "-c" + - "max_wal_senders=4" + - "-c" + - "shared_preload_libraries=pg_hint_plan" + - "-c" + - "random_page_cost=1.1" + server: + depends_on: + postgres: + condition: service_healthy + image: hari1367709/instantdb-server:latest + restart: unless-stopped + working_dir: /app + environment: + DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}" + NREPL_BIND_ADDRESS: "0.0.0.0" + PORT: "8888" + HOST: "0.0.0.0" + # AWS Credentials for KMS (required for InstantDB) + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + AWS_REGION: ${AWS_REGION:-us-east-1} + # Force unbuffered output for logs + PYTHONUNBUFFERED: "1" + NODE_ENV: "production" + command: ["java", "-Djava.awt.headless=true", "-server", "-jar", "target/instant-standalone.jar"] + ports: + - "8888" + - "6005" + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:8888/health || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s +volumes: + backend-db: + diff --git a/blueprints/instantdb/instant.svg b/blueprints/instantdb/instant.svg new file mode 100644 index 00000000..4e2dc24c --- /dev/null +++ b/blueprints/instantdb/instant.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blueprints/instantdb/template.toml b/blueprints/instantdb/template.toml new file mode 100644 index 00000000..571e6b7a --- /dev/null +++ b/blueprints/instantdb/template.toml @@ -0,0 +1,29 @@ +[variables] +main_domain = "${domain}" +postgres_password = "${password:32}" +postgres_user = "instant" +postgres_db = "instant" +aws_access_key_id = "FILL-YOUR-CREDENTIALS" +aws_secret_access_key = "FILL-YOUR-CREDENTIALS" +aws_region = "us-east-1" + +[config] +env = [ + "POSTGRES_PASSWORD=${postgres_password}", + "POSTGRES_USER=${postgres_user}", + "POSTGRES_DB=${postgres_db}", + "DATABASE_URL=postgresql://${postgres_user}:${postgres_password}@postgres:5432/${postgres_db}", + "NREPL_BIND_ADDRESS=0.0.0.0", + "PORT=8888", + "HOST=0.0.0.0", + "AWS_ACCESS_KEY_ID=${aws_access_key_id}", + "AWS_SECRET_ACCESS_KEY=${aws_secret_access_key}", + "AWS_REGION=${aws_region}", +] +mounts = [] + +[[config.domains]] +serviceName = "server" +port = 8888 +host = "${main_domain}" + diff --git a/blueprints/invoiceshelf/docker-compose.yml b/blueprints/invoiceshelf/docker-compose.yml index 8d2c8265..bc4e8ff0 100644 --- a/blueprints/invoiceshelf/docker-compose.yml +++ b/blueprints/invoiceshelf/docker-compose.yml @@ -20,8 +20,7 @@ services: image: invoiceshelf/invoiceshelf:nightly volumes: - - invoiceshelf-app-data:/data - - invoiceshelf-app-conf:/conf + - invoiceshelf-storage:/var/www/html/storage environment: - PHP_TZ=UTC - TIMEZONE=UTC @@ -49,5 +48,4 @@ services: volumes: invoiceshelf-postgres-data: - invoiceshelf-app-data: - invoiceshelf-app-conf: \ No newline at end of file + invoiceshelf-storage: diff --git a/blueprints/ipfs/docker-compose.yml b/blueprints/ipfs/docker-compose.yml new file mode 100644 index 00000000..4275f553 --- /dev/null +++ b/blueprints/ipfs/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.8" +services: + ipfs: + image: ipfs/kubo:latest + restart: unless-stopped + environment: + - IPFS_PROFILE=server + volumes: + - ipfs_data:/data/ipfs + - ipfs_staging:/export + ports: + - 4001 + - 8080 + - 5001 +volumes: + ipfs_data: {} + ipfs_staging: {} diff --git a/blueprints/ipfs/ipfs.svg b/blueprints/ipfs/ipfs.svg new file mode 100644 index 00000000..1b90c313 --- /dev/null +++ b/blueprints/ipfs/ipfs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blueprints/ipfs/template.toml b/blueprints/ipfs/template.toml new file mode 100644 index 00000000..89d4677e --- /dev/null +++ b/blueprints/ipfs/template.toml @@ -0,0 +1,25 @@ +[variables] +gateway_domain = "${domain}" +api_domain = "${domain}" + +[config] +env = [] + +[[config.domains]] +serviceName = "ipfs" +port = 8080 +host = "${gateway_domain}" + +[[config.domains]] +serviceName = "ipfs" +port = 5001 +host = "${api_domain}" + +[[config.mounts]] +filePath = "/container-init.d/001-configure-api.sh" +content = """ +#!/bin/sh +ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' +ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST", "GET"]' +""" diff --git a/blueprints/jenkins/docker-compose.yml b/blueprints/jenkins/docker-compose.yml new file mode 100644 index 00000000..f2b8ad3c --- /dev/null +++ b/blueprints/jenkins/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3.8" + +services: + jenkins: + image: jenkins/jenkins:latest + volumes: + - jenkins-home:/var/jenkins_home + - /var/run/docker.sock:/var/run/docker.sock + ports: + - 8080 + +volumes: + jenkins-home: {} \ No newline at end of file diff --git a/blueprints/jenkins/jenkins.svg b/blueprints/jenkins/jenkins.svg new file mode 100644 index 00000000..b511310d --- /dev/null +++ b/blueprints/jenkins/jenkins.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blueprints/jenkins/template.toml b/blueprints/jenkins/template.toml new file mode 100644 index 00000000..46a84921 --- /dev/null +++ b/blueprints/jenkins/template.toml @@ -0,0 +1,12 @@ +[variables] +main_domain = "${domain}" + +[config] +env = {} +mounts = [] + +[[config.domains]] +serviceName = "jenkins" +port = 8080 +host = "${main_domain}" + diff --git a/blueprints/komari-monitor/docker-compose.yml b/blueprints/komari-monitor/docker-compose.yml new file mode 100644 index 00000000..149999b0 --- /dev/null +++ b/blueprints/komari-monitor/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3.8" +services: + komari: + image: ghcr.io/komari-monitor/komari:latest + restart: unless-stopped + volumes: + - komari-data:/app/data + environment: + - ADMIN_USERNAME + - ADMIN_PASSWORD + +volumes: + komari-data: {} diff --git a/blueprints/komari-monitor/komari-monitor.ico b/blueprints/komari-monitor/komari-monitor.ico new file mode 100644 index 00000000..f314b8f2 Binary files /dev/null and b/blueprints/komari-monitor/komari-monitor.ico differ diff --git a/blueprints/komari-monitor/template.toml b/blueprints/komari-monitor/template.toml new file mode 100644 index 00000000..20955090 --- /dev/null +++ b/blueprints/komari-monitor/template.toml @@ -0,0 +1,15 @@ +[variables] +main_domain = "${domain}" +admin_password = "${password:16}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "komari" +port = 25_774 +host = "${main_domain}" + +[config.env] +ADMIN_USERNAME = "admin" +ADMIN_PASSWORD = "${admin_password}" diff --git a/blueprints/lavalink/docker-compose.yml b/blueprints/lavalink/docker-compose.yml new file mode 100644 index 00000000..1f4e91cf --- /dev/null +++ b/blueprints/lavalink/docker-compose.yml @@ -0,0 +1,41 @@ +services: + fix-perms: + image: busybox:1.36 + command: > + sh -c "mkdir -p /opt/Lavalink/plugins && + chmod -R 0777 /opt/Lavalink/plugins || true && + chown -R 1000:1000 /opt/Lavalink/plugins || true && + echo perms-fixed && sleep 1" + volumes: + - "../files/plugins/:/opt/Lavalink/plugins/" + - "../files/application.yml:/opt/Lavalink/application.yml" + restart: "no" + lavalink: + image: ghcr.io/lavalink-devs/lavalink:4 + depends_on: + - fix-perms + restart: unless-stopped + environment: + _JAVA_OPTIONS: "${_JAVA_OPTIONS:--Xmx6G}" + LAVALINK_SERVER_PASSWORD: "${LAVALINK_SERVER_PASSWORD:-youshallnotpass}" + SERVER_PORT: "${SERVER_PORT:-2333}" + volumes: + - "../files/application.yml:/opt/Lavalink/application.yml:rw" + - "../files/plugins/:/opt/Lavalink/plugins/:rw" + ports: + - ${SERVER_PORT} + + healthcheck: + test: > + sh -c 'wget --header="Authorization: ${LAVALINK_SERVER_PASSWORD}" -qO- http://127.0.0.1:${SERVER_PORT}/v4/info >/dev/null 2>&1 || exit 1' + interval: 100s + timeout: 5s + retries: 5 + start_period: 30s + + entrypoint: > + sh -c 'until [ -w /opt/Lavalink/plugins ] ; do + echo "waiting for /opt/Lavalink/plugins to be writable"; + sleep 1; + done; + exec java -jar /opt/Lavalink/Lavalink.jar' diff --git a/blueprints/lavalink/lavalink.svg b/blueprints/lavalink/lavalink.svg new file mode 100644 index 00000000..0ade923f --- /dev/null +++ b/blueprints/lavalink/lavalink.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/blueprints/lavalink/template.toml b/blueprints/lavalink/template.toml new file mode 100644 index 00000000..6c9a92cd --- /dev/null +++ b/blueprints/lavalink/template.toml @@ -0,0 +1,123 @@ +[variables] +main_domain = "${domain}" +server_port = "2333" +lavalink_server_password = "${password}" + +[config] +[[config.mounts]] +filePath = "./application.yml" +content = """ +server: # REST and WS server + port: 2333 + address: 0.0.0.0 + http2: + enabled: false +plugins: +# name: # Name of the plugin +# some_key: some_value # Some key-value pair for the plugin +# another_key: another_value +lavalink: + plugins: + # - dependency: "com.github.username.pluginName:pluginName-plugin:x.y.z" + # snapshot: false + # pluginsDir: "/opt/Lavalink/plugins" + # defaultPluginRepository: "https://maven.lavalink.dev/releases" + # defaultPluginSnapshotRepository: "https://maven.lavalink.dev/snapshots" + server: + password: "youshallnotpass" + sources: + # The default Youtube source is now deprecated and won't receive further updates. Please use https://github.com/lavalink-devs/youtube-source#plugin instead. + youtube: true + bandcamp: true + soundcloud: true + twitch: true + vimeo: true + nico: true + http: true + local: false + filters: + volume: true + equalizer: true + karaoke: true + timescale: true + tremolo: true + vibrato: true + distortion: true + rotation: true + channelMix: true + lowPass: true + nonAllocatingFrameBuffer: false + bufferDurationMs: 400 + frameBufferDurationMs: 5000 + opusEncodingQuality: 10 + resamplingQuality: LOW + trackStuckThresholdMs: 10000 + useSeekGhosting: true + youtubePlaylistLoadLimit: 6 + playerUpdateInterval: 5 + youtubeSearchEnabled: true + soundcloudSearchEnabled: true + gc-warnings: true + #ratelimit: + #ipBlocks: ["1.0.0.0/8", "..."] # list of ip blocks + #excludedIps: ["...", "..."] # ips which should be explicit excluded from usage by lavalink + #strategy: "RotateOnBan" # RotateOnBan | LoadBalance | NanoSwitch | RotatingNanoSwitch + #searchTriggersFail: true # Whether a search 429 should trigger marking the ip as failing + #retryLimit: -1 # -1 = use default lavaplayer value | 0 = infinity | >0 = retry will happen this numbers times + #youtubeConfig: # Required for avoiding all age restrictions by YouTube, some restricted videos still can be played without. + #email: "" # Email of Google account + #password: "" # Password of Google account + #httpConfig: # Useful for blocking bad-actors from ip-grabbing your music node and attacking it, this way only the http proxy will be attacked + #proxyHost: "localhost" # Hostname of the proxy, (ip or domain) + #proxyPort: 3128 # Proxy port, 3128 is the default for squidProxy + #proxyUser: "" # Optional user for basic authentication fields, leave blank if you don't use basic auth + #proxyPassword: "" # Password for basic authentication + timeouts: + connectTimeoutMs: 3000 + connectionRequestTimeoutMs: 3000 + socketTimeoutMs: 3000 + +metrics: + prometheus: + enabled: false + endpoint: /metrics + +sentry: + dsn: "" + environment: "" +# tags: +# some_key: some_value +# another_key: another_value + +logging: + file: + path: ./logs/ + + level: + root: INFO + lavalink: INFO + + request: + enabled: true + includeClientInfo: true + includeHeaders: false + includeQueryString: true + includePayload: true + maxPayloadLength: 10000 + + + logback: + rollingpolicy: + max-file-size: 1GB + max-history: 30 +""" + +[[config.domains]] +serviceName = "lavalink" +port = 2_333 +host = "${main_domain}" + +[config.env] +_JAVA_OPTIONS = "-Xmx6G" +LAVALINK_SERVER_PASSWORD = "${lavalink_server_password}" +SERVER_PORT = "${server_port}" diff --git a/blueprints/mautic/docker-compose.yml b/blueprints/mautic/docker-compose.yml new file mode 100644 index 00000000..223ea7ee --- /dev/null +++ b/blueprints/mautic/docker-compose.yml @@ -0,0 +1,131 @@ +version: "3.8" + +services: + # ------------------------------------------------------------------------- + # Service 1: Database + # ------------------------------------------------------------------------- + mysql: + image: mysql:8.0 + command: --default-authentication-plugin=mysql_native_password + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MAUTIC_DB_DATABASE} + MYSQL_USER: ${MAUTIC_DB_USER} + MYSQL_PASSWORD: ${MAUTIC_DB_PASSWORD} + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + + # ------------------------------------------------------------------------- + # Service 2: Mautic Web (The Leader) + # ------------------------------------------------------------------------- + mautic: + image: mautic/mautic:5.1.1-apache + restart: unless-stopped + depends_on: + mysql: + condition: service_healthy + ports: + - 80 + environment: + - DOCKER_MAUTIC_ROLE=mautic_web + - DOCKER_MAUTIC_RUN_MIGRATIONS=true + - MAUTIC_DB_HOST=${MAUTIC_DB_HOST} + - MAUTIC_DB_PORT=${MAUTIC_DB_PORT} + - MAUTIC_DB_DATABASE=${MAUTIC_DB_DATABASE} + - MAUTIC_DB_USER=${MAUTIC_DB_USER} + - MAUTIC_DB_PASSWORD=${MAUTIC_DB_PASSWORD} + - MAUTIC_URL=${MAUTIC_URL} + - MAUTIC_TRUSTED_PROXIES=${MAUTIC_TRUSTED_PROXIES} + - MAUTIC_MESSENGER_DSN_EMAIL=${MAUTIC_MESSENGER_DSN_EMAIL} + - MAUTIC_MESSENGER_DSN_HIT=${MAUTIC_MESSENGER_DSN_HIT} + - PHP_INI_DATE_TIMEZONE=${PHP_INI_DATE_TIMEZONE} + - PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT} + volumes: + - mautic_data:/var/www/html + # AUTOMATION FIX 1: Force permissions to be correct on every start + entrypoint: ["/bin/sh", "-c", "chown -R www-data:www-data /var/www/html && /entrypoint.sh apache2-foreground"] + # AUTOMATION FIX 2: Check if the CONFIG FILE exists. If not, report 'unhealthy'. + # This signals the other containers to keep waiting. + healthcheck: + test: ["CMD-SHELL", "test -f /var/www/html/config/local.php || exit 1"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 300s # Give you 5 mins to run the installer before marking failed + + # ------------------------------------------------------------------------- + # Service 3: Mautic Cron (Waits for Install) + # ------------------------------------------------------------------------- + mautic-cron: + image: mautic/mautic:5.1.1-apache + restart: unless-stopped + depends_on: + mautic: + condition: service_healthy # AUTOMATION FIX 3: Do not start until config file exists + environment: + - DOCKER_MAUTIC_ROLE=mautic_cron + - MAUTIC_DB_HOST=${MAUTIC_DB_HOST} + - MAUTIC_DB_PORT=${MAUTIC_DB_PORT} + - MAUTIC_DB_DATABASE=${MAUTIC_DB_DATABASE} + - MAUTIC_DB_USER=${MAUTIC_DB_USER} + - MAUTIC_DB_PASSWORD=${MAUTIC_DB_PASSWORD} + - MAUTIC_URL=${MAUTIC_URL} + - PHP_INI_DATE_TIMEZONE=${PHP_INI_DATE_TIMEZONE} + volumes: + - mautic_data:/var/www/html + + # ------------------------------------------------------------------------- + # Service 4: Mautic Worker (Waits for Install) + # ------------------------------------------------------------------------- + mautic-worker: + image: mautic/mautic:5.1.1-apache + restart: unless-stopped + depends_on: + mautic: + condition: service_healthy # AUTOMATION FIX 3: Do not start until config file exists + deploy: + resources: + limits: + memory: 512M + environment: + - DOCKER_MAUTIC_ROLE=mautic_worker + - DOCKER_MAUTIC_WORKERS_CONSUME_EMAIL=2 + - DOCKER_MAUTIC_WORKERS_CONSUME_HIT=2 + - DOCKER_MAUTIC_WORKERS_CONSUME_FAILED=2 + - MAUTIC_DB_HOST=${MAUTIC_DB_HOST} + - MAUTIC_DB_PORT=${MAUTIC_DB_PORT} + - MAUTIC_DB_DATABASE=${MAUTIC_DB_DATABASE} + - MAUTIC_DB_USER=${MAUTIC_DB_USER} + - MAUTIC_DB_PASSWORD=${MAUTIC_DB_PASSWORD} + - MAUTIC_URL=${MAUTIC_URL} + - MAUTIC_MESSENGER_DSN_EMAIL=${MAUTIC_MESSENGER_DSN_EMAIL} + - MAUTIC_MESSENGER_DSN_HIT=${MAUTIC_MESSENGER_DSN_HIT} + - PHP_INI_DATE_TIMEZONE=${PHP_INI_DATE_TIMEZONE} + volumes: + - mautic_data:/var/www/html + + # ------------------------------------------------------------------------- + # Service 5: phpMyAdmin + # ------------------------------------------------------------------------- + phpmyadmin: + image: phpmyadmin/phpmyadmin + restart: unless-stopped + depends_on: + mysql: + condition: service_healthy + environment: + PMA_HOST: mysql + PMA_PORT: 3306 + UPLOAD_LIMIT: 64M + ports: + - 80 + +volumes: + mysql_data: + mautic_data: diff --git a/blueprints/mautic/mautic.svg b/blueprints/mautic/mautic.svg new file mode 100644 index 00000000..3f5229ae --- /dev/null +++ b/blueprints/mautic/mautic.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blueprints/mautic/template.toml b/blueprints/mautic/template.toml new file mode 100644 index 00000000..eeb79eef --- /dev/null +++ b/blueprints/mautic/template.toml @@ -0,0 +1,52 @@ +[variables] +# Domain 1: For the main Mautic Application +mautic_domain = "${domain}" + +# Domain 2: For phpMyAdmin (Database Manager) +pma_domain = "${domain}" + +# Security: Random passwords +db_password = "${password:32}" +root_password = "${password:32}" + +[config] + +# --- Service 1: Mautic Web --- +[[config.domains]] +serviceName = "mautic" +port = 80 +host = "${mautic_domain}" +path = "/" + +# --- Service 2: phpMyAdmin --- +[[config.domains]] +serviceName = "phpmyadmin" +port = 80 +host = "${pma_domain}" +path = "/" + +# --- Shared Environment Variables --- +[config.env] + +# URL Configuration +MAUTIC_URL = "https://${mautic_domain}" + +# Database Connections +MAUTIC_DB_HOST = "mysql" +MAUTIC_DB_PORT = "3306" +MAUTIC_DB_DATABASE = "mautic" +MAUTIC_DB_USER = "mautic" +MAUTIC_DB_PASSWORD = "${db_password}" +MYSQL_ROOT_PASSWORD = "${root_password}" + +# Security & Proxy (JSON ARRAY FIXED) +# We use single quotes '...' so TOML treats the inner [...] as a string +MAUTIC_TRUSTED_PROXIES = '["0.0.0.0/0"]' + +# Queue Settings +MAUTIC_MESSENGER_DSN_EMAIL = "doctrine://default" +MAUTIC_MESSENGER_DSN_HIT = "doctrine://default" + +# PHP Settings +PHP_INI_DATE_TIMEZONE = "UTC" +PHP_MEMORY_LIMIT = "512M" \ No newline at end of file diff --git a/blueprints/minepanel/docker-compose.yml b/blueprints/minepanel/docker-compose.yml new file mode 100644 index 00000000..e69b75f9 --- /dev/null +++ b/blueprints/minepanel/docker-compose.yml @@ -0,0 +1,29 @@ +version: "3.8" +services: + backend: + image: ketbom/minepanel-backend:1.7.1 + restart: unless-stopped + environment: + - NODE_ENV=production + - FRONTEND_URL=${FRONTEND_URL} + - JWT_SECRET=${JWT_SECRET} + - CLIENT_PASSWORD=${CLIENT_PASSWORD} + - CLIENT_USERNAME=${CLIENT_USERNAME} + - BASE_DIR=${BASE_DIR} + volumes: + - minepanel-servers:/app/servers + - minepanel-data:/app/data + - /var/run/docker.sock:/var/run/docker.sock + + frontend: + image: ketbom/minepanel-frontend:1.7.1 + restart: unless-stopped + environment: + - NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL} + - NEXT_PUBLIC_DEFAULT_LANGUAGE=${NEXT_PUBLIC_DEFAULT_LANGUAGE} + depends_on: + - backend + +volumes: + minepanel-servers: + minepanel-data: diff --git a/blueprints/minepanel/minepanel.webp b/blueprints/minepanel/minepanel.webp new file mode 100644 index 00000000..21a6f7a4 Binary files /dev/null and b/blueprints/minepanel/minepanel.webp differ diff --git a/blueprints/minepanel/template.toml b/blueprints/minepanel/template.toml new file mode 100644 index 00000000..4f1b0862 --- /dev/null +++ b/blueprints/minepanel/template.toml @@ -0,0 +1,28 @@ +[variables] +main_domain = "${domain}" +jwt_secret = "${base64:32}" +client_username = "admin" +client_password = "${password:16}" +default_language = "en" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "frontend" +port = 3_000 +host = "${main_domain}" + +[[config.domains]] +serviceName = "backend" +port = 8_091 +host = "api-${main_domain}" + +[config.env] +JWT_SECRET = "${jwt_secret}" +CLIENT_USERNAME = "${client_username}" +CLIENT_PASSWORD = "${client_password}" +FRONTEND_URL = "http://${main_domain}" +NEXT_PUBLIC_BACKEND_URL = "http://api-${main_domain}" +NEXT_PUBLIC_DEFAULT_LANGUAGE = "${default_language}" +BASE_DIR = "/app" diff --git a/blueprints/misaka-danmu-server/docker-compose.yml b/blueprints/misaka-danmu-server/docker-compose.yml new file mode 100644 index 00000000..42252c25 --- /dev/null +++ b/blueprints/misaka-danmu-server/docker-compose.yml @@ -0,0 +1,43 @@ +version: "3.8" +services: + postgres: + image: postgres:18 + restart: unless-stopped + environment: + - POSTGRES_PASSWORD + - POSTGRES_USER + - POSTGRES_DB + - TZ=Asia/Shanghai + volumes: + - postgres-data:/var/lib/postgresql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U danmuapi -d danmuapi"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 60s + + danmu-app: + image: l429609201/misaka_danmu_server:latest + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + environment: + - PUID=1000 + - PGID=1000 + - UMASK=0022 + - TZ=Asia/Shanghai + - DANMUAPI_DATABASE__TYPE + - DANMUAPI_DATABASE__HOST + - DANMUAPI_DATABASE__PORT + - DANMUAPI_DATABASE__NAME + - DANMUAPI_DATABASE__USER + - DANMUAPI_DATABASE__PASSWORD + - DANMUAPI_ADMIN__INITIAL_USER + volumes: + - danmu-config:/app/config + +volumes: + postgres-data: {} + danmu-config: {} diff --git a/blueprints/misaka-danmu-server/misaka-danmu-server.png b/blueprints/misaka-danmu-server/misaka-danmu-server.png new file mode 100644 index 00000000..30990611 Binary files /dev/null and b/blueprints/misaka-danmu-server/misaka-danmu-server.png differ diff --git a/blueprints/misaka-danmu-server/template.toml b/blueprints/misaka-danmu-server/template.toml new file mode 100644 index 00000000..62e1c268 --- /dev/null +++ b/blueprints/misaka-danmu-server/template.toml @@ -0,0 +1,30 @@ +[variables] +main_domain = "${domain}" +db_password = "${password:24}" +db_user = "danmuapi" +db_name = "danmuapi" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "danmu-app" +port = 7768 +host = "${main_domain}" + +[config.env] +# PostgreSQL +POSTGRES_PASSWORD = "${db_password}" +POSTGRES_USER = "${db_user}" +POSTGRES_DB = "${db_name}" + +# Danmu App Database Connection +DANMUAPI_DATABASE__TYPE = "postgresql" +DANMUAPI_DATABASE__HOST = "postgres" +DANMUAPI_DATABASE__PORT = "5432" +DANMUAPI_DATABASE__NAME = "${db_name}" +DANMUAPI_DATABASE__USER = "${db_user}" +DANMUAPI_DATABASE__PASSWORD = "${db_password}" + +# Admin +DANMUAPI_ADMIN__INITIAL_USER = "admin" diff --git a/blueprints/nextcloud-aio/docker-compose.yml b/blueprints/nextcloud-aio/docker-compose.yml index 1f4e43e6..f262b157 100644 --- a/blueprints/nextcloud-aio/docker-compose.yml +++ b/blueprints/nextcloud-aio/docker-compose.yml @@ -1,6 +1,6 @@ services: nextcloud: - image: nextcloud:30.0.2 + image: nextcloud:32.0.5 restart: always ports: diff --git a/blueprints/openclaw/docker-compose.yml b/blueprints/openclaw/docker-compose.yml new file mode 100644 index 00000000..e6aba49b --- /dev/null +++ b/blueprints/openclaw/docker-compose.yml @@ -0,0 +1,86 @@ +services: + openclaw: + image: "coollabsio/openclaw:2026.2.6" + environment: + - AUTH_USERNAME=${AUTH_USERNAME} + - AUTH_PASSWORD=${AUTH_PASSWORD} + - OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + - OPENAI_API_KEY=${OPENAI_API_KEY} + - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} + - GEMINI_API_KEY=${GEMINI_API_KEY} + - XAI_API_KEY=${XAI_API_KEY} + - GROQ_API_KEY=${GROQ_API_KEY} + - MISTRAL_API_KEY=${MISTRAL_API_KEY} + - CEREBRAS_API_KEY=${CEREBRAS_API_KEY} + - VENICE_API_KEY=${VENICE_API_KEY} + - MOONSHOT_API_KEY=${MOONSHOT_API_KEY} + - KIMI_API_KEY=${KIMI_API_KEY} + - MINIMAX_API_KEY=${MINIMAX_API_KEY} + - ZAI_API_KEY=${ZAI_API_KEY} + - AI_GATEWAY_API_KEY=${AI_GATEWAY_API_KEY} + - OPENCODE_API_KEY=${OPENCODE_API_KEY} + - SYNTHETIC_API_KEY=${SYNTHETIC_API_KEY} + - COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN} + - XIAOMI_API_KEY=${XIAOMI_API_KEY} + - OPENCLAW_PRIMARY_MODEL=${OPENCLAW_PRIMARY_MODEL} + - DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - AWS_REGION=${AWS_REGION:-us-east-1} + - AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN} + - BEDROCK_PROVIDER_FILTER=${BEDROCK_PROVIDER_FILTER:-anthropic} + - OLLAMA_BASE_URL=${OLLAMA_BASE_URL} + - PORT=8080 + - OPENCLAW_GATEWAY_PORT=18789 + - OPENCLAW_GATEWAY_BIND=${OPENCLAW_GATEWAY_BIND:-loopback} + - OPENCLAW_STATE_DIR=/data/.openclaw + - OPENCLAW_WORKSPACE_DIR=/data/workspace + - BROWSER_CDP_URL=http://browser:9223 + - BROWSER_DEFAULT_PROFILE=${BROWSER_DEFAULT_PROFILE:-openclaw} + - BROWSER_EVALUATE_ENABLED=${BROWSER_EVALUATE_ENABLED:-true} + - BROWSER_SNAPSHOT_MODE=${BROWSER_SNAPSHOT_MODE:-efficient} + - BROWSER_REMOTE_TIMEOUT_MS=${BROWSER_REMOTE_TIMEOUT_MS:-1500} + - BROWSER_REMOTE_HANDSHAKE_TIMEOUT_MS=${BROWSER_REMOTE_HANDSHAKE_TIMEOUT_MS:-3000} + - HOOKS_ENABLED=${HOOKS_ENABLED:-false} + - HOOKS_PATH=${HOOKS_PATH:-/hooks} + - MOONSHOT_BASE_URL=${MOONSHOT_BASE_URL:-https://api.moonshot.ai/v1} + - KIMI_BASE_URL=${KIMI_BASE_URL:-https://api.moonshot.ai/anthropic} + - TELEGRAM_BOT_TOKEN=$TELEGRAM_BOT_TOKEN + - DISCORD_BOT_TOKEN=$DISCORD_BOT_TOKEN + - SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN + - SLACK_APP_TOKEN=$SLACK_APP_TOKEN + - WHATSAPP_ENABLED=$WHATSAPP_ENABLED + - OPENCLAW_DOCKER_APT_PACKAGES=$OPENCLAW_DOCKER_APT_PACKAGES + volumes: + - "openclaw-data:/data" + depends_on: + browser: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-sf", "http://127.0.0.1:8080/healthz"] + interval: 10s + timeout: 10s + retries: 5 + + + browser: + image: "coollabsio/openclaw-browser:latest" + environment: + - PUID=1000 + - PGID=1000 + - TZ=Etc/UTC + - CHROME_CLI=--remote-debugging-port=9222 + volumes: + - "browser-data:/config" + shm_size: 2g + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/9222' || exit 1"] + interval: 5s + timeout: 5s + retries: 10 + + +volumes: + openclaw-data: + browser-data: diff --git a/blueprints/openclaw/openclaw.svg b/blueprints/openclaw/openclaw.svg new file mode 100644 index 00000000..6d89f848 --- /dev/null +++ b/blueprints/openclaw/openclaw.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/blueprints/openclaw/template.toml b/blueprints/openclaw/template.toml new file mode 100644 index 00000000..188d1e83 --- /dev/null +++ b/blueprints/openclaw/template.toml @@ -0,0 +1,21 @@ +[variables] +gateway_token = "${password:32}" +auth_username = "dokploy" +auth_password = "${password:32}" + +[config] +[[config.domains]] +serviceName = "openclaw" +port = 8080 +host = "${domain}" + +[config.env] +OPENCLAW_GATEWAY_TOKEN = "${gateway_token}" +OPENCLAW_GATEWAY_PORT = 18789 +AUTH_USERNAME="${auth_username}" +AUTH_PASSWORD="${auth_password}" +OPENCLAW_BRIDGE_PORT = 18790 +OPENCLAW_GATEWAY_BIND="lan" +OPENCLAW_PLUGINS="discord,memory-core" +# Get here https://openrouter.ai/ +OPENROUTER_API_KEY="YOUR-API-KEY" diff --git a/blueprints/openpanel/docker-compose.yml b/blueprints/openpanel/docker-compose.yml index f6393543..53c95bd2 100644 --- a/blueprints/openpanel/docker-compose.yml +++ b/blueprints/openpanel/docker-compose.yml @@ -54,7 +54,7 @@ services: retries: 5 op-api: - image: lindesvard/openpanel-api:2.0.0 + image: lindesvard/openpanel-api:2 restart: always command: > sh -c " @@ -97,7 +97,7 @@ services: condition: service_healthy op-dashboard: - image: lindesvard/openpanel-dashboard:2.0.0 + image: lindesvard/openpanel-dashboard:2 restart: always depends_on: op-api: @@ -111,7 +111,7 @@ services: retries: 5 op-worker: - image: lindesvard/openpanel-worker:2.0.0 + image: lindesvard/openpanel-worker:2 restart: always depends_on: op-api: diff --git a/blueprints/postgres-pgdog/docker-compose.yml b/blueprints/postgres-pgdog/docker-compose.yml new file mode 100644 index 00000000..f5164d9c --- /dev/null +++ b/blueprints/postgres-pgdog/docker-compose.yml @@ -0,0 +1,33 @@ +services: + postgres-pgdog: + image: ${PGDOG_IMAGE} + restart: unless-stopped + # Uncomment 'ports' settings below to enable external access + # ports: + # - "6432:6432" + volumes: + - ../files/pgdog.toml:/pgdog/pgdog.toml + - ../files/users.toml:/pgdog/users.toml + environment: + - RUST_LOG=${RUST_LOG} + depends_on: + postgres: + condition: service_healthy + + postgres: + image: ${POSTGRES_IMAGE} + restart: unless-stopped + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + volumes: + - postgres-data:/var/lib/postgresql + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + postgres-data: diff --git a/blueprints/postgres-pgdog/postgres-pgdog.png b/blueprints/postgres-pgdog/postgres-pgdog.png new file mode 100644 index 00000000..bbc4aae7 Binary files /dev/null and b/blueprints/postgres-pgdog/postgres-pgdog.png differ diff --git a/blueprints/postgres-pgdog/template.toml b/blueprints/postgres-pgdog/template.toml new file mode 100644 index 00000000..2ffc4ec0 --- /dev/null +++ b/blueprints/postgres-pgdog/template.toml @@ -0,0 +1,36 @@ +[variables] +postgres_user = "${username}" +postgres_password = "${password:32}" +postgres_db = "postgres" +pgdog_image = "ghcr.io/pgdogdev/pgdog:v0.1.26" +postgres_image = "postgres:18-alpine" + +[[config.mounts]] +filePath = "pgdog.toml" +content = """ +[general] +host = "0.0.0.0" +port = 6432 + +[[databases]] +name = "${postgres_db}" +host = "postgres" +port = 5432 +""" + +[[config.mounts]] +filePath = "users.toml" +content = """ +[[users]] +name = "${postgres_user}" +database = "${postgres_db}" +password = "${postgres_password}" +""" + +[config.env] +POSTGRES_USER = "${postgres_user}" +POSTGRES_PASSWORD = "${postgres_password}" +POSTGRES_DB = "${postgres_db}" +PGDOG_IMAGE = "${pgdog_image}" +POSTGRES_IMAGE = "${postgres_image}" +RUST_LOG = "info" diff --git a/blueprints/pulse/docker-compose.yml b/blueprints/pulse/docker-compose.yml new file mode 100644 index 00000000..074aec07 --- /dev/null +++ b/blueprints/pulse/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3.8" +services: + pulse: + image: rcourtman/pulse:5.1 + restart: always + expose: + - 7655 + volumes: + - pulse_data:/data + - /var/run/docker.sock:/var/run/docker.sock + environment: + - PULSE_AUTH_USER=${PULSE_AUTH_USER} + - PULSE_AUTH_PASS=${PULSE_AUTH_PASS} + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7655/api/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + +volumes: + pulse_data: \ No newline at end of file diff --git a/blueprints/pulse/pulse.svg b/blueprints/pulse/pulse.svg new file mode 100644 index 00000000..428a6e54 --- /dev/null +++ b/blueprints/pulse/pulse.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/blueprints/pulse/template.toml b/blueprints/pulse/template.toml new file mode 100644 index 00000000..865990c4 --- /dev/null +++ b/blueprints/pulse/template.toml @@ -0,0 +1,13 @@ +[variables] +main_domain = "${domain}" +pulse_auth_user = "${username}" +pulse_auth_pass = "${password:32}" + +[config] +env = ["PULSE_AUTH_USER=${pulse_auth_user}", "PULSE_AUTH_PASS=${pulse_auth_pass}"] +mounts = [] + +[[config.domains]] +serviceName = "pulse" +port = 7_655 +host = "${main_domain}" \ No newline at end of file diff --git a/blueprints/pyrodactyl/docker-compose.yml b/blueprints/pyrodactyl/docker-compose.yml index ad0e42b7..2fde33d7 100644 --- a/blueprints/pyrodactyl/docker-compose.yml +++ b/blueprints/pyrodactyl/docker-compose.yml @@ -1,6 +1,6 @@ services: database: - image: mariadb:10.5 + image: mariadb:11 restart: always command: --default-authentication-plugin=mysql_native_password volumes: @@ -14,7 +14,7 @@ services: image: redis:alpine restart: always panel: - image: ghcr.io/pyrohost/pyrodactyl:main + image: ghcr.io/pyrodactyl-oss/pyrodactyl:latest restart: always links: - database @@ -35,15 +35,8 @@ services: DB_HOST: DB_PORT: DB_PASSWORD: ${MYSQL_PASSWORD} - RECAPTCHA_ENABLED: DB_CONNECTION: "mariadb" -networks: - default: - ipam: - config: - - subnet: 172.20.0.0/16 - volumes: pterodb: pterovar: diff --git a/blueprints/qbitwebui/docker-compose.yml b/blueprints/qbitwebui/docker-compose.yml new file mode 100644 index 00000000..3e805c3c --- /dev/null +++ b/blueprints/qbitwebui/docker-compose.yml @@ -0,0 +1,39 @@ +version: "3.8" + +services: + qbitwebui: + image: ghcr.io/maciejonos/qbitwebui:latest + restart: unless-stopped + environment: + # Required: Encryption key for storing credentials (min 32 chars) + - ENCRYPTION_KEY=${ENCRYPTION_KEY} + # Optional: Server port (default: 3000) + - PORT=${PORT:-3000} + # Optional: Database location (default: ./data/qbitwebui.db) + - DATABASE_PATH=${DATABASE_PATH:-/data/qbitwebui.db} + # Optional: Salt file location (default: ./data/.salt) + - SALT_PATH=${SALT_PATH:-/data/.salt} + # Optional: Allow self-signed certificates for qBittorrent instances (default: false) + # - ALLOW_SELF_SIGNED_CERTS=${ALLOW_SELF_SIGNED_CERTS:-false} + # Optional: Disable authentication/login (single-user mode) (default: false) + # - DISABLE_AUTH=${DISABLE_AUTH:-false} + # Optional: Disable new registrations, creates default admin account (default: false) + # - DISABLE_REGISTRATION=${DISABLE_REGISTRATION:-false} + # Optional: Enable file browser by setting downloads path + # - DOWNLOADS_PATH=/downloads + volumes: + - qbitwebui_data:/data + # Optional: Mount downloads directory for file browser feature + # Read-only mount (browse & download only): + # - /path/to/your/downloads:/downloads:ro + # Or read-write mount (enables delete/move/copy/rename): + # - /path/to/your/downloads:/downloads + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + +volumes: + qbitwebui_data: diff --git a/blueprints/qbitwebui/qbitwebui.png b/blueprints/qbitwebui/qbitwebui.png new file mode 100644 index 00000000..48052dff Binary files /dev/null and b/blueprints/qbitwebui/qbitwebui.png differ diff --git a/blueprints/qbitwebui/template.toml b/blueprints/qbitwebui/template.toml new file mode 100644 index 00000000..62151ba2 --- /dev/null +++ b/blueprints/qbitwebui/template.toml @@ -0,0 +1,16 @@ +[variables] +main_domain = "${domain}" +encryption_key = "${password:32}" + +[config] +[[config.domains]] +serviceName = "qbitwebui" +port = 3000 +host = "${main_domain}" +path = "/" + +[config.env] +ENCRYPTION_KEY = "${encryption_key}" +PORT = "3000" +DATABASE_PATH = "/data/qbitwebui.db" +SALT_PATH = "/data/.salt" diff --git a/blueprints/scrutiny/docker-compose.yml b/blueprints/scrutiny/docker-compose.yml new file mode 100644 index 00000000..56b27bd2 --- /dev/null +++ b/blueprints/scrutiny/docker-compose.yml @@ -0,0 +1,55 @@ +services: + scrutiny: + restart: unless-stopped + container_name: scrutiny + image: ghcr.io/analogj/scrutiny:master-omnibus + cap_add: + - SYS_RAWIO + ports: + - 8080 # webapp + - 8086 # influxDB admin + volumes: + - /run/udev:/run/udev:ro + - ./config:/opt/scrutiny/config + - ./influxdb:/opt/scrutiny/influxdb + devices: + - "/dev/sda" + - "/dev/sdb" + +# PROXMOX USERS: Proxmox LXCs don't have access to S.M.A.R.T data, while this may be possible on VMs using PCI passthrough, +# there's another way which is to run the scrutiny collector on proxmox host and have it send data to the scrutiny webapp running in an LXC or VM +# so basically you can use the following commented docker-compose (web+db) and run the collector directly on the proxmox host (guide: https://github.com/AnalogJ/scrutiny/blob/master/docs/INSTALL_HUB_SPOKE.md#setting-up-a-spoke-without-docker) + +# services: +# influxdb: +# restart: unless-stopped +# image: influxdb:2.2 +# ports: +# - '8086:8086' +# volumes: +# - './influxdb:/var/lib/influxdb2' +# healthcheck: +# test: ["CMD", "curl", "-f", "http://localhost:8086/health"] +# interval: 5s +# timeout: 10s +# retries: 20 +# +# +# web: +# restart: unless-stopped +# image: 'ghcr.io/analogj/scrutiny:master-web' +# ports: +# - '8080:8080' +# volumes: +# - './config:/opt/scrutiny/config' +# environment: +# SCRUTINY_WEB_INFLUXDB_HOST: 'influxdb' +# depends_on: +# influxdb: +# condition: service_healthy +# healthcheck: +# test: ["CMD", "curl", "-f", "http://localhost:8080/api/health"] +# interval: 5s +# timeout: 10s +# retries: 20 +# start_period: 10s diff --git a/blueprints/scrutiny/scrutiny.png b/blueprints/scrutiny/scrutiny.png new file mode 100644 index 00000000..c0812c1b Binary files /dev/null and b/blueprints/scrutiny/scrutiny.png differ diff --git a/blueprints/scrutiny/template.toml b/blueprints/scrutiny/template.toml new file mode 100644 index 00000000..60ff998b --- /dev/null +++ b/blueprints/scrutiny/template.toml @@ -0,0 +1 @@ +[config] \ No newline at end of file diff --git a/blueprints/searxng/docker-compose.yml b/blueprints/searxng/docker-compose.yml index 856490c6..721c077a 100644 --- a/blueprints/searxng/docker-compose.yml +++ b/blueprints/searxng/docker-compose.yml @@ -1,20 +1,18 @@ -version: "3.8" services: - redis: + valkey: image: valkey/valkey:8-alpine command: valkey-server --save 30 1 --loglevel warning restart: unless-stopped volumes: - - redis-data:/data + - valkey-data:/data searxng: image: searxng/searxng:latest restart: unless-stopped volumes: - - searxng-config:/etc/searxng + - ../files/searxng:/etc/searxng - searxng-data:/var/cache/searxng volumes: - redis-data: {} - searxng-config: {} + valkey-data: {} searxng-data: {} diff --git a/blueprints/searxng/template.toml b/blueprints/searxng/template.toml index 78f7bc68..092aca39 100644 --- a/blueprints/searxng/template.toml +++ b/blueprints/searxng/template.toml @@ -12,11 +12,15 @@ env = [ ] [[config.mounts]] -filePath = "/etc/searxng/settings.yml" +filePath = "/searxng/settings.yml" content = """ use_default_settings: true + server: secret_key: \"${secret_key}\" limiter: false image_proxy: false + +valkey: + url: valkey://valkey:6379/0 """ \ No newline at end of file diff --git a/blueprints/seaweedfs/docker-compose.yml b/blueprints/seaweedfs/docker-compose.yml new file mode 100644 index 00000000..ca4a0968 --- /dev/null +++ b/blueprints/seaweedfs/docker-compose.yml @@ -0,0 +1,114 @@ +services: + master: + image: chrislusf/seaweedfs:4.02 + command: > + -v=0 + master + -volumeSizeLimitMB=10240 + -ip=master + -ip.bind=0.0.0.0 + -port=9333 + -mdir=/data/master + volumes: + - seaweedfs-master:/data/master + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:9333"] + interval: 30s + timeout: 10s + retries: 3 + expose: + - 9333 + deploy: + resources: + limits: + memory: 512M + reservations: + memory: 256M + + volume: + image: chrislusf/seaweedfs:4.02 + command: > + -v=0 + volume + -mserver="master:9333" + -port=8080 + -dir=/data/volume + -max=100 + volumes: + - seaweedfs-volume:/data/volume + depends_on: + master: + condition: service_healthy + restart: unless-stopped + expose: + - 8080 + deploy: + resources: + limits: + memory: 1G + reservations: + memory: 512M + + filer: + image: chrislusf/seaweedfs:4.02 + command: > + -v=0 + filer + -defaultReplicaPlacement=000 + -master="master:9333" + -ip=filer + -ip.bind=0.0.0.0 + -port=8888 + environment: + - WEED_MASTER=master:9333 + volumes: + - seaweedfs-filer:/data + depends_on: + - master + - volume + restart: unless-stopped + # # Secure the GUI with username/password + # labels: + # # htpasswd -nb admin admin + # - "traefik.http.middlewares.basic-auth.basicauth.users=admin:$$apr1$$aLLYxhdC$$ZAW26eJfBRC8qWjCkcZns." + # - "traefik.http.routers.service-name.middlewares=basic-auth" + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:8888"] + interval: 30s + timeout: 10s + retries: 3 + deploy: + resources: + limits: + memory: 1G + reservations: + memory: 512M + expose: + - 8888 + + s3: + image: chrislusf/seaweedfs:4.02 + command: > + -v=0 + s3 + -filer="filer:8888" + -ip.bind=0.0.0.0 + -port=8333 + environment: + - AWS_ACCESS_KEY_ID=${S3_ACCESS_KEY} + - AWS_SECRET_ACCESS_KEY=${S3_SECRET_KEY} + restart: unless-stopped + deploy: + resources: + limits: + memory: 512M + reservations: + memory: 256M + expose: + - 8333 + +volumes: + seaweedfs-master: + seaweedfs-volume: + seaweedfs-filer: diff --git a/blueprints/seaweedfs/seaweedfs.svg b/blueprints/seaweedfs/seaweedfs.svg new file mode 100644 index 00000000..61fce568 --- /dev/null +++ b/blueprints/seaweedfs/seaweedfs.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blueprints/seaweedfs/template.toml b/blueprints/seaweedfs/template.toml new file mode 100644 index 00000000..a72ae280 --- /dev/null +++ b/blueprints/seaweedfs/template.toml @@ -0,0 +1,27 @@ +[variables] +main_domain = "${domain}" +filer_domain = "filer.${domain}" +master_domain = "master.${domain}" +s3_domain = "s3.${domain}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "filer" +port = 8888 +host = "${filer_domain}" + +[[config.domains]] +serviceName = "master" +port = 9333 +host = "${master_domain}" + +[[config.domains]] +serviceName = "s3" +port = 8333 +host = "${s3_domain}" + +[config.env] +S3_ACCESS_KEY = "admin" +S3_SECRET_KEY = "${password:16}" diff --git a/blueprints/strapi/docker-compose.yml b/blueprints/strapi/docker-compose.yml new file mode 100644 index 00000000..6ac724fc --- /dev/null +++ b/blueprints/strapi/docker-compose.yml @@ -0,0 +1,58 @@ +# Self-host guide: +# - https://strapi.io/blog/how-to-self-host-your-headless-cms-using-docker-compose + +services: + strapi: + image: elestio/strapi-production:v5.33.0 + environment: + # https://docs.strapi.io/cms/configurations/environment + NODE_ENV: production + STRAPI_TELEMETRY_DISABLED: true + STRAPI_PLUGIN_I18N_INIT_LOCALE_CODE: en + FAST_REFRESH: true + JWT_SECRET: ${JWT_SECRET} + ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET} + DATABASE_CLIENT: postgres + DATABASE_HOST: strapi_postgres + DATABASE_PORT: 5432 + DATABASE_NAME: strapi + DATABASE_USERNAME: strapi + DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - strapi_data:/srv/app + expose: + - 1337 + depends_on: + - strapi_postgres + healthcheck: + test: + - CMD + - wget + - "-q" + - "--spider" + - "http://127.0.0.1:1337" + start_period: 3s + interval: 30s + timeout: 10s + retries: 5 + + strapi_postgres: + image: postgres:18 + environment: + POSTGRES_DB: strapi + POSTGRES_USER: strapi + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - strapi_postgres_data:/var/lib/postgresql + healthcheck: + test: + - CMD-SHELL + - "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" + start_period: 3s + interval: 30s + timeout: 10s + retries: 5 + +volumes: + strapi_data: + strapi_postgres_data: diff --git a/blueprints/strapi/strapi.svg b/blueprints/strapi/strapi.svg new file mode 100644 index 00000000..1e4ed993 --- /dev/null +++ b/blueprints/strapi/strapi.svg @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/blueprints/strapi/template.toml b/blueprints/strapi/template.toml new file mode 100644 index 00000000..0acddaf5 --- /dev/null +++ b/blueprints/strapi/template.toml @@ -0,0 +1,15 @@ +[variables] +main_domain = "${domain}" +postgres_password = "${password:32}" +jwt_secret = "${password:32}" +admin_jwt_secret = "${password:32}" + +[[config.domains]] +serviceName = "strapi" +port = 1337 +host = "${main_domain}" + +[config.env] +POSTGRES_PASSWORD = "${postgres_password}" +JWT_SECRET = "${jwt_secret}" +ADMIN_JWT_SECRET = "${admin_jwt_secret}" diff --git a/blueprints/streamflow/docker-compose.yml b/blueprints/streamflow/docker-compose.yml new file mode 100644 index 00000000..cbfa8b51 --- /dev/null +++ b/blueprints/streamflow/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3.8" +services: + streamflow: + build: + context: https://github.com/bangtutorial/streamflow.git + restart: unless-stopped + environment: + - PORT=7575 + - SESSION_SECRET=${SESSION_SECRET} + - NODE_ENV=production + - TZ=${TIMEZONE} + volumes: + - streamflow-db:/app/db + - streamflow-logs:/app/logs + - streamflow-uploads:/app/public/uploads + ports: + - 7575 + +volumes: + streamflow-db: {} + streamflow-logs: {} + streamflow-uploads: {} diff --git a/blueprints/streamflow/streamflow.png b/blueprints/streamflow/streamflow.png new file mode 100644 index 00000000..ac281760 Binary files /dev/null and b/blueprints/streamflow/streamflow.png differ diff --git a/blueprints/streamflow/template.toml b/blueprints/streamflow/template.toml new file mode 100644 index 00000000..3867afaa --- /dev/null +++ b/blueprints/streamflow/template.toml @@ -0,0 +1,15 @@ +[variables] +main_domain = "${domain}" +session_secret = "${password:64}" + +[config] +[[config.domains]] +serviceName = "streamflow" +port = 7575 +host = "${main_domain}" + +[config.env] +SESSION_SECRET = "${session_secret}" +TIMEZONE = "Asia/Jakarta" + +[[config.mounts]] diff --git a/blueprints/supabase/docker-compose.yml b/blueprints/supabase/docker-compose.yml index 7d4dae81..506ddc90 100644 --- a/blueprints/supabase/docker-compose.yml +++ b/blueprints/supabase/docker-compose.yml @@ -77,6 +77,7 @@ services: SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY} DASHBOARD_USERNAME: ${DASHBOARD_USERNAME} DASHBOARD_PASSWORD: ${DASHBOARD_PASSWORD} + CONTAINER_PREFIX: ${CONTAINER_PREFIX} # https://unix.stackexchange.com/a/294837 entrypoint: bash -c 'eval "echo \"$$(cat ~/temp.yml)\"" > ~/kong.yml && /docker-entrypoint.sh kong docker-start' diff --git a/blueprints/supabase/template.toml b/blueprints/supabase/template.toml index 9f35f79c..f70c93cc 100644 --- a/blueprints/supabase/template.toml +++ b/blueprints/supabase/template.toml @@ -309,7 +309,7 @@ services: ## Secure Realtime routes - name: realtime-v1-ws _comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*' - url: http://realtime-dev.supabase-realtime:4000/socket + url: http://realtime-dev.${CONTAINER_PREFIX}-realtime:4000/socket protocol: ws routes: - name: realtime-v1-ws @@ -329,7 +329,7 @@ services: - anon - name: realtime-v1-rest _comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*' - url: http://realtime-dev.supabase-realtime:4000/api + url: http://realtime-dev.${CONTAINER_PREFIX}-realtime:4000/api protocol: http routes: - name: realtime-v1-rest @@ -850,7 +850,7 @@ transforms: kong: '.appname == "supabase-kong"' auth: '.appname == "supabase-auth"' rest: '.appname == "supabase-rest"' - realtime: '.appname == "realtime-dev.supabase-realtime"' + realtime: '.appname == "realtime-dev.${CONTAINER_PREFIX}-realtime"' storage: '.appname == "supabase-storage"' functions: '.appname == "supabase-edge-functions"' db: '.appname == "supabase-db"' diff --git a/blueprints/superset/docker-compose.yml b/blueprints/superset/docker-compose.yml index 076fe0a8..3a20fd04 100644 --- a/blueprints/superset/docker-compose.yml +++ b/blueprints/superset/docker-compose.yml @@ -15,23 +15,14 @@ # ## NETWORK INSTRUCTIONS # # If you want to connect superset with other internal databases managed by -# Dokploy (on dokploy-network) using internal hostnames, you will need to -# uncomment the `networks` section, both for the superset container and -# at the very bottom of this docker-compose template. +# Dokploy using internal hostnames, you will need to connect the `superset` +# container to those networks. # -# Note that the `superset` service name/hostname will not be unique on the -# global `dokploy-network`. If you plan to: -# -# 1. deploy a second instance of superset on dokploy-network, and -# 2. have other containers on dokploy-network utilise the second instance's -# Superset API (https://superset.apache.org/docs/api) -# -# Please change the service name of the second instance. services: superset: - image: amancevice/superset - restart: always + image: amancevice/superset:6.0.0 + restart: unless-stopped #networks: # - dokploy-network depends_on: @@ -52,14 +43,14 @@ services: REDIS_HOST: superset_redis superset_postgres: - image: postgres - restart: always + image: postgres:18 + restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - - superset_postgres_data:/var/lib/postgresql/data + - superset_postgres_data:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 30s @@ -67,8 +58,8 @@ services: retries: 3 superset_redis: - image: redis - restart: always + image: redis:8 + restart: unless-stopped volumes: - superset_redis_data:/data command: redis-server --requirepass ${REDIS_PASSWORD} @@ -78,10 +69,6 @@ services: timeout: 10s retries: 3 -#networks: -# dokploy-network: -# external: true - volumes: superset_postgres_data: superset_redis_data: diff --git a/blueprints/superset/template.toml b/blueprints/superset/template.toml index ec4535fd..7cee12fc 100644 --- a/blueprints/superset/template.toml +++ b/blueprints/superset/template.toml @@ -3,7 +3,6 @@ main_domain = "${domain}" secret_key = "${password:30}" postgres_password = "${password:30}" redis_password = "${password:30}" -mapbox_api_key = "" [[config.domains]] serviceName = "superset" @@ -12,7 +11,7 @@ host = "${main_domain}" [config.env] SECRET_KEY = "${secret_key}" -MAPBOX_API_KEY = "${mapbox_api_key}" +MAPBOX_API_KEY = "" POSTGRES_DB = "superset" POSTGRES_USER = "superset" POSTGRES_PASSWORD = "${postgres_password}" diff --git a/blueprints/syncthing/docker-compose.yml b/blueprints/syncthing/docker-compose.yml new file mode 100644 index 00000000..e6083a7b --- /dev/null +++ b/blueprints/syncthing/docker-compose.yml @@ -0,0 +1,19 @@ +services: + syncthing: + image: lscr.io/linuxserver/syncthing:latest + restart: unless-stopped + expose: + - 8384 + - 22000 + - 21027/udp + volumes: + - syncthing_config:/config + - syncthing_data:/var/syncthing/Sync + environment: + - PUID=1000 + - PGID=1000 + - TZ=${timezone} + +volumes: + syncthing_config: + syncthing_data: diff --git a/blueprints/syncthing/syncthing.svg b/blueprints/syncthing/syncthing.svg new file mode 100644 index 00000000..de8850f5 --- /dev/null +++ b/blueprints/syncthing/syncthing.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blueprints/syncthing/template.toml b/blueprints/syncthing/template.toml new file mode 100644 index 00000000..eda476e4 --- /dev/null +++ b/blueprints/syncthing/template.toml @@ -0,0 +1,9 @@ +[variables] +main_domain = "${domain}" +timezone = "America/Sao_Paulo" + +[config] +[[config.domains]] +serviceName = "syncthing" +port = 8384 +host = "${main_domain}" diff --git a/blueprints/tailscale-exitnode/template.toml b/blueprints/tailscale-exitnode/template.toml index eac3e68e..cc03571f 100644 --- a/blueprints/tailscale-exitnode/template.toml +++ b/blueprints/tailscale-exitnode/template.toml @@ -1,4 +1,4 @@ [config.env] TAILSCALE_HOSTNAME = "" -TAILSCALE_APIKEY = "" \ No newline at end of file +TAILSCALE_AUTHKEY = "" \ No newline at end of file diff --git a/blueprints/trilium-next/docker-compose.yml b/blueprints/trilium-next/docker-compose.yml new file mode 100755 index 00000000..6ffc82a5 --- /dev/null +++ b/blueprints/trilium-next/docker-compose.yml @@ -0,0 +1,23 @@ +# Running `docker-compose up` will create/use the "trilium-data" directory in the user home +services: + trilium_next: + # Optionally, replace `latest` with a version tag like `v0.110.3` + # Using `latest` may cause unintended updates to the container + image: triliumnext/trilium:v0.101.3 + # Restart the container unless it was stopped by the user + restart: unless-stopped + environment: + - TRILIUM_DATA_DIR=/home/node/trilium-data + ports: + # By default, Trilium will be available at http://localhost:8080 + # It will also be accessible at http://:8080 + # You might want to limit this with something like Docker Networks, reverse proxies, or firewall rules, + # however be aware that using UFW is known to not work with default Docker installations, see: + # https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-and-ufw + - "8080" + volumes: + # Unless TRILIUM_DATA_DIR is set, the data will be stored in the "trilium-data" directory in the home directory. + # This can also be changed with by replacing the line below with `- /path/of/your/choice:/home/node/trilium-data + - ${TRILIUM_DATA_DIR:-~/trilium-data}:/home/node/trilium-data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro diff --git a/blueprints/trilium-next/template.toml b/blueprints/trilium-next/template.toml new file mode 100755 index 00000000..0292bb68 --- /dev/null +++ b/blueprints/trilium-next/template.toml @@ -0,0 +1,13 @@ +[variables] +main_domain = "${domain}" + +[config] +env = [ +"TRILIUM_DATA_DIR=/root" +] +mount = [] + +[[config.domains]] +serviceName = "trilium_next" +port = 8080 +host = "${main_domain}" diff --git a/blueprints/trilium-next/trilium-next-logo.svg b/blueprints/trilium-next/trilium-next-logo.svg new file mode 100644 index 00000000..79f47a82 --- /dev/null +++ b/blueprints/trilium-next/trilium-next-logo.svg @@ -0,0 +1,2 @@ + +Trilium Notes \ No newline at end of file diff --git a/blueprints/trmnl-byos-laravel/docker-compose.yml b/blueprints/trmnl-byos-laravel/docker-compose.yml index f571719d..61674d23 100644 --- a/blueprints/trmnl-byos-laravel/docker-compose.yml +++ b/blueprints/trmnl-byos-laravel/docker-compose.yml @@ -1,6 +1,6 @@ services: trmnl-byos-laravel: - image: ghcr.io/usetrmnl/byos_laravel:0.21.0 + image: ghcr.io/usetrmnl/byos_laravel:0.27.0 environment: - APP_URL=${APP_URL} - PHP_OPCACHE_ENABLE=${PHP_OPCACHE_ENABLE} diff --git a/blueprints/umami/docker-compose.yml b/blueprints/umami/docker-compose.yml index b20524a7..6cd51601 100644 --- a/blueprints/umami/docker-compose.yml +++ b/blueprints/umami/docker-compose.yml @@ -1,6 +1,6 @@ services: umami: - image: ghcr.io/umami-software/umami:postgresql-v2.19.0 + image: ghcr.io/umami-software/umami:3.0.3 restart: always healthcheck: test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"] diff --git a/blueprints/uptime-kuma/docker-compose.yml b/blueprints/uptime-kuma/docker-compose.yml index ca80a8a3..f50c2013 100644 --- a/blueprints/uptime-kuma/docker-compose.yml +++ b/blueprints/uptime-kuma/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.8" services: uptime-kuma: - image: louislam/uptime-kuma:1.23.15 + image: louislam/uptime-kuma:2.1.0 restart: always volumes: - uptime-kuma-data:/app/data diff --git a/blueprints/vikunja/docker-compose.yml b/blueprints/vikunja/docker-compose.yml index 11b744b0..0d1c7fbe 100644 --- a/blueprints/vikunja/docker-compose.yml +++ b/blueprints/vikunja/docker-compose.yml @@ -1,17 +1,17 @@ -version: "3.8" - services: vikunja: image: vikunja/vikunja + user: "0:0" environment: - VIKUNJA_SERVICE_PUBLICURL: http://vikunja.local - VIKUNJA_DATABASE_HOST: db + VIKUNJA_SERVICE_PUBLICURL: ${VIKUNJA_SERVICE_PUBLICURL} + VIKUNJA_PUBLIC_PORT: ${VIKUNJA_PUBLIC_PORT} + VIKUNJA_DATABASE_HOST: ${VIKUNJA_DATABASE_HOST} VIKUNJA_DATABASE_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD} - VIKUNJA_DATABASE_TYPE: postgres - VIKUNJA_DATABASE_USER: vikunja - VIKUNJA_DATABASE_DATABASE: vikunja + VIKUNJA_DATABASE_TYPE: ${VIKUNJA_DATABASE_TYPE} + VIKUNJA_DATABASE_USER: ${VIKUNJA_DATABASE_USER} + VIKUNJA_DATABASE_DATABASE: ${VIKUNJA_DATABASE_DATABASE} VIKUNJA_SERVICE_JWTSECRET: ${VIKUNJA_SERVICE_JWTSECRET} - expose: + ports: - 3456 volumes: - vikunja-files:/app/vikunja/files @@ -24,15 +24,16 @@ services: image: postgres:17 environment: POSTGRES_PASSWORD: ${VIKUNJA_DATABASE_PASSWORD} - POSTGRES_USER: vikunja - POSTGRES_DB: vikunja + POSTGRES_USER: ${VIKUNJA_DATABASE_USER} + POSTGRES_DB: ${VIKUNJA_DATABASE_DATABASE} volumes: - vikunja-db:/var/lib/postgresql/data restart: unless-stopped healthcheck: - test: ["CMD-SHELL", "pg_isready -h localhost -U $$POSTGRES_USER"] - interval: 2s - start_period: 30s + test: ["CMD-SHELL", "pg_isready", "-U", "${VIKUNJA_DATABASE_USER}", "-d", "${VIKUNJA_DATABASE_DATABASE}"] + interval: 10s + timeout: 5s + retries: 3 volumes: vikunja-files: {} diff --git a/blueprints/vikunja/template.toml b/blueprints/vikunja/template.toml index 0a4e88f9..1740d3e6 100644 --- a/blueprints/vikunja/template.toml +++ b/blueprints/vikunja/template.toml @@ -18,10 +18,6 @@ VIKUNJA_DATABASE_USER = "vikunja" VIKUNJA_DATABASE_DATABASE = "vikunja" VIKUNJA_SERVICE_JWTSECRET = "${jwt_secret}" -POSTGRES_PASSWORD = "${db_password}" -POSTGRES_USER = "vikunja" -POSTGRES_DB = "vikunja" - [[config.mounts]] serviceName = "vikunja" volumeName = "vikunja-files" diff --git a/blueprints/wg-easy/docker-compose.yml b/blueprints/wg-easy/docker-compose.yml index 1161bb12..0a98f6d9 100644 --- a/blueprints/wg-easy/docker-compose.yml +++ b/blueprints/wg-easy/docker-compose.yml @@ -3,24 +3,23 @@ volumes: services: wg-easy: - image: ghcr.io/wg-easy/wg-easy:15 - restart: unless-stopped environment: - - WG_HOST=${WIREGUARD_HOST} - - PASSWORD=${WIREGUARD_PASSWORD} - - WG_PORT=51820 + - INIT_ENABLED=1 + - INIT_HOST=${WIREGUARD_HOST} + - INIT_PORT=51820 + - INIT_USERNAME=admin + - INIT_PASSWORD=${WIREGUARD_PASSWORD} + - INIT_DNS=1.1.1.1,8.8.8.8 - PORT=51821 - - WG_MTU=1280 - - WG_DEFAULT_DNS=1.1.1.1,8.8.8.8 - - WG_ALLOWED_IPS=0.0.0.0/0 - - WG_POST_UP=iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; - - WG_POST_DOWN=iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; + image: ghcr.io/wg-easy/wg-easy:15 + container_name: wg-easy volumes: - etc_wireguard:/etc/wireguard - /lib/modules:/lib/modules:ro ports: - "51820:51820/udp" - "51821:51821/tcp" + restart: unless-stopped cap_add: - NET_ADMIN - SYS_MODULE diff --git a/blueprints/wuzapi/docker-compose.yml b/blueprints/wuzapi/docker-compose.yml new file mode 100644 index 00000000..87b5b8b8 --- /dev/null +++ b/blueprints/wuzapi/docker-compose.yml @@ -0,0 +1,36 @@ +version: "3.8" +services: + wuzapi-server: + image: asternic/wuzapi:sha-30c1805 + restart: unless-stopped + expose: + - 8080 + environment: + - WUZAPI_ADMIN_TOKEN=${WUZAPI_ADMIN_TOKEN} + - WUZAPI_GLOBAL_ENCRYPTION_KEY=${WUZAPI_GLOBAL_ENCRYPTION_KEY} + - DB_USER=${DB_USER:-wuzapi} + - DB_PASSWORD=${DB_PASSWORD:-wuzapi} + - DB_NAME=${DB_NAME:-wuzapi} + - DB_HOST=db + - DB_PORT=5432 + - TZ=${TZ:-UTC} + depends_on: + - db + + db: + image: postgres:16-alpine + restart: always + environment: + POSTGRES_USER: ${DB_USER:-wuzapi} + POSTGRES_PASSWORD: ${DB_PASSWORD:-wuzapi} + POSTGRES_DB: ${DB_NAME:-wuzapi} + volumes: + - db_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${DB_USER:-wuzapi}"] + interval: 5s + timeout: 5s + retries: 5 + +volumes: + db_data: diff --git a/blueprints/wuzapi/template.toml b/blueprints/wuzapi/template.toml new file mode 100644 index 00000000..71d95c49 --- /dev/null +++ b/blueprints/wuzapi/template.toml @@ -0,0 +1,20 @@ +[variables] +main_domain = "${domain}" +admin_token = "${password:32}" +encryption_key = "${password:32}" +db_user = "wuzapi" +db_password = "${password:32}" +db_name = "wuzapi" + +[config] +[[config.domains]] +serviceName = "wuzapi-server" +port = 8080 +host = "${main_domain}" + +[config.env] +WUZAPI_ADMIN_TOKEN = "${admin_token}" +WUZAPI_GLOBAL_ENCRYPTION_KEY = "${encryption_key}" +DB_USER = "${db_user}" +DB_PASSWORD = "${db_password}" +DB_NAME = "${db_name}" diff --git a/blueprints/wuzapi/wuzapi.png b/blueprints/wuzapi/wuzapi.png new file mode 100644 index 00000000..f48f5d33 Binary files /dev/null and b/blueprints/wuzapi/wuzapi.png differ diff --git a/meta.json b/meta.json index a9f88590..723047d4 100644 --- a/meta.json +++ b/meta.json @@ -365,8 +365,8 @@ { "id": "appwrite", "name": "Appwrite", - "version": "1.6.1", - "description": "Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.\nUsing Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and more services.", + "version": "1.8.0", + "description": "Appwrite is an end-to-end platform for building Web, Mobile, Native, or Backend apps, packaged as a set of Docker microservices. It includes both a backend server and a fully integrated hosting solution for deploying static and server-side rendered frontends. Appwrite abstracts the complexity and repetitiveness required to build modern apps from scratch and allows you to build secure, full-stack applications faster.\nUsing Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and more services.", "links": { "github": "https://github.com/appwrite/appwrite", "website": "https://appwrite.io/", @@ -376,7 +376,9 @@ "tags": [ "database", "firebase", - "postgres" + "mariadb", + "hosting", + "self-hosted" ] }, { @@ -508,8 +510,8 @@ { "id": "autobase", "name": "Autobase", - "version": "2.3.0", - "description": "Autobase for PostgreSQL® is an open-source alternative to cloud-managed databases (DBaaS) such as Amazon RDS, Google Cloud SQL, Azure Database, and more.", + "version": "2.5.2", + "description": "Autobase for PostgreSQL® is an open-source alternative to cloud-managed databases (self-hosted DBaaS).", "links": { "github": "https://github.com/vitabaks/autobase", "website": "https://autobase.tech/", @@ -1297,6 +1299,23 @@ "console" ] }, + { + "id": "cloudflare-ddns", + "name": "Cloudflare DDNS", + "version": "1.15.1", + "description": "A small, feature-rich, and robust Cloudflare DDNS updater.", + "logo": "cloudflare-ddns.svg", + "links": { + "github": "https://github.com/favonia/cloudflare-ddns", + "website": "https://github.com/favonia/cloudflare-ddns", + "docs": "https://github.com/favonia/cloudflare-ddns" + }, + "tags": [ + "cloud", + "networking", + "ddns" + ] + }, { "id": "cloudflared", "name": "Cloudflared", @@ -1305,8 +1324,8 @@ "logo": "cloudflared.svg", "links": { "github": "https://github.com/cloudflare/cloudflared", - "website": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/", - "docs": "https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/" + "website": "https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/", + "docs": "https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/get-started/" }, "tags": [ "cloud", @@ -1315,6 +1334,24 @@ "tunnel" ] }, + { + "id": "cloudreve", + "name": "Cloudreve", + "version": "4.10.1", + "description": "Self-hosted file management and sharing system with multi-cloud storage support. Compatible with local, OneDrive, S3, and various cloud providers.", + "logo": "cloudreve.png", + "links": { + "github": "https://github.com/cloudreve/Cloudreve", + "website": "https://cloudreve.org", + "docs": "https://docs.cloudreve.org" + }, + "tags": [ + "storage", + "file-sharing", + "cloud", + "self-hosted" + ] + }, { "id": "cockpit", "name": "Cockpit", @@ -2101,6 +2138,23 @@ "media system" ] }, + { + "id": "emqx", + "name": "EMQX", + "version": "6.0.1", + "description": "A scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles", + "logo": "emqx.svg", + "links": { + "github": "https://github.com/emqx/emqx", + "website": "https://www.emqx.com", + "docs": "https://docs.emqx.com" + }, + "tags": [ + "broker", + "iot", + "mqtt" + ] + }, { "id": "enshrouded", "name": "Enshrouded", @@ -3116,6 +3170,23 @@ "events" ] }, + { + "id": "instantdb", + "name": "InstantDB", + "version": "latest", + "description": "InstantDB is a real-time database server that provides instant data synchronization and real-time updates for applications.", + "logo": "instant.svg", + "links": { + "github": "https://github.com/instantdb/instant/tree/main/server", + "website": "https://github.com/instantdb/instant", + "docs": "https://github.com/instantdb/instant" + }, + "tags": [ + "database", + "real-time", + "self-hosted" + ] + }, { "id": "invoiceshelf", "name": "InvoiceShelf", @@ -3133,6 +3204,24 @@ "finance" ] }, + { + "id": "ipfs", + "name": "IPFS (Kubo)", + "version": "latest", + "description": "IPFS (Kubo) is a decentralized peer-to-peer file sharing and storage network node. Host your own IPFS gateway and API.", + "logo": "ipfs.svg", + "links": { + "github": "https://github.com/ipfs/kubo", + "website": "https://ipfs.tech/", + "docs": "https://docs.ipfs.tech/" + }, + "tags": [ + "storage", + "decentralized", + "p2p", + "self-hosted" + ] + }, { "id": "it-tools", "name": "IT Tools", @@ -3182,6 +3271,25 @@ "media system" ] }, + { + "id": "jenkins", + "name": "jenkins", + "version": "latest", + "description": "Jenkins is a free, open-source automation server that helps developers build, test, and deploy software by automating repetitive tasks in the software delivery pipeline.", + "logo": "jenkins.svg", + "links": { + "github": "https://github.com/jenkinsci/jenkins", + "website": "https://www.jenkins.io/", + "docs": "https://www.jenkins.io/doc/" + }, + "tags": [ + "ci-cd", + "devops", + "automation", + "pipelines", + "open-source" + ] + }, { "id": "kaneo", "name": "Kaneo", @@ -3342,6 +3450,22 @@ "web" ] }, + { + "id": "komari-monitor", + "name": "Komari Monitor", + "version": "latest", + "description": "A lightweight, self-hosted server monitoring tool for tracking server performance.", + "logo": "komari-monitor.ico", + "links": { + "github": "https://github.com/komari-monitor/komari", + "website": "https://github.com/komari-monitor/komari", + "docs": "https://github.com/komari-monitor/komari#readme" + }, + "tags": [ + "monitoring", + "self-hosted" + ] + }, { "id": "kutt", "name": "Kutt", @@ -3373,6 +3497,22 @@ "ai" ] }, + { + "id": "lavalink", + "name": "Lavalink", + "version": "4.1.1", + "description": "Lavalink is an open source standalone audio sending node based on Lavaplayer.", + "logo": "lavalink.svg", + "links": { + "github": "https://github.com/lavalink-devs/Lavalink", + "website": "https://lavalink.dev/", + "docs": "https://lavalink.dev/getting-started/index.html" + }, + "tags": [ + "voice", + "discord" + ] + }, { "id": "letterfeed", "name": "Letterfeed", @@ -3682,6 +3822,24 @@ "self-hosted" ] }, + { + "id": "mautic", + "name": "Mautic", + "version": "5.1.1", + "description": "Mautic is the world's largest open-source marketing automation project. It allows you to automate the process of finding and nurturing contacts through landing pages and forms, sending email, text messages, web notifications, and tracking your contacts.", + "logo": "mautic.svg", + "links": { + "github": "https://github.com/mautic/mautic", + "website": "https://www.mautic.org/", + "docs": "https://docs.mautic.org/en" + }, + "tags": [ + "marketing", + "automation", + "email", + "crm" + ] + }, { "id": "maybe", "name": "Maybe", @@ -3836,6 +3994,24 @@ "media" ] }, + { + "id": "minepanel", + "name": "Minepanel", + "version": "1.7.1", + "description": "Web panel for managing Minecraft servers with Docker. Create, configure, start/stop, and monitor multiple instances from a modern UI.", + "logo": "minepanel.webp", + "links": { + "github": "https://github.com/Ketbome/minepanel", + "website": "https://minepanel.ketbome.lat", + "docs": "https://minepanel.ketbome.lat" + }, + "tags": [ + "gaming", + "minecraft", + "server-management", + "docker" + ] + }, { "id": "minio", "name": "Minio", @@ -3851,6 +4027,23 @@ "storage" ] }, + { + "id": "misaka-danmu-server", + "name": "Misaka Danmu Server", + "version": "latest", + "description": "A self-hosted danmaku (bullet comments) server for live streaming and video platforms.", + "logo": "misaka-danmu-server.png", + "links": { + "github": "https://github.com/l429609201/misaka_danmu_server", + "website": "https://github.com/l429609201/misaka_danmu_server", + "docs": "https://github.com/l429609201/misaka_danmu_server#readme" + }, + "tags": [ + "streaming", + "danmaku", + "live" + ] + }, { "id": "mixpost", "name": "Mixpost", @@ -4171,8 +4364,8 @@ "description": "Obsidian LiveSync with CouchDB for real-time note synchronization.", "logo": "obsidian.png", "links": { - "github": "https://github.com/apache/couchdb", - "website": "https://couchdb.apache.org/", + "github": "https://github.com/vrtmrz/obsidian-livesync", + "website": "https://obsidian.md/sync", "docs": "https://docs.couchdb.apache.org/" }, "tags": [ @@ -4362,6 +4555,27 @@ "surrealdb" ] }, + { + "id": "openclaw", + "name": "Openclaw", + "version": "2026.1.29", + "description": "WhatsApp gateway CLI with Pi RPC agent - self-hosted AI-powered messaging platform", + "logo": "openclaw.svg", + "links": { + "github": "https://github.com/openclaw/openclaw", + "website": "https://openclaw.ai/", + "docs": "https://docs.openclaw.ai/" + }, + "tags": [ + "whatsapp", + "ai", + "messaging", + "chatbot", + "gateway", + "self-hosted", + "automation" + ] + }, { "id": "opengist", "name": "OpenGist", @@ -4910,6 +5124,25 @@ "webmail" ] }, + { + "id": "postgres-pgdog", + "name": "PostgreSQL with PgDog", + "version": "0.1.26", + "description": "PostgreSQL database with PgDog connection pooler, load balancer, and horizontal scaling proxy. A modern alternative to PgBouncer with multi-threading support.", + "logo": "postgres-pgdog.png", + "links": { + "github": "https://github.com/pgdogdev/pgdog", + "website": "https://pgdog.dev", + "docs": "https://docs.pgdog.dev" + }, + "tags": [ + "database", + "postgresql", + "pooler", + "proxy", + "load-balancer" + ] + }, { "id": "postgresus", "name": "Postgresus", @@ -4996,6 +5229,24 @@ "management" ] }, + { + "id": "pulse", + "name": "Pulse", + "version": "latest", + "description": "A responsive monitoring platform for Proxmox VE, PBS, and Docker with real-time metrics across nodes and containers.", + "logo": "pulse.svg", + "links": { + "github": "https://github.com/rcourtman/Pulse", + "website": "https://pulserelay.pro/", + "docs": "https://github.com/rcourtman/Pulse/blob/main/docs/README.md" + }, + "tags": [ + "monitoring", + "proxmox", + "docker", + "metrics" + ] + }, { "id": "pyrodactyl", "name": "Pyrodactyl", @@ -5030,6 +5281,24 @@ "file-sharing" ] }, + { + "id": "qbitwebui", + "name": "qBittorrent Web UI", + "version": "latest", + "description": "A modern web interface for managing multiple qBittorrent instances. Built with React, Hono, and Bun.", + "logo": "qbitwebui.png", + "links": { + "github": "https://github.com/Maciejonos/qbitwebui", + "website": "https://github.com/Maciejonos/qbitwebui", + "docs": "https://github.com/Maciejonos/qbitwebui#readme" + }, + "tags": [ + "torrent", + "download", + "media", + "qbittorrent" + ] + }, { "id": "qdrant", "name": "Qdrant", @@ -5288,6 +5557,22 @@ "self-hosted" ] }, + { + "id": "scrutiny", + "name": "Scrutiny", + "version": "latest", + "description": "Hard Drive S.M.A.R.T Monitoring, Historical Trends & Real World Failure Thresholds", + "logo": "scrutiny.png", + "links": { + "github": "https://github.com/AnalogJ/scrutiny/", + "website": "", + "docs": "" + }, + "tags": [ + "monitoring", + "NAS" + ] + }, { "id": "scrypted", "name": "Scrypted", @@ -5342,6 +5627,25 @@ "aggregator" ] }, + { + "id": "seaweedfs", + "name": "SeaweedFS", + "version": "latest", + "description": "SeaweedFS is a fast distributed storage system for blobs, objects, and files. Features S3-compatible API, POSIX FUSE mount, and WebDAV support.", + "logo": "seaweedfs.svg", + "links": { + "github": "https://github.com/seaweedfs/seaweedfs", + "website": "https://seaweedfs.com/", + "docs": "https://github.com/seaweedfs/seaweedfs/wiki" + }, + "tags": [ + "storage", + "s3", + "distributed", + "object-storage", + "file-system" + ] + }, { "id": "shlink", "name": "Shlink", @@ -5554,6 +5858,43 @@ "open-source" ] }, + { + "id": "streamflow", + "name": "StreamFlow", + "version": "2.1", + "description": "StreamFlow is a multi-platform live streaming web application that enables simultaneous RTMP streaming to YouTube, Facebook, and other platforms with video gallery, scheduled streaming, and real-time monitoring.", + "logo": "streamflow.png", + "links": { + "github": "https://github.com/bangtutorial/streamflow", + "website": "https://github.com/bangtutorial/streamflow", + "docs": "https://github.com/bangtutorial/streamflow#readme" + }, + "tags": [ + "streaming", + "rtmp", + "video", + "live-streaming", + "media" + ] + }, + { + "id": "strapi", + "name": "Strapi", + "version": "v5.33.0", + "description": "Open-source headless CMS to build powerful APIs with built-in content management.", + "logo": "strapi.svg", + "links": { + "github": "https://github.com/strapi/strapi", + "discord": "https://discord.com/invite/strapi", + "docs": "https://docs.strapi.io", + "website": "https://strapi.io" + }, + "tags": [ + "headless", + "cms", + "content-management" + ] + }, { "id": "supabase", "name": "SupaBase", @@ -5575,7 +5916,7 @@ { "id": "superset", "name": "Superset (Unofficial)", - "version": "latest", + "version": "6.0.0", "description": "Data visualization and data exploration platform.", "logo": "superset.svg", "links": { @@ -5608,6 +5949,23 @@ "surrealdb" ] }, + { + "id": "syncthing", + "name": "Syncthing", + "version": "latest", + "description": "Syncthing is a continuous file synchronization program that synchronizes files between two or more computers in real time.", + "logo": "syncthing.svg", + "links": { + "github": "https://github.com/syncthing/syncthing", + "website": "https://syncthing.net/", + "docs": "https://docs.syncthing.net/" + }, + "tags": [ + "file-sync", + "synchronization", + "backup" + ] + }, { "id": "tailscale-exitnode", "name": "Tailscale Exit nodes", @@ -5762,10 +6120,27 @@ "personal-use" ] }, + { + "id": "trilium-next", + "name": "TriliumNext", + "version": "latest", + "description": "Is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.", + "logo": "trilium-next-logo.svg", + "links": { + "github": "https://github.com/TriliumNext/Trilium", + "website": "https://triliumnotes.org/", + "docs": "https://docs.triliumnotes.org/" + }, + "tags": [ + "self-hosted", + "productivity", + "personal-use" + ] + }, { "id": "trmnl-byos-laravel", "name": "TRMNL BYOS Laravel", - "version": "0.21.0", + "version": "0.27.0", "description": "TRMNL BYOS Laravel is a self-hosted application to manage TRMNL e-ink devices.", "logo": "byos-laravel.svg", "links": { @@ -5846,7 +6221,7 @@ { "id": "umami", "name": "Umami", - "version": "v2.19.0", + "version": "v3.0.3", "description": "Umami is a simple, fast, privacy-focused alternative to Google Analytics.", "logo": "umami.png", "links": { @@ -5895,7 +6270,7 @@ { "id": "uptime-kuma", "name": "Uptime Kuma", - "version": "1.23.15", + "version": "2.1.0", "description": "Uptime Kuma is a free and open source monitoring tool that allows you to monitor your websites and applications.", "logo": "uptime-kuma.png", "links": { @@ -5983,7 +6358,7 @@ "description": "Vikunja is a self-hosted, open-source to-do list application to organize tasks, projects, and notes.", "logo": "image.png", "links": { - "github": "https://kolaente.dev/vikunja/", + "github": "https://github.com/go-vikunja/vikunja", "website": "https://vikunja.io/", "docs": "https://vikunja.io/docs/" }, @@ -6132,6 +6507,24 @@ "cms" ] }, + { + "id": "wuzapi", + "name": "WuzAPI", + "version": "v1.0.0", + "description": "A RESTful API service for WhatsApp with multiple device support and concurrent sessions.", + "logo": "wuzapi.png", + "links": { + "github": "https://github.com/asternic/wuzapi", + "website": "https://www.wuzapi.app/", + "docs": "https://github.com/asternic/wuzapi/blob/main/README.md" + }, + "tags": [ + "api", + "whatsapp", + "messaging", + "automation" + ] + }, { "id": "xsshunter", "name": "XSSHunter",