diff --git a/README.md b/README.md index 1e45c8c867..f21e19e31f 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ If you have a spare domain name you can configure applications to be accessible * [Authelia](https://www.authelia.com/) - The Single Sign-On Multi-Factor portal for web apps * [Authentik](https://goauthentik.io/) - an open-source Identity Provider focused on flexibility and versatility * [Barcode Buddy](https://github.com/Forceu/barcodebuddy/) - Barcode system for Grocy +* [Baserow](https://gitlab.com/baserow/baserow) - an open source no-code database and Airtable alternative * [Bazarr](https://github.com/morpheus65535/bazarr) - companion to Radarr and Sonarr for downloading subtitles * [Beets](https://beets.io/) - media library management system for obsessive music geeks * [Blaze](https://github.com/blenderskool/blaze) - File sharing progressive web app diff --git a/nas.yml b/nas.yml index 3f132b0c9c..3bab8fedce 100644 --- a/nas.yml +++ b/nas.yml @@ -93,6 +93,10 @@ tags: - barcodebuddy + - role: baserow + tags: + - baserow + - role: bazarr tags: - bazarr diff --git a/roles/baserow/defaults/main.yml b/roles/baserow/defaults/main.yml new file mode 100644 index 0000000000..efb9698d8c --- /dev/null +++ b/roles/baserow/defaults/main.yml @@ -0,0 +1,368 @@ +--- +baserow_enabled: false +baserow_available_externally: false + +# directories +baserow_data_directory: "{{ docker_home }}/baserow" + +# network +baserow_http_port: "8156" +baserow_https_port: "8157" +baserow_hostname: "baserow" +baserow_network_name: "baserow" + +# specs +baserow_caddy_memory: 1g +baserow_backend_memory: 1g +baserow_frontend_memory: 1g +baserow_celery_memory: 1g +baserow_celery_export_memory: 1g +baserow_celery_beat_memory: 1g +baserow_db_memory: 1g +baserow_redis_memory: 1g + +# docker +baserow_caddy_container_name: baserow-caddy +baserow_caddy_image_name: "caddy" +baserow_caddy_image_version: "2" +baserow_backend_container_name: baserow-backend +baserow_backend_image_name: "baserow/backend" +baserow_backend_image_version: "1.25.1" +baserow_frontend_container_name: baserow-frontend +baserow_frontend_image_name: "baserow/web-frontend" +baserow_frontend_image_version: "1.25.1" +baserow_celery_container_name: baserow-celery +baserow_celery_image_name: "baserow/backend" +baserow_celery_image_version: "1.25.1" +baserow_celery_export_container_name: baserow-celery-export +baserow_celery_export_image_name: "baserow/backend" +baserow_celery_export_image_version: "1.25.1" +baserow_celery_beat_container_name: baserow-celery-beat +baserow_celery_beat_image_name: "baserow/backend" +baserow_celery_beat_image_version: "1.25.1" +baserow_db_container_name: baserow-db +baserow_db_image_name: "postgres" +baserow_db_image_version: "15" +baserow_redis_container_name: baserow-redis +baserow_redis_image_name: "redis" +baserow_redis_image_version: "6" +baserow_user_id: "1000" +baserow_group_id: "1000" + + +# baserow +baserow_db_name: "baserow" +baserow_db_user: "baserow" +baserow_db_pass: "baserow" +baserow_secret_key: "super_secret" +baserow_jwt_signing_key: "secret_jwt_key" +baserow_public_url: "https://{{ baserow_hostname }}.{{ ansible_nas_domain }}" +baserow_db_port: "5432" +baserow_db_options: "" +baserow_database_url: "postgres://{{ baserow_db_user }}:{{ baserow_db_pass }}@{{ baserow_db_container_name }}:{{ baserow_db_port }}/{{ baserow_db_name }}" +baserow_redis_port: "6379" +baserow_redis_protocol: "redis" +baserow_redis_url: "redis://{{ baserow_redis_password }}@{{ baserow_redis_container_name }}:{{ baserow_redis_port }}" +baserow_redis_user: "redis" +baserow_redis_password: "redis" +baserow_email_smtp: "" +baserow_email_smtp_host: "" +baserow_email_smtp_port: "" +baserow_email_smtp_use_tls: "" +baserow_email_smtp_use_ssl: "" +baserow_email_smtp_user: "" +baserow_email_smtp_password: "" +baserow_email_smtp_ssl_certfile_path: "" +baserow_email_smtp_ssl_keyfile_path: "" +baserow_from_email: "" +baserow_aws_access_key_id: "" +baserow_aws_secret_access_key: "" +baserow_aws_storage_bucket_name: "" +baserow_aws_s3_region_name: "" +baserow_aws_s3_endpoint_url: "" +baserow_aws_s3_custom_domain: "" +baserow_amount_of_workers: "" +baserow_row_page_size_limit: "200" +baserow_batch_rows_size_limit: "200" +baserow_initial_table_data_limit: "" +baserow_file_upload_size_limit_mb: "1048576" +baserow_unique_row_values_size_limit: "100" +baserow_extra_allowed_hosts: "" +baserow_additional_apps: "" +baserow_plugin_git_repos: "" +baserow_plugin_urls: "" +baserow_enable_secure_proxy_ssl_header: "" +baserow_migrate_on_startup: "true" +baserow_sync_templates_on_startup: "true" +baserow_dont_update_formulas_after_migration: "" +baserow_trigger_sync_templates_after_migration: "true" +baserow_sync_templates_time_limit: "1800" +baserow_backend_debug: "" +baserow_backend_log_level: "INFO" +baserow_feature_flags: "" +baserow_enable_otel: "false" +baserow_deployment_env: "" +baserow_otel_exporter_otlp_endpoint: "" +baserow_otel_resource_attributes: "" +baserow_posthog_project_api_key: "" +baserow_posthog_host: "" +baserow_private_backend_url: "http://{{ baserow_backend_container_name }}:8000" +baserow_public_backend_url: "http://{{ baserow_backend_container_name }}:8000" +baserow_public_web_frontend_url: "http://{{ baserow_frontend_container_name }}:3000" +baserow_private_web_frontend_url: "http://{{ baserow_frontend_container_name }}:3000" +baserow_embedded_share_url: "{{ baserow_public_web_frontend_url }}" +baserow_media_url: "{{ baserow_public_url }}/media/" +baserow_media_root: "/baserow/media/" +baserow_static_root: "/baserow/static/" +baserow_airtable_import_soft_time_limit: "1800" +baserow_hours_until_trash_permanently_deleted: "72" +baserow_old_action_cleanup_interval_minutes: "5" +baserow_minutes_until_action_cleaned_up: "120" +# baserow_group_storage_usage_queue: "" +baserow_disable_anonymous_public_view_ws_connections: "" +baserow_wait_instead_of_409_conflict_error: "" +baserow_disable_model_cache: "" +baserow_plugin_dir: "/baserow/plugins" +baserow_job_expiration_time_limit: "43200" +baserow_job_cleanup_interval_minutes: "5" +baserow_row_history_cleanup_interval_minutes: "30" +baserow_row_history_retention_days: "180" +baserow_user_log_entry_cleanup_interval_minutes: "60" +baserow_user_log_entry_retention_days: "61" +baserow_max_row_report_error_count: "30" +baserow_job_soft_time_limit: "1800" +baserow_frontend_jobs_polling_timeout_ms: "2000" +baserow_initial_create_sync_table_data_limit: "5000" +baserow_max_snapshots_per_group: "-1" +baserow_snapshot_expiration_time_days: "360" +baserow_webhooks_allow_private_address: "" +baserow_webhooks_ip_blacklist: "" +baserow_webhooks_ip_whitelist: "" +baserow_webhooks_url_regex_blacklist: "" +baserow_webhooks_url_check_timeout_secs: "10" +baserow_webhooks_max_consecutive_trigger_failures: "8" +baserow_webhooks_max_retries_per_call: "8" +baserow_webhooks_max_per_table: "20" +baserow_webhooks_max_call_log_entries: "10" +baserow_webhooks_request_timeout_seconds: "5" +baserow_enterprise_audit_log_cleanup_interval_minutes: "30" +baserow_enterprise_audit_log_retention_days: "365" +baserow_allow_multiple_sso_providers_for_same_account: "" +baserow_storage_usage_job_crontab: "0 0 * * *" +baserow_seat_usage_job_crontab: "0 1 * * *" +baserow_periodic_field_update_crontab: "*/10 * * * *" +baserow_periodic_field_update_timeout_minutes: "9" +baserow_periodic_field_update_queue_name: "export" +baserow_max_concurrent_user_requests: "" +baserow_concurrent_user_requests_throttle_timeout: "30" +baserow_send_verify_email_rate_limit: "5/h" +baserow_oss_only: "" +baserow_otel_traces_sampler: "" +baserow_otel_traces_sampler_arg: "" +baserow_otel_per_module_sampler_overrides: "" +baserow_cachalot_enabled: "" +baserow_cachalot_mode: "" +baserow_cachalot_only_cachable_tables: "" +baserow_cachalot_uncachable_tables: "" +baserow_cachalot_timeout: "604800" +baserow_auto_index_view_enabled: "" +baserow_personal_view_lowest_role_allowed: "VIEWER" +baserow_disable_locked_migrations: "" +baserow_use_pg_fulltext_search: "true" +baserow_auto_vacuum: "true" +baserow_builder_domains: "" +baserow_sentry_dsn: "" +baserow_sentry_backend_dsn: "" +baserow_openai_api_key: "" +baserow_openai_organization: "" +baserow_openai_models: "" +baserow_ollama_host: "" +baserow_ollama_models: "" + +baserow_disable_public_url_check: "" +baserow_download_file_via_xhr: "0" +baserow_disable_google_docs_file_preview: "" +baserow_additional_modules: "" +baserow_max_import_file_size_mb: "512" +baserow_frontend_same_site_cookie: "lax" + +baserow_caddy_global_conf: "" +baserow_caddy_addresses: "{{ baserow_public_url }}, http://localhost, http://{{ ansible_default_ipv4.address }}" + +baserow_backend_env: + SECRET_KEY: "{{ baserow_secret_key }}" + BASEROW_JWT_SIGNING_KEY: "{{ baserow_jwt_signing_key }}" + DATABASE_PASSWORD: "{{ baserow_db_pass }}" + # If you manually change this line make sure you also change the duplicate line in + # the web-frontend service. + BASEROW_PUBLIC_URL: "{{ baserow_public_url }}" + + # Set these if you want to use an external postgres instead of the db service below. + DATABASE_USER: "{{ baserow_db_user }}" + DATABASE_NAME: "{{ baserow_db_name }}" + DATABASE_HOST: "{{ baserow_db_pass }}" + DATABASE_PORT: "{{ baserow_db_port }}" + DATABASE_OPTIONS: "{{ baserow_db_options }}" + DATABASE_URL: "{{ baserow_database_url }}" + + # Set these if you want to use an external redis instead of the redis service below. + REDIS_HOST: "{{ baserow_redis_container_name }}" + REDIS_PORT: "{{ baserow_redis_port }}" + REDIS_PROTOCOL: "{{ baserow_redis_protocol }}" + REDIS_PASSWORD: "{{ baserow_redis_password }}" + # REDIS_URL: "{{ baserow_redis_url }}" + # REDIS_USER: "{{ baserow_redis_user }}" + + # Set these to enable Baserow to send emails. + EMAIL_SMTP: "{{ baserow_email_smtp }}" + EMAIL_SMTP_HOST: "{{ baserow_email_smtp_host }}" + EMAIL_SMTP_PORT: "{{ baserow_email_smtp_port }}" + EMAIL_SMTP_USE_TLS: "{{ baserow_email_smtp_use_tls }}" + EMAIL_SMTP_USE_SSL: "{{ baserow_email_smtp_use_ssl }}" + EMAIL_SMTP_USER: "{{ baserow_email_smtp_user }}" + EMAIL_SMTP_PASSWORD: "{{ baserow_email_smtp_password }}" + EMAIL_SMTP_SSL_CERTFILE_PATH: "{{ baserow_email_smtp_ssl_certfile_path }}" + EMAIL_SMTP_SSL_KEYFILE_PATH: "{{ baserow_email_smtp_ssl_keyfile_path }}" + FROM_EMAIL: "{{ baserow_from_email }}" + + # Set these to use AWS S3 bucket to store user files. + AWS_ACCESS_KEY_ID: "{{ baserow_aws_access_key_id }}" + AWS_SECRET_ACCESS_KEY: "{{ baserow_aws_secret_access_key }}" + AWS_STORAGE_BUCKET_NAME: "{{ baserow_aws_storage_bucket_name }}" + AWS_S3_REGION_NAME: "{{ baserow_aws_s3_region_name }}" + AWS_S3_ENDPOINT_URL: "{{ baserow_aws_s3_endpoint_url }}" + AWS_S3_CUSTOM_DOMAIN: "{{ baserow_aws_s3_custom_domain }}" + + # Misc settings see https://baserow.io/docs/installation%2Fconfiguration for info + BASEROW_AMOUNT_OF_WORKERS: "{{ baserow_amount_of_workers }}" + BASEROW_ROW_PAGE_SIZE_LIMIT: "{{ baserow_row_page_size_limit }}" + BATCH_ROWS_SIZE_LIMIT: "{{ baserow_batch_rows_size_limit }}" + # INITIAL_TABLE_DATA_LIMIT: "{{ baserow_initial_table_data_limit }}" + BASEROW_FILE_UPLOAD_SIZE_LIMIT_MB: "{{ baserow_file_upload_size_limit_mb }}" + BASEROW_UNIQUE_ROW_VALUES_SIZE_LIMIT: "{{ baserow_unique_row_values_size_limit }}" + + BASEROW_EXTRA_ALLOWED_HOSTS: "{{ baserow_extra_allowed_hosts }}" + ADDITIONAL_APPS: "{{ baserow_additional_apps }}" + BASEROW_PLUGIN_GIT_REPOS: "{{ baserow_plugin_git_repos }}" + BASEROW_PLUGIN_URLS: "{{ baserow_plugin_urls }}" + + BASEROW_ENABLE_SECURE_PROXY_SSL_HEADER: "{{ baserow_enable_secure_proxy_ssl_header }}" + MIGRATE_ON_STARTUP: "{{ baserow_migrate_on_startup }}" + SYNC_TEMPLATES_ON_STARTUP: "{{ baserow_sync_templates_on_startup }}" + DONT_UPDATE_FORMULAS_AFTER_MIGRATION: "{{ baserow_dont_update_formulas_after_migration }}" + BASEROW_TRIGGER_SYNC_TEMPLATES_AFTER_MIGRATION: "{{ baserow_trigger_sync_templates_after_migration }}" + BASEROW_SYNC_TEMPLATES_TIME_LIMIT: "{{ baserow_sync_templates_time_limit }}" + + BASEROW_BACKEND_DEBUG: "{{ baserow_backend_debug }}" + BASEROW_BACKEND_LOG_LEVEL: "{{ baserow_backend_log_level }}" + FEATURE_FLAGS: "{{ baserow_feature_flags }}" + # BASEROW_ENABLE_OTEL: "{{ baserow_enable_otel }}" + BASEROW_DEPLOYMENT_ENV: "{{ baserow_deployment_env }}" + OTEL_EXPORTER_OTLP_ENDPOINT: "{{ baserow_otel_exporter_otlp_endpoint }}" + # OTEL_RESOURCE_ATTRIBUTES: "{{ baserow_otel_resource_attributes }}" + POSTHOG_PROJECT_API_KEY: "{{ baserow_posthog_project_api_key }}" + POSTHOG_HOST: "{{ baserow_posthog_host }}" + + PRIVATE_BACKEND_URL: "{{ baserow_private_backend_url }}" + PUBLIC_BACKEND_URL: "{{ baserow_public_backend_url }}" + PUBLIC_WEB_FRONTEND_URL: "{{ baserow_public_web_frontend_url }}" + BASEROW_EMBEDDED_SHARE_URL: "{{ baserow_embedded_share_url }}" + MEDIA_URL: "{{ baserow_media_url }}" + MEDIA_ROOT: "{{ baserow_media_root }}" + + BASEROW_AIRTABLE_IMPORT_SOFT_TIME_LIMIT: "{{ baserow_airtable_import_soft_time_limit }}" + HOURS_UNTIL_TRASH_PERMANENTLY_DELETED: "{{ baserow_hours_until_trash_permanently_deleted }}" + # OLD_ACTION_CLEANUP_INTERVAL_MINUTES: "{{ baserow_old_action_cleanup_interval_minutes | int }}" + MINUTES_UNTIL_ACTION_CLEANED_UP: "{{ baserow_minutes_until_action_cleaned_up }}" + # BASEROW_GROUP_STORAGE_USAGE_QUEUE: "{{ baserow_group_storage_usage_queue }}" + DISABLE_ANONYMOUS_PUBLIC_VIEW_WS_CONNECTIONS: "{{ baserow_disable_anonymous_public_view_ws_connections }}" + BASEROW_WAIT_INSTEAD_OF_409_CONFLICT_ERROR: "{{ baserow_wait_instead_of_409_conflict_error }}" + BASEROW_DISABLE_MODEL_CACHE: "{{ baserow_disable_model_cache }}" + BASEROW_PLUGIN_DIR: "{{ baserow_plugin_dir }}" + BASEROW_JOB_EXPIRATION_TIME_LIMIT: "{{ baserow_job_expiration_time_limit }}" + BASEROW_JOB_CLEANUP_INTERVAL_MINUTES: "{{ baserow_job_cleanup_interval_minutes }}" + BASEROW_ROW_HISTORY_CLEANUP_INTERVAL_MINUTES: "{{ baserow_row_history_cleanup_interval_minutes }}" + BASEROW_ROW_HISTORY_RETENTION_DAYS: "{{ baserow_row_history_retention_days }}" + BASEROW_USER_LOG_ENTRY_CLEANUP_INTERVAL_MINUTES: "{{ baserow_user_log_entry_cleanup_interval_minutes }}" + BASEROW_USER_LOG_ENTRY_RETENTION_DAYS: "{{ baserow_user_log_entry_retention_days }}" + BASEROW_MAX_ROW_REPORT_ERROR_COUNT: "{{ baserow_max_row_report_error_count }}" + BASEROW_JOB_SOFT_TIME_LIMIT: "{{ baserow_job_soft_time_limit }}" + BASEROW_FRONTEND_JOBS_POLLING_TIMEOUT_MS: "{{ baserow_frontend_jobs_polling_timeout_ms }}" + BASEROW_INITIAL_CREATE_SYNC_TABLE_DATA_LIMIT: "{{ baserow_initial_create_sync_table_data_limit }}" + BASEROW_MAX_SNAPSHOTS_PER_GROUP: "{{ baserow_max_snapshots_per_group }}" + BASEROW_SNAPSHOT_EXPIRATION_TIME_DAYS: "{{ baserow_snapshot_expiration_time_days }}" + BASEROW_WEBHOOKS_ALLOW_PRIVATE_ADDRESS: "{{ baserow_webhooks_allow_private_address }}" + BASEROW_WEBHOOKS_IP_BLACKLIST: "{{ baserow_webhooks_ip_blacklist }}" + BASEROW_WEBHOOKS_IP_WHITELIST: "{{ baserow_webhooks_ip_whitelist }}" + BASEROW_WEBHOOKS_URL_REGEX_BLACKLIST: "{{ baserow_webhooks_url_regex_blacklist }}" + BASEROW_WEBHOOKS_URL_CHECK_TIMEOUT_SECS: "{{ baserow_webhooks_url_check_timeout_secs }}" + BASEROW_WEBHOOKS_MAX_CONSECUTIVE_TRIGGER_FAILURES: "{{ baserow_webhooks_max_consecutive_trigger_failures }}" + BASEROW_WEBHOOKS_MAX_RETRIES_PER_CALL: "{{ baserow_webhooks_max_retries_per_call }}" + BASEROW_WEBHOOKS_MAX_PER_TABLE: "{{ baserow_webhooks_max_per_table }}" + BASEROW_WEBHOOKS_MAX_CALL_LOG_ENTRIES: "{{ baserow_webhooks_max_call_log_entries }}" + BASEROW_WEBHOOKS_REQUEST_TIMEOUT_SECONDS: "{{ baserow_webhooks_request_timeout_seconds }}" + BASEROW_ENTERPRISE_AUDIT_LOG_CLEANUP_INTERVAL_MINUTES: "{{ baserow_enterprise_audit_log_cleanup_interval_minutes }}" + BASEROW_ENTERPRISE_AUDIT_LOG_RETENTION_DAYS: "{{ baserow_enterprise_audit_log_retention_days }}" + BASEROW_ALLOW_MULTIPLE_SSO_PROVIDERS_FOR_SAME_ACCOUNT: "{{ baserow_allow_multiple_sso_providers_for_same_account }}" + BASEROW_STORAGE_USAGE_JOB_CRONTAB: "{{ baserow_storage_usage_job_crontab }}" + BASEROW_SEAT_USAGE_JOB_CRONTAB: "{{ baserow_seat_usage_job_crontab }}" + BASEROW_PERIODIC_FIELD_UPDATE_CRONTAB: "{{ baserow_periodic_field_update_crontab }}" + BASEROW_PERIODIC_FIELD_UPDATE_TIMEOUT_MINUTES: "{{ baserow_periodic_field_update_timeout_minutes }}" + BASEROW_PERIODIC_FIELD_UPDATE_QUEUE_NAME: "{{ baserow_periodic_field_update_queue_name }}" + BASEROW_MAX_CONCURRENT_USER_REQUESTS: "{{ baserow_max_concurrent_user_requests }}" + BASEROW_CONCURRENT_USER_REQUESTS_THROTTLE_TIMEOUT: "{{ baserow_concurrent_user_requests_throttle_timeout }}" + BASEROW_SEND_VERIFY_EMAIL_RATE_LIMIT: "{{ baserow_send_verify_email_rate_limit }}" + BASEROW_OSS_ONLY: "{{ baserow_oss_only }}" + OTEL_TRACES_SAMPLER: "{{ baserow_otel_traces_sampler }}" + OTEL_TRACES_SAMPLER_ARG: "{{ baserow_otel_traces_sampler_arg }}" + OTEL_PER_MODULE_SAMPLER_OVERRIDES: "{{ baserow_otel_per_module_sampler_overrides }}" + BASEROW_CACHALOT_ENABLED: "{{ baserow_cachalot_enabled }}" + BASEROW_CACHALOT_MODE: "{{ baserow_cachalot_mode }}" + BASEROW_CACHALOT_ONLY_CACHABLE_TABLES: "{{ baserow_cachalot_only_cachable_tables }}" + BASEROW_CACHALOT_UNCACHABLE_TABLES: "{{ baserow_cachalot_uncachable_tables }}" + BASEROW_CACHALOT_TIMEOUT: "{{ baserow_cachalot_timeout }}" + BASEROW_AUTO_INDEX_VIEW_ENABLED: "{{ baserow_auto_index_view_enabled }}" + BASEROW_PERSONAL_VIEW_LOWEST_ROLE_ALLOWED: "{{ baserow_personal_view_lowest_role_allowed }}" + BASEROW_DISABLE_LOCKED_MIGRATIONS: "{{ baserow_disable_locked_migrations }}" + BASEROW_USE_PG_FULLTEXT_SEARCH: "{{ baserow_use_pg_fulltext_search }}" + BASEROW_AUTO_VACUUM: "{{ baserow_auto_vacuum }}" + BASEROW_BUILDER_DOMAINS: "{{ baserow_builder_domains }}" + SENTRY_DSN: "{{ baserow_sentry_dsn }}" + SENTRY_BACKEND_DSN: "{{ baserow_sentry_backend_dsn }}" + BASEROW_OPENAI_API_KEY: "{{ baserow_openai_api_key }}" + BASEROW_OPENAI_ORGANIZATION: "{{ baserow_openai_organization }}" + BASEROW_OPENAI_MODELS: "{{ baserow_openai_models }}" + BASEROW_OLLAMA_HOST: "{{ baserow_ollama_host }}" + BASEROW_OLLAMA_MODELS: "{{ baserow_ollama_models }}" + +baserow_frontend_env: + BASEROW_PUBLIC_URL: "{{ baserow_public_url }}" + PRIVATE_BACKEND_URL: "{{ baserow_private_backend_url }}" + PUBLIC_BACKEND_URL: "{{ baserow_public_backend_url }}" + PUBLIC_WEB_FRONTEND_URL: "{{ baserow_public_web_frontend_url }}" + BASEROW_EMBEDDED_SHARE_URL: "{{ baserow_embedded_share_url }}" + BASEROW_DISABLE_PUBLIC_URL_CHECK: "{{ baserow_disable_public_url_check }}" + # INITIAL_TABLE_DATA_LIMIT: "{{ baserow_initial_table_data_limit }}" + DOWNLOAD_FILE_VIA_XHR: "{{ baserow_download_file_via_xhr }}" + BASEROW_DISABLE_GOOGLE_DOCS_FILE_PREVIEW: "{{ baserow_disable_google_docs_file_preview }}" + HOURS_UNTIL_TRASH_PERMANENTLY_DELETED: "{{ baserow_hours_until_trash_permanently_deleted }}" + DISABLE_ANONYMOUS_PUBLIC_VIEW_WS_CONNECTIONS: "{{ baserow_disable_anonymous_public_view_ws_connections }}" + FEATURE_FLAGS: "{{ baserow_feature_flags }}" + ADDITIONAL_MODULES: "{{ baserow_additional_modules }}" + BASEROW_MAX_IMPORT_FILE_SIZE_MB: "{{ baserow_max_import_file_size_mb }}" + BASEROW_MAX_SNAPSHOTS_PER_GROUP: "{{ baserow_max_snapshots_per_group }}" + # BASEROW_ENABLE_OTEL: "{{ baserow_enable_otel }}" + BASEROW_DEPLOYMENT_ENV: "{{ baserow_deployment_env }}" + BASEROW_OSS_ONLY: "{{ baserow_oss_only }}" + BASEROW_USE_PG_FULLTEXT_SEARCH: "{{ baserow_use_pg_fulltext_search }}" + POSTHOG_PROJECT_API_KEY: "{{ baserow_posthog_project_api_key }}" + POSTHOG_HOST: "{{ baserow_posthog_host }}" + BASEROW_UNIQUE_ROW_VALUES_SIZE_LIMIT: "{{ baserow_unique_row_values_size_limit }}" + BASEROW_ROW_PAGE_SIZE_LIMIT: "{{ baserow_row_page_size_limit }}" + BASEROW_BUILDER_DOMAINS: "{{ baserow_builder_domains }}" + BASEROW_FRONTEND_SAME_SITE_COOKIE: "{{ baserow_frontend_same_site_cookie }}" + SENTRY_DSN: "{{ baserow_sentry_dsn }}" + +baserow_celery_env: "{{ baserow_backend_env }}" +baserow_celery_export_env: "{{ baserow_backend_env }}" +baserow_celery_beat_env: "{{ baserow_backend_env }}" diff --git a/roles/baserow/docs/baserow.md b/roles/baserow/docs/baserow.md new file mode 100644 index 0000000000..a407a1f8a2 --- /dev/null +++ b/roles/baserow/docs/baserow.md @@ -0,0 +1,11 @@ +# Baserow + +Homepage: [https://gitlab.com/baserow/baserow](https://gitlab.com/baserow/baserow) + +Baserow is an open source no-code database and Airtable alternative. Create your own database without technical experience. Our user friendly no-code tool gives you the powers of a developer without leaving your browser. + +## Usage + +Set `baserow_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Baserow web interface can be found at [http://ansible_nas_host_or_ip:8156](http://ansible_nas_host_or_ip:8156). diff --git a/roles/baserow/molecule/default/molecule.yml b/roles/baserow/molecule/default/molecule.yml new file mode 100644 index 0000000000..f750d979ba --- /dev/null +++ b/roles/baserow/molecule/default/molecule.yml @@ -0,0 +1,16 @@ +--- +platforms: + - name: instance + image: geerlingguy/docker-ubuntu2204-ansible:latest + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - /var/run/docker.sock:/var/run/docker.sock + - /tmp:/tmp:rw + privileged: true + pre_build_image: true +provisioner: + inventory: + group_vars: + all: + baserow_enabled: true + baserow_data_directory: /tmp diff --git a/roles/baserow/molecule/default/side_effect.yml b/roles/baserow/molecule/default/side_effect.yml new file mode 100644 index 0000000000..0653ba264c --- /dev/null +++ b/roles/baserow/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: + baserow_enabled: false diff --git a/roles/baserow/molecule/default/verify.yml b/roles/baserow/molecule/default/verify.yml new file mode 100644 index 0000000000..b19353e023 --- /dev/null +++ b/roles/baserow/molecule/default/verify.yml @@ -0,0 +1,68 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Get baserow caddy container state + community.docker.docker_container: + name: "{{ baserow_caddy_container_name }}" + register: result_caddy + + - name: Get baserow db container state + community.docker.docker_container: + name: "{{ baserow_db_container_name }}" + register: result_db + + - name: Get baserow redis container state + community.docker.docker_container: + name: "{{ baserow_redis_container_name }}" + register: result_redis + + - name: Get baserow backend container state + community.docker.docker_container: + name: "{{ baserow_backend_container_name }}" + register: result_backend + + - name: Get baserow frontend container state + community.docker.docker_container: + name: "{{ baserow_frontend_container_name }}" + register: result_frontend + + - name: Get baserow celery container state + community.docker.docker_container: + name: "{{ baserow_celery_container_name }}" + register: result_celery + + - name: Get baserow celery export container state + community.docker.docker_container: + name: "{{ baserow_celery_export_container_name }}" + register: result_celery_export + + - name: Get baserow celery beat container state + community.docker.docker_container: + name: "{{ baserow_celery_beat_container_name }}" + register: result_celery_beat + + - name: Check if baserow containers are running + ansible.builtin.assert: + that: + - result_caddy.container['State']['Status'] == "running" + - result_caddy.container['State']['Restarting'] == false + - result_db.container['State']['Status'] == "running" + - result_db.container['State']['Restarting'] == false + - result_redis.container['State']['Status'] == "running" + - result_redis.container['State']['Restarting'] == false + - result_backend.container['State']['Status'] == "running" + - result_backend.container['State']['Restarting'] == false + - result_frontend.container['State']['Status'] == "running" + - result_frontend.container['State']['Restarting'] == false + - result_celery.container['State']['Status'] == "running" + - result_celery.container['State']['Restarting'] == false + - result_celery_export.container['State']['Status'] == "running" + - result_celery_export.container['State']['Restarting'] == false + - result_celery_beat.container['State']['Status'] == "running" + - result_celery_beat.container['State']['Restarting'] == false diff --git a/roles/baserow/molecule/default/verify_stopped.yml b/roles/baserow/molecule/default/verify_stopped.yml new file mode 100644 index 0000000000..503aa00f71 --- /dev/null +++ b/roles/baserow/molecule/default/verify_stopped.yml @@ -0,0 +1,68 @@ +--- +- 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 baserow celery beat + community.docker.docker_container: + name: "{{ baserow_celery_beat_container_name }}" + state: absent + register: result_celery_beat + + - name: Try and stop and remove baserow celery export + community.docker.docker_container: + name: "{{ baserow_celery_export_container_name }}" + state: absent + register: result_celery_export + + - name: Try and stop and remove baserow celery + community.docker.docker_container: + name: "{{ baserow_celery_container_name }}" + state: absent + register: result_celery + + - name: Try and stop and remove baserow frontend + community.docker.docker_container: + name: "{{ baserow_frontend_container_name }}" + state: absent + register: result_frontend + + - name: Try and stop and remove baserow backend + community.docker.docker_container: + name: "{{ baserow_backend_container_name }}" + state: absent + register: result_backend + + - name: Try and stop and remove baserow caddy + community.docker.docker_container: + name: "{{ baserow_caddy_container_name }}" + state: absent + register: result_caddy + + - name: Try and stop and remove baserow redis + community.docker.docker_container: + name: "{{ baserow_redis_container_name }}" + state: absent + register: result_redis + + - name: Try and stop and remove baserow db + community.docker.docker_container: + name: "{{ baserow_db_container_name }}" + state: absent + register: result_db + + - name: Check if baserow is stopped + ansible.builtin.assert: + that: + - not result_celery_beat.changed + - not result_celery_export.changed + - not result_celery.changed + - not result_frontend.changed + - not result_backend.changed + - not result_caddy.changed + - not result_redis.changed + - not result_db.changed diff --git a/roles/baserow/requirements.yml b/roles/baserow/requirements.yml new file mode 120000 index 0000000000..9a736435ab --- /dev/null +++ b/roles/baserow/requirements.yml @@ -0,0 +1 @@ +../../requirements.yml \ No newline at end of file diff --git a/roles/baserow/tasks/main.yml b/roles/baserow/tasks/main.yml new file mode 100644 index 0000000000..20597520e4 --- /dev/null +++ b/roles/baserow/tasks/main.yml @@ -0,0 +1,233 @@ +--- +- name: Start Baserow + block: + - name: Create Baserow Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + with_items: + - "{{ baserow_data_directory }}" + + - name: Create Baserow Media and Plugins Directoriy + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: 9999 + group: 9999 + with_items: + - "{{ baserow_data_directory }}/media" + - "{{ baserow_data_directory }}/plugins" + + - name: Create Baserow network + community.docker.docker_network: + name: "{{ baserow_network_name }}" + + - name: Template Caddyfile + ansible.builtin.template: + src: Caddyfile.j2 + dest: "{{ baserow_data_directory }}/Caddyfile" + register: beets_config + + - name: Create Baserow Postgress Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_db_container_name }}" + image: "{{ baserow_db_image_name }}:{{ baserow_db_image_version }}" + pull: true + volumes: + - "{{ baserow_data_directory }}/pgdata:/var/lib/postgresql/data:rw" + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + env: + POSTGRES_PASSWORD: "{{ baserow_db_pass }}" + POSTGRES_USER: "{{ baserow_db_user }}" + POSTGRES_DB: "{{ baserow_db_name }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ baserow_db_memory }}" + healthcheck: + test: ["CMD-SHELL", "su postgres -c \"pg_isready -U {{ baserow_db_user }}\""] + interval: 10s + timeout: 5s + retries: 5 + + - name: Create Baserow Redis Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_redis_container_name }}" + image: "{{ baserow_redis_image_name }}:{{ baserow_redis_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + labels: + traefik.enable: "false" + restart_policy: always + memory: "{{ baserow_redis_memory }}" + command: redis-server --requirepass {{ baserow_redis_password }} + healthcheck: + test: ["CMD", "redis-cli", "ping"] + + - name: Create Baserow Caddy Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_caddy_container_name }}" + image: "{{ baserow_caddy_image_name }}:{{ baserow_caddy_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + volumes: + - "{{ baserow_data_directory }}/Caddyfile:/etc/caddy/Caddyfile" + - "{{ baserow_data_directory }}/media:/baserow/media" + - "{{ baserow_data_directory }}/plugins:/baserow/plugins" + - "{{ baserow_data_directory }}/caddy_config:/config" + - "{{ baserow_data_directory }}/caddy_data:/data" + + ports: + - "{{ baserow_http_port }}:80" + - "{{ baserow_https_port }}:443" + env: + BASEROW_CADDY_ADDRESSES: "{{ baserow_caddy_addresses }}" + PRIVATE_WEB_FRONTEND_URL: "{{ baserow_private_web_frontend_url }}" + PRIVATE_BACKEND_URL: "{{ baserow_private_backend_url }}" + BASEROW_PUBLIC_URL: "{{ baserow_public_url }}" + restart_policy: unless-stopped + memory: "{{ baserow_caddy_memory }}" + labels: + traefik.enable: "{{ baserow_available_externally | string }}" + traefik.http.routers.baserow.rule: "Host(`{{ baserow_hostname }}.{{ ansible_nas_domain }}`)" + traefik.http.routers.baserow.tls.certresolver: "letsencrypt" + traefik.http.routers.baserow.tls.domains[0].main: "{{ ansible_nas_domain }}" + traefik.http.routers.baserow.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.baserow.loadbalancer.server.port: "80" + + - name: Create Baserow Backend Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_backend_container_name }}" + image: "{{ baserow_backend_image_name }}:{{ baserow_backend_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + volumes: + - "{{ baserow_data_directory }}/media:/baserow/media" + env: "{{ baserow_backend_env }}" + restart_policy: unless-stopped + memory: "{{ baserow_backend_memory }}" + labels: + traefik.enable: "false" + + - name: Create Baserow Frontend Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_frontend_container_name }}" + image: "{{ baserow_frontend_image_name }}:{{ baserow_frontend_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + env: "{{ baserow_frontend_env }}" + restart_policy: unless-stopped + memory: "{{ baserow_frontend_memory }}" + labels: + traefik.enable: "false" + + - name: Create Baserow Celery Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_celery_container_name }}" + image: "{{ baserow_celery_image_name }}:{{ baserow_celery_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + volumes: + - "{{ baserow_data_directory }}/media:/baserow/media" + env: "{{ baserow_celery_env }}" + restart_policy: unless-stopped + memory: "{{ baserow_celery_memory }}" + labels: + traefik.enable: "false" + healthcheck: + test: ["CMD-SHELL", "/baserow/backend/docker/docker-entrypoint.sh celery-worker-healthcheck"] + command: celery-worker + + - name: Create Baserow Celery Export Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_celery_export_container_name }}" + image: "{{ baserow_celery_export_image_name }}:{{ baserow_celery_export_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + volumes: + - "{{ baserow_data_directory }}/media:/baserow/media" + env: "{{ baserow_celery_export_env }}" + restart_policy: unless-stopped + memory: "{{ baserow_celery_export_memory }}" + labels: + traefik.enable: "false" + healthcheck: + test: ["CMD-SHELL", "/baserow/backend/docker/docker-entrypoint.sh celery-exportworker-healthcheck"] + command: celery-exportworker + + - name: Create Baserow Celery Beat Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ baserow_celery_beat_container_name }}" + image: "{{ baserow_celery_beat_image_name }}:{{ baserow_celery_beat_image_version }}" + pull: true + networks: + - name: "{{ baserow_network_name }}" + network_mode: "{{ baserow_network_name }}" + volumes: + - "{{ baserow_data_directory }}/media:/baserow/media" + env: "{{ baserow_celery_beat_env }}" + restart_policy: unless-stopped + memory: "{{ baserow_celery_beat_memory }}" + labels: + traefik.enable: "false" + stop_signal: SIGQUIT + command: celery-beat + when: baserow_enabled is true + +- name: Stop Baserow + block: + - name: Stop Baserow Celery Beat + community.docker.docker_container: + name: "{{ baserow_celery_beat_container_name }}" + state: absent + - name: Stop Baserow Celery Export + community.docker.docker_container: + name: "{{ baserow_celery_export_container_name }}" + state: absent + - name: Stop Baserow Celery + community.docker.docker_container: + name: "{{ baserow_celery_container_name }}" + state: absent + - name: Stop Baserow Frontend + community.docker.docker_container: + name: "{{ baserow_frontend_container_name }}" + state: absent + - name: Stop Baserow Backend + community.docker.docker_container: + name: "{{ baserow_backend_container_name }}" + state: absent + - name: Stop Baserow Caddy + community.docker.docker_container: + name: "{{ baserow_caddy_container_name }}" + state: absent + - name: Stop Baserow Redis + community.docker.docker_container: + name: "{{ baserow_redis_container_name }}" + state: absent + - name: Stop Baserow DB + community.docker.docker_container: + name: "{{ baserow_db_container_name }}" + state: absent + when: baserow_enabled is false diff --git a/roles/baserow/templates/Caddyfile.j2 b/roles/baserow/templates/Caddyfile.j2 new file mode 100644 index 0000000000..b5f29b486a --- /dev/null +++ b/roles/baserow/templates/Caddyfile.j2 @@ -0,0 +1,48 @@ +{ + on_demand_tls { + ask {{ baserow_private_backend_url }}/api/builder/domains/ask-public-domain-exists/ + interval 2m + burst 5 + } + + {{ baserow_caddy_global_conf }} +} + +{{ baserow_caddy_addresses }} { + tls { + on_demand + } + + @is_baserow_tool { + expression "{{ baserow_public_url }}".contains({http.request.host}) + } + + handle @is_baserow_tool { + handle /api/* { + reverse_proxy {{ baserow_private_backend_url }} + } + + handle /ws/* { + reverse_proxy {{ baserow_private_backend_url }} + } + + handle_path /media/* { + @downloads { + query dl=* + } + header @downloads Content-disposition "attachment; filename={query.dl}" + + file_server { + root {{ baserow_media_root }} + } + } + + handle_path /static/* { + file_server { + root {{ baserow_static_root }} + } + } + } + + reverse_proxy {{ baserow_private_web_frontend_url }} +} diff --git a/website/docs/applications/development-tools/baserow.md b/website/docs/applications/development-tools/baserow.md new file mode 100644 index 0000000000..0a30b4246d --- /dev/null +++ b/website/docs/applications/development-tools/baserow.md @@ -0,0 +1,14 @@ +--- +title: "Baserow" +description: "An open source no-code database and Airtable alternative" +--- + +Homepage: [https://gitlab.com/baserow/baserow](https://gitlab.com/baserow/baserow) + +Baserow is an open source no-code database and Airtable alternative. Create your own database without technical experience. Our user friendly no-code tool gives you the powers of a developer without leaving your browser. + +## Usage + +Set `baserow_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Baserow web interface can be found at [http://ansible_nas_host_or_ip:8156](http://ansible_nas_host_or_ip:8156).