From 2004db2c7ee3a8b78741f10e9f3bf18257c2b178 Mon Sep 17 00:00:00 2001 From: Anarion Date: Fri, 24 May 2024 19:55:42 +0200 Subject: [PATCH] :sparkles: Add Budibase --- README.md | 1 + nas.yml | 4 + roles/budibase/defaults/main.yml | 145 ++++++++++++++ roles/budibase/docs/budibase.md | 11 ++ roles/budibase/molecule/default/molecule.yml | 6 + .../budibase/molecule/default/side_effect.yml | 10 + roles/budibase/molecule/default/verify.yml | 61 ++++++ .../molecule/default/verify_stopped.yml | 61 ++++++ roles/budibase/requirements.yml | 1 + roles/budibase/tasks/main.yml | 186 ++++++++++++++++++ .../development-tools/budibase.md | 14 ++ 11 files changed, 500 insertions(+) create mode 100644 roles/budibase/defaults/main.yml create mode 100644 roles/budibase/docs/budibase.md create mode 100644 roles/budibase/molecule/default/molecule.yml create mode 100644 roles/budibase/molecule/default/side_effect.yml create mode 100644 roles/budibase/molecule/default/verify.yml create mode 100644 roles/budibase/molecule/default/verify_stopped.yml create mode 120000 roles/budibase/requirements.yml create mode 100644 roles/budibase/tasks/main.yml create mode 100644 website/docs/applications/development-tools/budibase.md diff --git a/README.md b/README.md index def390f48f..06191f6232 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ If you have a spare domain name you can configure applications to be accessible * [Blaze](https://github.com/blenderskool/blaze) - File sharing progressive web app * [Blocky](https://0xerr0r.github.io/blocky/) - Fast and lightweight DNS proxy as ad-blocker * [Booksonic](https://booksonic.org/) - The selfhosted audiobook server +* [Budibase](https://github.com/Budibase/budibase) - Low code platform for building business apps and workflows in minutes * [Calibre](https://calibre-ebook.com) - Calibre is a powerful and easy to use e-book manager. * [Calibre-web](https://github.com/janeczku/calibre-web) - Provides a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. * [Changedetection.io](https://github.com/dgtlmoon/changedetection.io) - Free open source website change detection, monitor and notification service diff --git a/nas.yml b/nas.yml index 853c7a057b..744ed13a7a 100644 --- a/nas.yml +++ b/nas.yml @@ -106,6 +106,10 @@ tags: - booksonic + - role: budibase + tags: + - budibase + - role: calibre tags: - calibre diff --git a/roles/budibase/defaults/main.yml b/roles/budibase/defaults/main.yml new file mode 100644 index 0000000000..a2baaf6e80 --- /dev/null +++ b/roles/budibase/defaults/main.yml @@ -0,0 +1,145 @@ +--- +budibase_enabled: false +budibase_available_externally: false + +# directories +budibase_data_directory: "{{ docker_home }}/budibase" + +# network +budibase_port: "10000" +budibase_hostname: "budibase" +budibase_network_name: "budibase" + +# specs +budibase_app_memory: 1g +budibase_worker_memory: 1g +budibase_minio_memory: 1g +budibase_proxy_memory: 1g +budibase_couchdb_memory: 1g +budibase_redis_memory: 1g +budibase_watchtower_memory: 1g + +# docker +budibase_app_container_name: budibase-app +budibase_app_image_name: "budibase.docker.scarf.sh/budibase/apps" +budibase_app_image_version: latest +budibase_worker_container_name: budibase-worker +budibase_worker_image_name: budibase.docker.scarf.sh/budibase/worker +budibase_worker_image_version: latest +budibase_minio_container_name: budibase-minio +budibase_minio_image_name: minio/minio +budibase_minio_image_version: latest +budibase_proxy_container_name: budibase-proxy +budibase_proxy_image_name: budibase/proxy +budibase_proxy_image_version: latest +budibase_couchdb_container_name: budibase-couchdb +budibase_couchdb_image_name: budibase/couchdb +budibase_couchdb_image_version: latest +budibase_redis_container_name: budibase-redis +budibase_redis_image_name: redis +budibase_redis_image_version: latest +budibase_watchtower_container_name: budibase-watchtower +budibase_watchtower_image_name: containrrr/watchtower +budibase_watchtower_image_version: latest +budibase_user_id: "1000" +budibase_group_id: "1000" + + +# budibase +budibase_couchdb_url: http://{{ budibase_couchdb_username }}:{{ budibase_couchdb_password }}@{{ budibase_couchdb_container_name }}:5984 +budibase_worker_url: http://{{ budibase_worker_container_name }}:4003 +budibase_minio_url: http://{{ budibase_minio_container_name }}:9000 +budibase_apps_url: "http://{{ budibase_app_container_name }}:4002" +budibase_redis_url: http://{{ budibase_redis_container_name }}:6379 +budibase_watchtower_url: "http://{{ budibase_watchtower_container_name }}:8080" +budibase_minio_access_key: "budibase" +budibase_minio_secret_key: "budibase" +budibase_internal_api_key: "budibase" +budibase_environment: "PRODUCTION" +budibase_app_port: "4002" +budibase_api_encryption_key: "testsecret" +budibase_jwt_secret: "testsecret" +budibase_log_level: "info" +budibase_enable_analytics: "false" +budibase_redis_password: "budibase" +budibase_admin_user_email: "admin@{{ ansible_nas_domain }}" +budibase_admin_user_password: "supersecure" +budibase_plugins_dir: "/plugins" +budibase_offline_mode: "" +budibase_cluster_port: "10000" +budibase_worker_port: "4003" +budibase_minio_browser: "off" +budibase_proxy_rate_limit_webhooks_per_second: "10" +budibase_proxy_rate_limit_api_per_second: "20" +budibase_resolver: "127.0.0.11" +budibase_couchdb_password: "budibase" +budibase_couchdb_username: "budibase" +budibase_targetbuild: "docker-compose" +budibase_watchtower_http_api: "true" +budibase_watchtower_http_api_token: "budibase" +budibase_watchtower_cleanup: "true" + +budibase_app_env: + SELF_HOSTED: "1" + COUCH_DB_URL: "{{ budibase_couchdb_url }}" + WORKER_URL: "{{ budibase_worker_url }}" + MINIO_URL: "{{ budibase_minio_url }}" + MINIO_ACCESS_KEY: "{{ budibase_minio_access_key }}" + MINIO_SECRET_KEY: "{{ budibase_minio_secret_key }}" + INTERNAL_API_KEY: "{{ budibase_internal_api_key }}" + BUDIBASE_ENVIRONMENT: "{{ budibase_environment }}" + PORT: "{{ budibase_app_port }}" + API_ENCRYPTION_KEY: "{{ budibase_api_encryption_key }}" + JWT_SECRET: "{{ budibase_jwt_secret }}" + LOG_LEVEL: "{{ budibase_log_level }}" + ENABLE_ANALYTICS: "{{ budibase_enable_analytics }}" + REDIS_URL: "{{ budibase_redis_url }}" + REDIS_PASSWORD: "{{ budibase_redis_password }}" + BB_ADMIN_USER_EMAIL: "{{ budibase_admin_user_email }}" + BB_ADMIN_USER_PASSWORD: "{{ budibase_admin_user_password }}" + PLUGINS_DIR: "{{ budibase_plugins_dir }}" + OFFLINE_MODE: "{{ budibase_offline_mode }}" + +budibase_worker_env: + SELF_HOSTED: "1" + CLUSTER_PORT: "{{ budibase_cluster_port }}" + APPS_URL: "{{ budibase_apps_url }}" + COUCH_DB_USERNAME: "{{ budibase_couchdb_username }}" + COUCH_DB_PASSWORD: "{{ budibase_couchdb_password }}" + COUCH_DB_URL: "{{ budibase_couchdb_url }}" + MINIO_URL: "{{ budibase_minio_url }}" + MINIO_ACCESS_KEY: "{{ budibase_minio_access_key }}" + MINIO_SECRET_KEY: "{{ budibase_minio_secret_key }}" + INTERNAL_API_KEY: "{{ budibase_internal_api_key }}" + PORT: "{{ budibase_worker_port }}" + API_ENCRYPTION_KEY: "{{ budibase_api_encryption_key }}" + JWT_SECRET: "{{ budibase_jwt_secret }}" + + REDIS_URL: "{{ budibase_redis_url }}" + REDIS_PASSWORD: "{{ budibase_redis_password }}" + OFFLINE_MODE: "{{ budibase_offline_mode }}" + +budibase_minio_env: + MINIO_ACCESS_KEY: "{{ budibase_minio_access_key }}" + MINIO_SECRET_KEY: "{{ budibase_minio_secret_key }}" + MINIO_BROWSER: "{{ budibase_minio_browser }}" + +budibase_proxy_env: + PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND: "{{ budibase_proxy_rate_limit_webhooks_per_second }}" + PROXY_RATE_LIMIT_API_PER_SECOND: "{{ budibase_proxy_rate_limit_api_per_second }}" + APPS_UPSTREAM_URL: "{{ budibase_apps_url }}" + WORKER_UPSTREAM_URL: "{{ budibase_worker_url }}" + MINIO_UPSTREAM_URL: "{{ budibase_minio_url }}" + COUCHDB_UPSTREAM_UR: "{{ budibase_couchdb_url }}" + WATCHTOWER_UPSTREAM_URL: "{{ budibase_watchtower_url }}" + RESOLVER: "{{ budibase_resolver }}" + +budibase_couchdb_env: + COUCHDB_PASSWORD: "{{ budibase_couchdb_password }}" + COUCHDB_USER: "{{ budibase_couchdb_username }}" + TARGETBUILD: "{{ budibase_targetbuild }}" + +budibase_watchtower_env: + WATCHTOWER_HTTP_API: "{{ budibase_watchtower_http_api }}" + WATCHTOWER_HTTP_API_TOKEN: "{{ budibase_watchtower_http_api_token }}" + WATCHTOWER_CLEANUP: "{{ budibase_watchtower_cleanup }}" diff --git a/roles/budibase/docs/budibase.md b/roles/budibase/docs/budibase.md new file mode 100644 index 0000000000..492f3baa87 --- /dev/null +++ b/roles/budibase/docs/budibase.md @@ -0,0 +1,11 @@ +# Budibase + +Homepage: [https://github.com/Budibase/budibase](https://github.com/Budibase/budibase) + +Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s, and more 🚀 + +## Usage + +Set `budibase_enabled: true` in your `inventories//group_vars/nas.yml` file. + +budibase web interface can be found at [http://ansible_nas_host_or_ip:10000](http://ansible_nas_host_or_ip:10000). diff --git a/roles/budibase/molecule/default/molecule.yml b/roles/budibase/molecule/default/molecule.yml new file mode 100644 index 0000000000..4af772b4c7 --- /dev/null +++ b/roles/budibase/molecule/default/molecule.yml @@ -0,0 +1,6 @@ +--- +provisioner: + inventory: + group_vars: + all: + budibase_enabled: true diff --git a/roles/budibase/molecule/default/side_effect.yml b/roles/budibase/molecule/default/side_effect.yml new file mode 100644 index 0000000000..083108237c --- /dev/null +++ b/roles/budibase/molecule/default/side_effect.yml @@ -0,0 +1,10 @@ +--- +- name: Stop + hosts: all + become: true + tasks: + - name: "Include {{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }} role" + ansible.builtin.include_role: + name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + vars: + budibase_enabled: false diff --git a/roles/budibase/molecule/default/verify.yml b/roles/budibase/molecule/default/verify.yml new file mode 100644 index 0000000000..8c4fe37740 --- /dev/null +++ b/roles/budibase/molecule/default/verify.yml @@ -0,0 +1,61 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Get budibase app container state + community.docker.docker_container: + name: "{{ budibase_app_container_name }}" + register: result_app + + - name: Get budibase worker container state + community.docker.docker_container: + name: "{{ budibase_worker_container_name }}" + register: result_worker + + - name: Get budibase minio container state + community.docker.docker_container: + name: "{{ budibase_minio_container_name }}" + register: result_minio + + - name: Get budibase proxy container state + community.docker.docker_container: + name: "{{ budibase_proxy_container_name }}" + register: result_proxy + + - name: Get budibase couchdb container state + community.docker.docker_container: + name: "{{ budibase_couchdb_container_name }}" + register: result_couchdb + + - name: Get budibase redis container state + community.docker.docker_container: + name: "{{ budibase_redis_container_name }}" + register: result_redis + + - name: Get budibase watchtower container state + community.docker.docker_container: + name: "{{ budibase_watchtower_container_name }}" + register: result_watchtower + + - name: Check if budibase containers are running + ansible.builtin.assert: + that: + - result_app.container['State']['Status'] == "running" + - result_app.container['State']['Restarting'] == false + - result_worker.container['State']['Status'] == "running" + - result_worker.container['State']['Restarting'] == false + - result_minio.container['State']['Status'] == "running" + - result_minio.container['State']['Restarting'] == false + - result_proxy.container['State']['Status'] == "running" + - result_proxy.container['State']['Restarting'] == false + - result_couchdb.container['State']['Status'] == "running" + - result_couchdb.container['State']['Restarting'] == false + - result_redis.container['State']['Status'] == "running" + - result_redis.container['State']['Restarting'] == false + - result_watchtower.container['State']['Status'] == "running" + - result_watchtower.container['State']['Restarting'] == false diff --git a/roles/budibase/molecule/default/verify_stopped.yml b/roles/budibase/molecule/default/verify_stopped.yml new file mode 100644 index 0000000000..061f361545 --- /dev/null +++ b/roles/budibase/molecule/default/verify_stopped.yml @@ -0,0 +1,61 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Try and stop and remove budibase app + community.docker.docker_container: + name: "{{ budibase_app_container_name }}" + state: absent + register: result_app + + - name: Try and stop and remove budibase worker + community.docker.docker_container: + name: "{{ budibase_worker_container_name }}" + state: absent + register: result_worker + + - name: Try and stop and remove budibase minio + community.docker.docker_container: + name: "{{ budibase_minio_container_name }}" + state: absent + register: result_minio + + - name: Try and stop and remove budibase proxy + community.docker.docker_container: + name: "{{ budibase_proxy_container_name }}" + state: absent + register: result_proxy + + - name: Try and stop and remove budibase couchdb + community.docker.docker_container: + name: "{{ budibase_couchdb_container_name }}" + state: absent + register: result_couchdb + + - name: Try and stop and remove budibase redis + community.docker.docker_container: + name: "{{ budibase_redis_container_name }}" + state: absent + register: result_redis + + - name: Try and stop and remove budibase watchtower + community.docker.docker_container: + name: "{{ budibase_watchtower_container_name }}" + state: absent + register: result_watchtower + + - name: Check if budibase is stopped + ansible.builtin.assert: + that: + - not result_app.changed + - not result_worker.changed + - not result_minio.changed + - not result_proxy.changed + - not result_couchdb.changed + - not result_redis.changed + - not result_watchtower.changed diff --git a/roles/budibase/requirements.yml b/roles/budibase/requirements.yml new file mode 120000 index 0000000000..9a736435ab --- /dev/null +++ b/roles/budibase/requirements.yml @@ -0,0 +1 @@ +../../requirements.yml \ No newline at end of file diff --git a/roles/budibase/tasks/main.yml b/roles/budibase/tasks/main.yml new file mode 100644 index 0000000000..ea6885459c --- /dev/null +++ b/roles/budibase/tasks/main.yml @@ -0,0 +1,186 @@ +--- +- name: Start Budibase + block: + - name: Create Budibase Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: + - "{{ budibase_data_directory }}" + + - name: Create Budibase network + community.docker.docker_network: + name: "{{ budibase_network_name }}" + + - name: Create Budibase Minio Docker Container + community.docker.docker_container: + name: "{{ budibase_minio_container_name }}" + image: "{{ budibase_minio_image_name }}:{{ budibase_minio_image_version }}" + pull: true + volumes: + - "{{ budibase_data_directory }}/minio_data:/data:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_minio_env }}" + command: server /data --console-address ":9001" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ budibase_minio_memory }}" + healthcheck: + test: "timeout 5s bash -c ':> /dev/tcp/127.0.0.1/9000' || exit 1" + interval: 30s + timeout: 20s + retries: 3 + + - name: Create Budibase Proxy Docker Container + community.docker.docker_container: + name: "{{ budibase_proxy_container_name }}" + image: "{{ budibase_proxy_image_name }}:{{ budibase_proxy_image_version }}" + pull: true + ports: + - "{{ budibase_port }}:10000" + volumes: + - "{{ budibase_data_directory }}/minio_data:/data:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_proxy_env }}" + labels: + traefik.enable: "{{ budibase_available_externally | string }}" + traefik.http.routers.budibase.rule: "Host(`{{ budibase_hostname }}.{{ ansible_nas_domain }}`)" + traefik.http.routers.budibase.tls.certresolver: "letsencrypt" + traefik.http.routers.budibase.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.budibase.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.budibase.loadbalancer.server.port: "10000" + restart_policy: always + memory: "{{ budibase_proxy_memory }}" + + - name: Create Budibase CouchDB Docker Container + community.docker.docker_container: + name: "{{ budibase_couchdb_container_name }}" + image: "{{ budibase_couchdb_image_name }}:{{ budibase_couchdb_image_version }}" + pull: true + volumes: + - "{{ budibase_data_directory }}/couchdb3_data:/opt/couchdb/data:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_couchdb_env }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ budibase_couchdb_memory }}" + + - name: Create Budibase Redis Docker Container + community.docker.docker_container: + name: "{{ budibase_redis_container_name }}" + image: "{{ budibase_redis_image_name }}:{{ budibase_redis_image_version }}" + pull: true + volumes: + - "{{ budibase_data_directory }}/redis:/data:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + command: redis-server --requirepass "{{ budibase_redis_password }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ budibase_redis_memory }}" + + - name: Create Budibase Watchtower Docker Container + community.docker.docker_container: + name: "{{ budibase_watchtower_container_name }}" + image: "{{ budibase_watchtower_image_name }}:{{ budibase_watchtower_image_version }}" + pull: true + volumes: + - /var/run/docker.sock:/var/run/docker.sock + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_watchtower_env }}" + command: --debug --http-api-update {{ budibase_app_container_name }} {{ budibase_worker_container_name }} {{ budibase_proxy_container_name }} + labels: + traefik.enable: "false" + com.centurylinklabs.watchtower.enable: "false" + restart_policy: always + memory: "{{ budibase_watchtower_memory }}" + + - name: Create Budibase App Docker Container + community.docker.docker_container: + name: "{{ budibase_app_container_name }}" + image: "{{ budibase_app_image_name }}:{{ budibase_app_image_version }}" + pull: true + volumes: + - "{{ budibase_data_directory }}/plugins:/plugins:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_app_env }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ budibase_app_memory }}" + + - name: Create Budibase Worker Docker Container + community.docker.docker_container: + name: "{{ budibase_worker_container_name }}" + image: "{{ budibase_worker_image_name }}:{{ budibase_worker_image_version }}" + pull: true + volumes: + - "{{ budibase_data_directory }}/plugins:/plugins:rw" + networks: + - name: "{{ budibase_network_name }}" + network_mode: "{{ budibase_network_name }}" + container_default_behavior: no_defaults + env: "{{ budibase_worker_env }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ budibase_worker_memory }}" + when: budibase_enabled is true + +- name: Stop Budibase + block: + - name: Stop Budibase App + community.docker.docker_container: + name: "{{ budibase_app_container_name }}" + state: absent + + - name: Stop Budibase Worker + community.docker.docker_container: + name: "{{ budibase_worker_container_name }}" + state: absent + + - name: Stop Budibase Minio + community.docker.docker_container: + name: "{{ budibase_minio_container_name }}" + state: absent + + - name: Stop Budibase Proxy + community.docker.docker_container: + name: "{{ budibase_proxy_container_name }}" + state: absent + + - name: Stop Budibase CouchDB + community.docker.docker_container: + name: "{{ budibase_couchdb_container_name }}" + state: absent + + - name: Stop Budibase Redis + community.docker.docker_container: + name: "{{ budibase_redis_container_name }}" + state: absent + + - name: Stop Budibase Watchtower + community.docker.docker_container: + name: "{{ budibase_watchtower_container_name }}" + state: absent + when: budibase_enabled is false diff --git a/website/docs/applications/development-tools/budibase.md b/website/docs/applications/development-tools/budibase.md new file mode 100644 index 0000000000..9df44c8a57 --- /dev/null +++ b/website/docs/applications/development-tools/budibase.md @@ -0,0 +1,14 @@ +--- +title: "Budibase" +description: "Low code platform for building business apps and workflows in minutes" +--- + +Homepage: [https://github.com/Budibase/budibase](https://github.com/Budibase/budibase) + +Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s, and more 🚀 + +## Usage + +Set `budibase_enabled: true` in your `inventories//group_vars/nas.yml` file. + +budibase web interface can be found at [http://ansible_nas_host_or_ip:10000](http://ansible_nas_host_or_ip:10000).