From 6b4d7f48e70db7ad4238fe3f55ef59d6659cf97f Mon Sep 17 00:00:00 2001 From: Davide Silvestri <75379892+silvestrid@users.noreply.github.com> Date: Tue, 28 Apr 2026 16:54:30 +0200 Subject: [PATCH 1/3] fix: ground Kuma with workspace plan context (#5227) * fix: ground Kuma with workspace plan context Inject the current workspace plan tier into Kuma's runtime context and add a docs-first guardrail so feature and plan questions are grounded instead of guessed. * fix: tighten Kuma plan tier grounding Handle missing and unknown license tiers explicitly, log unexpected plan lookup failures, and align the prompt with the exact lower-case plan tokens injected into assistant context. * address feedback --- ...n_context_and_hallucination_guardrail.json | 9 ++ .../baserow_enterprise/assistant/agents.py | 36 ++++++ .../baserow_enterprise/assistant/assistant.py | 36 ++++++ .../src/baserow_enterprise/assistant/deps.py | 2 + .../baserow_enterprise/assistant/prompts.py | 10 ++ .../baserow_enterprise/assistant/telemetry.py | 4 +- .../assistant/tools/search_user_docs/tools.py | 52 ++++---- .../assistant/evals/eval_utils.py | 2 + .../evals/test_eval_search_user_docs.py | 22 +++- .../assistant/test_assistant.py | 122 ++++++++++++++++++ .../test_assistant_search_docs_tools.py | 49 ++++++- 11 files changed, 311 insertions(+), 33 deletions(-) create mode 100644 changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json diff --git a/changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json b/changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json new file mode 100644 index 0000000000..b9a30c2883 --- /dev/null +++ b/changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json @@ -0,0 +1,9 @@ +{ + "type": "bug", + "message": "Give Kuma the current license tier in its context and steer uncertain feature or plan questions to docs search.", + "issue_origin": "github", + "issue_number": 5210, + "domain": "core", + "bullet_points": [], + "created_at": "2026-04-17" +} diff --git a/enterprise/backend/src/baserow_enterprise/assistant/agents.py b/enterprise/backend/src/baserow_enterprise/assistant/agents.py index 1af2110615..4d49386d1b 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/agents.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/agents.py @@ -5,6 +5,17 @@ from baserow_enterprise.assistant.prompts import AGENT_SYSTEM_PROMPT from baserow_enterprise.assistant.tools.toolset import tool_manifest_line_compact +FREE_LICENSE_TIER = "free" +_CANONICAL_LICENSE_TIERS = { + FREE_LICENSE_TIER, + "premium", + "advanced", + "enterprise", +} +_LICENSE_TIER_ALIASES = { + "enterprise_without_support": "enterprise", +} + main_agent: Agent[AssistantDeps, str] = Agent( deps_type=AssistantDeps, output_type=str, @@ -14,6 +25,17 @@ ) +def _canonical_license_tier(license_tier: str) -> str: + """ + Return the public license tier token that is safe to inject into the prompt. + """ + + normalized_tier = _LICENSE_TIER_ALIASES.get(license_tier, license_tier) + if normalized_tier in _CANONICAL_LICENSE_TIERS: + return normalized_tier + return FREE_LICENSE_TIER + + @main_agent.instructions def dynamic_ui_context(ctx) -> str: """Inject the UI context into the system prompt dynamically.""" @@ -31,6 +53,20 @@ def dynamic_mode(ctx) -> str: return f"\n{ctx.deps.mode.value}" +@main_agent.instructions +def dynamic_license_tier(ctx) -> str: + """Inject the active workspace license tier and its paid features.""" + + lt = ctx.deps.license_tier + if lt is None: + return f"\n{FREE_LICENSE_TIER}" + features = ",".join(sorted(lt.features)) + return ( + f"\n{_canonical_license_tier(lt.type)}" + f"\n{features}" + ) + + @main_agent.instructions def dynamic_current_task(ctx) -> str: """Pin the original user request as immutable context.""" diff --git a/enterprise/backend/src/baserow_enterprise/assistant/assistant.py b/enterprise/backend/src/baserow_enterprise/assistant/assistant.py index f5fbb5a423..9ec91bb701 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/assistant.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/assistant.py @@ -1,6 +1,7 @@ import asyncio from typing import Any, AsyncGenerator +from django.contrib.auth.models import AbstractUser from django.core.cache import cache from django.utils import translation @@ -22,6 +23,7 @@ from pydantic_ai.usage import UsageLimits from baserow.api.sessions import get_client_undo_redo_action_group_id +from baserow.core.models import Workspace from baserow_enterprise.assistant.agents import main_agent, title_agent from baserow_enterprise.assistant.deps import ( AgentMode, @@ -46,6 +48,8 @@ ) from baserow_enterprise.assistant.tools.navigation.utils import unsafe_navigate_to from baserow_enterprise.assistant.tools.registries import assistant_tool_registry +from baserow_premium.api.user.user_data_types import ActiveLicensesDataType +from baserow_premium.license.registries import LicenseType, license_type_registry from .models import AssistantChat, AssistantChatMessage, AssistantChatPrediction from .types import ( @@ -101,6 +105,37 @@ def set_assistant_cancellation_key( cache.set(get_assistant_cancellation_key(chat_uuid), True, timeout=timeout) +def _get_workspace_license_type( + user: AbstractUser, workspace: Workspace +) -> LicenseType | None: + """ + Pick the highest-``order`` ``LicenseType`` active for the user in the workspace, + reusing the same data the frontend consumes from ``ActiveLicensesDataType``. Returns + ``None`` when no license applies. + + :param user: The user for whom to get the license type. + :param workspace: The workspace for which to get the license type. + :return: The active LicenseType with the highest order, or None if no license is + active. + """ + + try: + active = ActiveLicensesDataType().get_user_data(user, None) + names = set(active["instance_wide"]) | set( + active["per_workspace"].get(workspace.id, {}) + ) + return max( + (lt for lt in license_type_registry.get_all() if lt.type in names), + key=lambda lt: lt.order, + default=None, + ) + except Exception: + logger.exception( + "Failed to determine workspace license type for assistant context." + ) + return None + + def _extract_tool_thought(event: FunctionToolCallEvent) -> str | None: """Extract the chain-of-thought ``thought`` argument from a tool call event, if present and non-empty.""" @@ -134,6 +169,7 @@ def __init__(self, chat: AssistantChat): user=self._user, workspace=self._workspace, tool_helpers=self._tool_helpers, + license_tier=_get_workspace_license_type(self._user, self._workspace), ) self._toolset, db_m, app_m, auto_m, explain_m = ( assistant_tool_registry.build_toolset( diff --git a/enterprise/backend/src/baserow_enterprise/assistant/deps.py b/enterprise/backend/src/baserow_enterprise/assistant/deps.py index f4bb95db97..8f8223a6b6 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/deps.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/deps.py @@ -13,6 +13,7 @@ from baserow_enterprise.assistant.tools.navigation.types import ( AnyNavigationRequestType, ) + from baserow_premium.license.registries import LicenseType class AgentMode(str, Enum): @@ -120,6 +121,7 @@ class AssistantDeps: workspace: "Workspace" tool_helpers: ToolHelpers mode: AgentMode = AgentMode.DATABASE + license_tier: "LicenseType | None" = None sources: list[str] = field(default_factory=list) dynamic_tools: list[Tool] = field(default_factory=list) database_manifest: str = "" diff --git a/enterprise/backend/src/baserow_enterprise/assistant/prompts.py b/enterprise/backend/src/baserow_enterprise/assistant/prompts.py index da98c4816b..31b81e057b 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/prompts.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/prompts.py @@ -41,6 +41,15 @@ """ +GROUNDING = """\ + +If you are not sure whether a Baserow feature, plan, limit, setting, or UI behavior exists, do not guess. Use `search_user_docs` first. +If the docs do not confirm it, say you don't know. Never invent plan names, feature names, pricing, upgrade advice, or UI paths. +The canonical plan names are Free, Premium, Advanced, and Enterprise. `` uses the lowercase equivalents (`free`, `premium`, `advanced`, `enterprise`); treat them as exact matches. +`` is the exhaustive list of paid feature flags the current workspace has. Never claim a feature is available if it is not in ``. Use `search_user_docs` to explain what each feature does. + +""" + LIMITATIONS_AND_SOURCES = f"""\ Cannot create/modify/delete: user accounts, workspaces, dashboards, widgets, snapshots, webhooks, integrations, roles, permissions. @@ -53,5 +62,6 @@ + RULES + HANDLING_AMBIGUITY + BASEROW_KNOWLEDGE + + GROUNDING + LIMITATIONS_AND_SOURCES ) diff --git a/enterprise/backend/src/baserow_enterprise/assistant/telemetry.py b/enterprise/backend/src/baserow_enterprise/assistant/telemetry.py index f1242c39a9..609b78fb7f 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/telemetry.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/telemetry.py @@ -36,6 +36,7 @@ from uuid import uuid4 from opentelemetry.sdk.trace import ReadableSpan, SpanProcessor, TracerProvider +from opentelemetry.sdk.trace.sampling import ALWAYS_ON from opentelemetry.trace import SpanKind from baserow.core.posthog import get_posthog_client @@ -461,7 +462,8 @@ def setup_instrumentation(): from pydantic_ai import Agent, InstrumentationSettings - tracer_provider = TracerProvider() + # Prevent environment OTEL_TRACES_SAMPLER config from dropping assistant traces. + tracer_provider = TracerProvider(sampler=ALWAYS_ON) tracer_provider.add_span_processor(PosthogSpanProcessor()) Agent.instrument_all( diff --git a/enterprise/backend/src/baserow_enterprise/assistant/tools/search_user_docs/tools.py b/enterprise/backend/src/baserow_enterprise/assistant/tools/search_user_docs/tools.py index 79d360ff52..f4468d79cd 100644 --- a/enterprise/backend/src/baserow_enterprise/assistant/tools/search_user_docs/tools.py +++ b/enterprise/backend/src/baserow_enterprise/assistant/tools/search_user_docs/tools.py @@ -170,6 +170,9 @@ async def _search_user_docs_impl( ) -> dict[str, Any]: """Inner implementation of search_user_docs, separated for error handling.""" + from baserow_enterprise.assistant.model_profiles import get_model_string + from baserow_enterprise.assistant.retrying_model import _resolve_model + @sync_to_async def _search(question: str) -> list[KnowledgeBaseChunk]: chunks = KnowledgeBaseHandler().search(question, 15) @@ -198,41 +201,35 @@ def _search(question: str) -> list[KnowledgeBaseChunk]: f"Question: {question}\n\n" f"Documentation context (source URL -> content):\n{context}" ) - from baserow_enterprise.assistant.model_profiles import get_model_string - from baserow_enterprise.assistant.retrying_model import _resolve_model agent_result = await search_docs_agent.run( prompt, model=_resolve_model(get_model_string()) ) prediction = agent_result.output + # Force reliability to 0 if model says nothing was found. + nothing_found = "nothing found" in prediction.answer.lower() + reliability = 0.0 if nothing_found else prediction.reliability + sources = [] available_urls = {chunk.source_document.source_url for chunk in relevant_chunks} - for url in prediction.sources: - # somehow LLMs sometimes return sources as objects - if isinstance(url, dict) and "url" in url: - url = url["url"] - - if not isinstance(url, str): - continue - - if url in available_urls and url not in sources: - sources.append(url) - if len(sources) >= 3: - break - - # Only fallback to available URLs if reliability is high AND we have a - # real answer. Don't populate sources if the model indicated no relevant - # docs were found. - nothing_found = "nothing found" in prediction.answer.lower() - if not sources and prediction.reliability > 0.8 and not nothing_found: - sources = list(available_urls)[:3] + if not nothing_found: + for url in prediction.sources: + # somehow LLMs sometimes return sources as objects + if isinstance(url, dict) and "url" in url: + url = url["url"] - # Override reliability to 0 if the model explicitly said nothing was - # found. The model sometimes returns high reliability for "nothing - # found" answers, which is semantically incorrect - we want reliability - # to reflect whether we actually found useful information. - reliability = 0.0 if nothing_found else prediction.reliability + if not isinstance(url, str): + continue + + if url in available_urls and url not in sources: + sources.append(url) + if len(sources) >= 3: + break + + # Fallback to available URLs if the model didn't cite sources. + if not sources: + sources = list(available_urls)[:3] if reliability >= 0.7: reliability_note = ( @@ -242,7 +239,8 @@ def _search(question: str) -> list[KnowledgeBaseChunk]: reliability_note = ( "PARTIAL MATCH: Some relevant information was found, but the " "documentation may not fully cover this topic. Supplement with " - "general knowledge but warn the user that details may be incomplete." + "general knowledge if you're confident it is accurate and up to date, " + "but warn the user that details may be incomplete." ) else: reliability_note = ( diff --git a/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/eval_utils.py b/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/eval_utils.py index e4d9963fca..125b58e523 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/eval_utils.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/eval_utils.py @@ -15,6 +15,7 @@ from pydantic_ai.usage import UsageLimits from baserow_enterprise.assistant.agents import main_agent +from baserow_enterprise.assistant.assistant import _get_workspace_license_type from baserow_enterprise.assistant.deps import AssistantDeps, ToolHelpers from baserow_enterprise.assistant.tools.registries import assistant_tool_registry from baserow_enterprise.assistant.types import ( @@ -209,6 +210,7 @@ def create_eval_assistant(user, workspace, max_iters=15, model=None): user=user, workspace=workspace, tool_helpers=tool_helpers, + license_tier=_get_workspace_license_type(user, workspace), ) # Build the single-agent toolset (navigation + core + database + automation) diff --git a/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/test_eval_search_user_docs.py b/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/test_eval_search_user_docs.py index b3b7f7831e..ce44cb4637 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/test_eval_search_user_docs.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/assistant/evals/test_eval_search_user_docs.py @@ -111,6 +111,21 @@ def _require_knowledge_base(synced_knowledge_base): ["permission", "field", "read", "lock"], id="field-permissions", ), + pytest.param( + "Which Baserow plan unlocks field-level permissions for a workspace?", + ["field-level-permissions", "permissions"], + ["plan", "field-level permissions", "field permissions", "enterprise"], + id="plan-for-field-level-permissions", + ), + pytest.param( + ( + "I can't find the conditional options toggle for my single select field. " + "Should I upgrade, or is there another requirement?" + ), + ["single-select", "select-option", "fields"], + ["conditional", "single select", "plan", "upgrade"], + id="conditional-options-plan-question", + ), pytest.param( ( "How can I create a calendar that shows my tasks, but only the ones assigned to me." @@ -121,9 +136,8 @@ def _require_knowledge_base(synced_knowledge_base): ), pytest.param( ( - "I'm trying to combine the first name and last name columns " - "into one, but I want to make sure it's uppercase. Can you tell me how to " - "write that formula?" + "What would a formula look like that combines a first name and last name field " + "into a full name field?" ), ["formula", "understanding-formulas"], ["concat", "upper", "formula"], @@ -270,7 +284,7 @@ def test_search_user_docs( hint=f"tools called: {[e.get('tool_name') for e in history if e.get('tool_name')]}", ) checks.check( - f"returned at least one source URL for user docs", + "returned at least one source URL for user docs", len(sources) >= 1, hint=f"tools called: {[e.get('tool_name') for e in history if e.get('tool_name')]}", ) diff --git a/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant.py b/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant.py index 62e5e77d54..06a39393db 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant.py @@ -7,13 +7,16 @@ from pydantic_ai.messages import PartStartEvent from pydantic_ai.messages import TextPart as PaiTextPart +from baserow_enterprise.assistant.agents import dynamic_license_tier from baserow_enterprise.assistant.assistant import ( Assistant, + _get_workspace_license_type, compact_message_history, get_model_string, ) from baserow_enterprise.assistant.deps import AssistantDeps from baserow_enterprise.assistant.models import AssistantChat, AssistantChatMessage +from baserow_enterprise.assistant.prompts import AGENT_SYSTEM_PROMPT from baserow_enterprise.assistant.types import ( AiMessage, AiMessageChunk, @@ -308,6 +311,125 @@ def test_preserves_simple_conversations(self): assert len(compacted) == 2 +@pytest.mark.django_db +class TestAssistantLicenseTier: + @patch("baserow_enterprise.assistant.assistant._get_workspace_license_type") + def test_assistant_initializes_license_tier( + self, mock__get_workspace_license_type, enterprise_data_fixture + ): + user = enterprise_data_fixture.create_user() + workspace = enterprise_data_fixture.create_workspace(user=user) + chat = AssistantChat.objects.create( + user=user, workspace=workspace, title="Test Chat" + ) + license_type = MagicMock(type="premium", features=["premium"]) + mock__get_workspace_license_type.return_value = license_type + + assistant = Assistant(chat) + + mock__get_workspace_license_type.assert_called_once_with(user, workspace) + assert assistant._deps.license_tier is license_type + + def test_dynamic_license_tier_injects_type_and_features(self): + ctx = MagicMock() + ctx.deps.license_tier = MagicMock(type="advanced", features=["sso", "rbac"]) + + assert dynamic_license_tier(ctx) == ( + "\nadvanced\nrbac,sso" + ) + + def test_dynamic_license_tier_normalizes_internal_enterprise_type(self): + ctx = MagicMock() + ctx.deps.license_tier = MagicMock( + type="enterprise_without_support", features=["sso", "rbac"] + ) + + assert dynamic_license_tier(ctx) == ( + "\nenterprise\nrbac,sso" + ) + + def test_dynamic_license_tier_renders_free_for_unknown_type(self): + ctx = MagicMock() + ctx.deps.license_tier = MagicMock(type="unknown", features=["sso", "rbac"]) + + assert dynamic_license_tier(ctx) == ( + "\nfree\nrbac,sso" + ) + + def test_dynamic_license_tier_renders_free_when_no_license(self): + ctx = MagicMock() + ctx.deps.license_tier = None + + assert dynamic_license_tier(ctx) == "\nfree" + + def test_agent_system_prompt_includes_grounding_guardrail(self): + assert "Use `search_user_docs` first" in AGENT_SYSTEM_PROMPT + assert "Never invent plan names" in AGENT_SYSTEM_PROMPT + + +@pytest.mark.django_db +class TestGetWorkspaceLicenseType: + _PATCH_PATH = ( + "baserow_enterprise.assistant.assistant.ActiveLicensesDataType.get_user_data" + ) + + def _call(self, data, workspace_id=1): + with patch(self._PATCH_PATH, return_value=data): + return _get_workspace_license_type(MagicMock(), MagicMock(id=workspace_id)) + + def test_returns_none_without_active_licenses(self): + assert self._call({"instance_wide": {}, "per_workspace": {}}) is None + + def test_returns_instance_wide_license(self): + result = self._call({"instance_wide": {"premium": True}, "per_workspace": {}}) + assert result is not None + assert result.type == "premium" + + def test_returns_per_workspace_license(self): + result = self._call( + {"instance_wide": {}, "per_workspace": {42: {"advanced": True}}}, + workspace_id=42, + ) + assert result is not None + assert result.type == "advanced" + + def test_ignores_licenses_from_other_workspaces(self): + assert ( + self._call( + {"instance_wide": {}, "per_workspace": {99: {"advanced": True}}}, + workspace_id=42, + ) + is None + ) + + def test_picks_highest_order_from_combined_set(self): + result = self._call( + { + "instance_wide": {"premium": True}, + "per_workspace": {1: {"advanced": True}}, + } + ) + assert result is not None + # PremiumLicenseType.order=10, AdvancedLicenseType.order=75 + assert result.type == "advanced" + + def test_skips_license_names_not_in_registry(self): + result = self._call( + { + "instance_wide": {"bogus_tier": True, "premium": True}, + "per_workspace": {}, + } + ) + assert result is not None + assert result.type == "premium" + + def test_returns_none_when_only_unknown_names(self): + assert ( + self._call({"instance_wide": {"bogus_tier": True}, "per_workspace": {}}) + is None + ) + + @pytest.mark.django_db class TestAssistantMessagePersistence: """Test that messages are persisted correctly during streaming.""" diff --git a/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant_search_docs_tools.py b/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant_search_docs_tools.py index dcc77492f9..a9d5b9b6fa 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant_search_docs_tools.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/assistant/test_assistant_search_docs_tools.py @@ -1,10 +1,11 @@ import os -from unittest.mock import patch +from unittest.mock import AsyncMock, MagicMock, patch import pytest from baserow_enterprise.assistant.tools.search_user_docs.tools import ( _TOOL_QUERY_RE, + SearchDocsResult, search_user_docs, ) @@ -84,6 +85,52 @@ async def test_search_user_docs_handles_empty_results(data_fixture): assert "Nothing found" in result["answer"] +@pytest.mark.django_db +@pytest.mark.asyncio +async def test_search_user_docs_does_not_add_sources_for_nothing_found_prediction( + data_fixture, +): + user = data_fixture.create_user() + workspace = data_fixture.create_workspace(user=user) + ctx = make_test_ctx(user, workspace) + chunk = MagicMock(content="Some unrelated documentation.") + chunk.source_document = MagicMock(source_url="https://example.com/docs") + + with ( + patch( + "baserow_enterprise.assistant.tools.search_user_docs.tools.KnowledgeBaseHandler" + ) as mock_handler_cls, + patch( + "baserow_enterprise.assistant.tools.search_user_docs.tools.search_docs_agent.run", + new_callable=AsyncMock, + ) as mock_run, + patch( + "baserow_enterprise.assistant.model_profiles.get_model_string", + return_value="test/model", + ), + patch( + "baserow_enterprise.assistant.retrying_model._resolve_model", + return_value=MagicMock(), + ), + ): + mock_handler_cls.return_value.search.return_value = [chunk] + mock_run.return_value = MagicMock( + output=SearchDocsResult( + answer="Nothing found in the documentation.", + reliability=1.0, + sources=["https://example.com/docs"], + ) + ) + + result = await search_user_docs( + ctx, question="Does Baserow support imaginary widgets?", thought="user asks" + ) + + assert result["reliability"] == 0.0 + assert result["sources"] == [] + assert ctx.deps.sources == [] + + @pytest.mark.django_db @pytest.mark.asyncio async def test_search_user_docs_handles_error(data_fixture): From 67c6a0173b0d4c5bb6fc021a00a9c5b5e29c00a7 Mon Sep 17 00:00:00 2001 From: Davide Silvestri <75379892+silvestrid@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:48:44 +0200 Subject: [PATCH 2/3] fix: harden user file media serving (#5270) --- Caddyfile | 56 +++++--- Caddyfile.dev | 4 +- backend/src/baserow/api/user_files/views.py | 3 + backend/src/baserow/config/settings/base.py | 18 ++- .../contrib/builder/api/domains/views.py | 2 + .../src/baserow/core/user_files/exceptions.py | 4 + .../src/baserow/core/user_files/handler.py | 127 ++++++++++++++---- .../api/user_files/test_user_files_views.py | 17 +++ .../api/domains/test_domain_public_views.py | 5 + .../core/user_file/test_user_file_handler.py | 59 +++++++- .../bug/harden_user_file_media_serving.json | 9 ++ deploy/all-in-one/docker-compose.yml | 2 + deploy/apache/no-caddy/sub-domain.conf | 6 +- deploy/nginx/no-caddy/nginx.conf | 12 +- docker-compose.no-caddy.yml | 2 + docker-compose.yml | 3 + .../configuration-files/nginx.conf | 24 ++-- docs/installation/configuration.md | 3 +- docs/installation/install-behind-apache.md | 7 +- docs/installation/install-behind-nginx.md | 12 +- .../install-using-standalone-images.md | 8 +- e2e-tests/fixtures/e2e-db.dump | Bin 965749 -> 1017568 bytes 22 files changed, 309 insertions(+), 74 deletions(-) create mode 100644 changelog/entries/unreleased/bug/harden_user_file_media_serving.json diff --git a/Caddyfile b/Caddyfile index 4667cd8e51..373fcdc901 100644 --- a/Caddyfile +++ b/Caddyfile @@ -6,6 +6,29 @@ {$BASEROW_CADDY_GLOBAL_CONF} } +(baserow_media_files) { + handle_path /media/* { + @downloads { + query dl=* + } + header @downloads Content-Disposition "attachment; filename={query.dl}" + header X-Content-Type-Options "nosniff" + header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" + + # Allow to call head from public url to get size + header { + Access-Control-Allow-Origin {$BASEROW_PUBLIC_URL:http://localhost} + Access-Control-Allow-Methods "GET, HEAD, OPTIONS" + Access-Control-Allow-Headers "*" + Access-Control-Expose-Headers "Content-Length, Content-Type" + } + + file_server { + root {$MEDIA_ROOT:/baserow/media/} + } + } +} + {$BASEROW_CADDY_ADDRESSES} { tls { on_demand @@ -20,30 +43,27 @@ ` } + @is_baserow_media { + path /media/* + expression ` + "{$MEDIA_URL:}".startsWith("http://" + {http.request.host} + "/") || + "{$MEDIA_URL:}".startsWith("https://" + {http.request.host} + "/") || + "{$MEDIA_URL:}".startsWith("http://" + {http.request.host} + ":") || + "{$MEDIA_URL:}".startsWith("https://" + {http.request.host} + ":") + ` + } + + handle @is_baserow_media { + import baserow_media_files + } + handle @is_baserow_tool { @backend_routes path /api/* /ws/* /mcp/* /assistant/* {$BASEROW_CADDY_BACKEND_EXTRA_ROUTES:} handle @backend_routes { reverse_proxy {$PRIVATE_BACKEND_URL:localhost:8000} } - handle_path /media/* { - @downloads { - query dl=* - } - header @downloads Content-disposition "attachment; filename={query.dl}" - - # Allow to call head from public url to get size - header { - Access-Control-Allow-Origin {$BASEROW_PUBLIC_URL:http://localhost} - Access-Control-Allow-Methods "GET, HEAD, OPTIONS" - Access-Control-Allow-Headers "*" - Access-Control-Expose-Headers "Content-Length, Content-Type" - } - - file_server { - root {$MEDIA_ROOT:/baserow/media/} - } - } + import baserow_media_files handle_path /static/* { file_server { diff --git a/Caddyfile.dev b/Caddyfile.dev index a8d9ac84d8..3d342eebea 100644 --- a/Caddyfile.dev +++ b/Caddyfile.dev @@ -9,7 +9,9 @@ @downloads { query dl=* } - header @downloads Content-disposition "attachment; filename={query.dl}" + header @downloads Content-Disposition "attachment; filename={query.dl}" + header X-Content-Type-Options "nosniff" + header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" header { Access-Control-Allow-Origin {$PUBLIC_WEB_FRONTEND_URL:http://localhost:3000} diff --git a/backend/src/baserow/api/user_files/views.py b/backend/src/baserow/api/user_files/views.py index 46a5be76c8..c07d335f4d 100644 --- a/backend/src/baserow/api/user_files/views.py +++ b/backend/src/baserow/api/user_files/views.py @@ -10,6 +10,7 @@ from baserow.api.schemas import get_error_schema from baserow.contrib.database.api.tokens.authentications import TokenAuthentication from baserow.core.user_files.exceptions import ( + ActiveContentBlockedUserFileError, FileSizeTooLargeError, FileURLCouldNotBeReached, InvalidFileStreamError, @@ -49,6 +50,7 @@ class UploadFileView(APIView): { InvalidFileStreamError: ERROR_INVALID_FILE, FileSizeTooLargeError: ERROR_FILE_SIZE_TOO_LARGE, + ActiveContentBlockedUserFileError: ERROR_INVALID_FILE, } ) def post(self, request): @@ -93,6 +95,7 @@ class UploadViaURLView(APIView): FileSizeTooLargeError: ERROR_FILE_SIZE_TOO_LARGE, FileURLCouldNotBeReached: ERROR_FILE_URL_COULD_NOT_BE_REACHED, InvalidFileURLError: ERROR_INVALID_FILE_URL, + ActiveContentBlockedUserFileError: ERROR_INVALID_FILE, } ) @validate_body(UserFileUploadViaURLRequestSerializer) diff --git a/backend/src/baserow/config/settings/base.py b/backend/src/baserow/config/settings/base.py index 9f04b9b4ab..6f8a8c823f 100644 --- a/backend/src/baserow/config/settings/base.py +++ b/backend/src/baserow/config/settings/base.py @@ -611,6 +611,15 @@ Decimal(os.getenv("BASEROW_FILE_UPLOAD_SIZE_LIMIT_MB", 1024 * 1024)) * 1024 * 1024 ) # ~1TB by default +FILE_UPLOAD_ACTIVE_CONTENT_POLICY = os.getenv( + "BASEROW_FILE_UPLOAD_ACTIVE_CONTENT_POLICY", "download" +).lower() +if FILE_UPLOAD_ACTIVE_CONTENT_POLICY not in ("download", "block"): + raise ImproperlyConfigured( + "BASEROW_FILE_UPLOAD_ACTIVE_CONTENT_POLICY must be set to " + "'download' or 'block'." + ) + BASEROW_OPENAI_UPLOADED_FILE_SIZE_LIMIT_MB = int( os.getenv("BASEROW_OPENAI_UPLOADED_FILE_SIZE_LIMIT_MB", 512) ) @@ -778,15 +787,22 @@ def __setitem__(self, key, value): if not BASEROW_EMBEDDED_SHARE_URL: BASEROW_EMBEDDED_SHARE_URL = PUBLIC_WEB_FRONTEND_URL +MEDIA_URL_PATH = "/media/" +MEDIA_URL = os.getenv("MEDIA_URL", urljoin(PUBLIC_BACKEND_URL, MEDIA_URL_PATH)) + PRIVATE_BACKEND_URL = os.getenv("PRIVATE_BACKEND_URL", "http://backend:8000") PUBLIC_BACKEND_HOSTNAME = urlparse(PUBLIC_BACKEND_URL).hostname PUBLIC_WEB_FRONTEND_HOSTNAME = urlparse(PUBLIC_WEB_FRONTEND_URL).hostname BASEROW_EMBEDDED_SHARE_HOSTNAME = urlparse(BASEROW_EMBEDDED_SHARE_URL).hostname +MEDIA_URL_HOSTNAME = urlparse(MEDIA_URL).hostname PRIVATE_BACKEND_HOSTNAME = urlparse(PRIVATE_BACKEND_URL).hostname if PUBLIC_BACKEND_HOSTNAME: ALLOWED_HOSTS.append(PUBLIC_BACKEND_HOSTNAME) +if MEDIA_URL_HOSTNAME: + ALLOWED_HOSTS.append(MEDIA_URL_HOSTNAME) + if PRIVATE_BACKEND_HOSTNAME: ALLOWED_HOSTS.append(PRIVATE_BACKEND_HOSTNAME) @@ -951,8 +967,6 @@ def __setitem__(self, key, value): os.getenv("BASEROW_INITIAL_CREATE_SYNC_TABLE_DATA_LIMIT", 5000) ) -MEDIA_URL_PATH = "/media/" -MEDIA_URL = os.getenv("MEDIA_URL", urljoin(PUBLIC_BACKEND_URL, MEDIA_URL_PATH)) MEDIA_ROOT = os.getenv("MEDIA_ROOT", "/baserow/media") # Indicates the directory where the user files and user thumbnails are stored. diff --git a/backend/src/baserow/contrib/builder/api/domains/views.py b/backend/src/baserow/contrib/builder/api/domains/views.py index 8a0a0b79af..481c5f3a47 100644 --- a/backend/src/baserow/contrib/builder/api/domains/views.py +++ b/backend/src/baserow/contrib/builder/api/domains/views.py @@ -401,6 +401,8 @@ def get(self, request): + settings.EXTRA_PUBLIC_BACKEND_HOSTNAMES + settings.EXTRA_PUBLIC_WEB_FRONTEND_HOSTNAMES ) + if settings.MEDIA_URL_HOSTNAME: + allowed_domain.add(settings.MEDIA_URL_HOSTNAME) if domain_name in allowed_domain: return Response(None, status=200) diff --git a/backend/src/baserow/core/user_files/exceptions.py b/backend/src/baserow/core/user_files/exceptions.py index 3c0cd7d077..b08165ab9b 100644 --- a/backend/src/baserow/core/user_files/exceptions.py +++ b/backend/src/baserow/core/user_files/exceptions.py @@ -15,6 +15,10 @@ def __init__(self, max_size_bytes, *args, **kwargs): super().__init__(*args, **kwargs) +class ActiveContentBlockedUserFileError(Exception): + """Raised when the file upload active content policy blocks a file.""" + + class FileURLCouldNotBeReached(Exception): """ Raised when the provided URL could not be reached or points to an internal diff --git a/backend/src/baserow/core/user_files/handler.py b/backend/src/baserow/core/user_files/handler.py index e214db7481..20b1842983 100644 --- a/backend/src/baserow/core/user_files/handler.py +++ b/backend/src/baserow/core/user_files/handler.py @@ -31,6 +31,7 @@ from baserow.core.utils import random_string, sha256_hash, stream_size, truncate_middle from .exceptions import ( + ActiveContentBlockedUserFileError, FileSizeTooLargeError, FileURLCouldNotBeReached, InvalidFileStreamError, @@ -43,9 +44,66 @@ from PIL import Image MIME_TYPE_UNKNOWN = "application/octet-stream" +ACTIVE_CONTENT_EXTENSIONS = {"html", "htm", "xhtml", "xml", "svg", "svgz"} +ACTIVE_CONTENT_MIME_TYPES = { + "application/xhtml+xml", + "application/xml", + "image/svg+xml", + "text/html", + "text/xml", +} class UserFileHandler: + def _is_active_content_extension(self, extension: str) -> bool: + return extension.lower() in ACTIVE_CONTENT_EXTENSIONS + + def _is_active_content_mime_type(self, mime_type: str) -> bool: + return mime_type.lower() in ACTIVE_CONTENT_MIME_TYPES + + def _resolve_mime_type_and_active_content( + self, file_name: str, extension: str, stream + ) -> tuple[str, bool]: + """ + Resolves the MIME type for an uploaded file and decides whether it should be + treated as active content. + + Both the filename-derived MIME type and the client-supplied `content_type` are + checked independently against the active-content blocklist so that a malicious + client cannot bypass the gate by pairing an innocuous extension with a dangerous + Content-Type header (or vice versa). + + :param file_name: The name of the uploaded file. + :param extension: The file extension of the uploaded file. + :param stream: The file content stream of the uploaded file, which may have a + `content_type` attribute. + :return: A tuple of the resolved MIME type and whether the file is considered + active content. + """ + + guessed_mime_type = mimetypes.guess_type(file_name)[0] + uploaded_mime_type = getattr(stream, "content_type", None) + mime_type = guessed_mime_type or uploaded_mime_type or MIME_TYPE_UNKNOWN + is_active_content = ( + self._is_active_content_extension(extension) + or ( + guessed_mime_type is not None + and self._is_active_content_mime_type(guessed_mime_type) + ) + or ( + uploaded_mime_type is not None + and self._is_active_content_mime_type(uploaded_mime_type) + ) + ) + return mime_type, is_active_content + + def _neutralize_active_content(self, user_file: UserFile) -> UserFile: + user_file.mime_type = MIME_TYPE_UNKNOWN + user_file.is_image = False + user_file.image_width = None + user_file.image_height = None + return user_file + def is_user_file_name(self, user_file_name: str) -> bool: """ Checks if the given name is a user file name. @@ -266,6 +324,15 @@ def upload_user_file(self, user, file_name, stream, storage=None): storage = storage or get_default_storage() stream_hash = sha256_hash(stream) file_name = truncate_middle(file_name, 64) + extension = pathlib.Path(file_name).suffix[1:].lower() + mime_type, is_active_content = self._resolve_mime_type_and_active_content( + file_name, extension, stream + ) + + if is_active_content and settings.FILE_UPLOAD_ACTIVE_CONTENT_POLICY == "block": + raise ActiveContentBlockedUserFileError( + "The provided file type is not allowed." + ) existing_user_file = UserFile.objects.filter( original_name=file_name, @@ -274,14 +341,18 @@ def upload_user_file(self, user, file_name, stream, storage=None): ).first() if existing_user_file: + if is_active_content: + self._neutralize_active_content(existing_user_file) + existing_user_file.save( + update_fields=[ + "mime_type", + "is_image", + "image_width", + "image_height", + ] + ) return existing_user_file - extension = pathlib.Path(file_name).suffix[1:].lower() - mime_type = ( - mimetypes.guess_type(file_name)[0] - or getattr(stream, "content_type", None) - or MIME_TYPE_UNKNOWN - ) unique = self.generate_unique(stream_hash, extension) user_file = UserFile( original_name=file_name, @@ -293,26 +364,30 @@ def upload_user_file(self, user, file_name, stream, storage=None): sha256_hash=stream_hash, ) - image = None - try: - image = Image.open(stream) - user_file.mime_type = f"image/{image.format}".lower() - self.generate_and_save_image_thumbnails( - image, user_file.name, storage=storage - ) - # Skip marking as images if thumbnails cannot be generated (i.e. PSD files). - user_file.is_image = True - user_file.image_width = image.width - user_file.image_height = image.height - except IOError: - pass # Not an image - except Exception as exc: - logger.warning( - f"Failed to generate thumbnails for user file of type {mime_type}: {exc}" - ) - finally: - if image is not None: - del image + if is_active_content: + self._neutralize_active_content(user_file) + else: + image = None + try: + image = Image.open(stream) + user_file.mime_type = f"image/{image.format}".lower() + self.generate_and_save_image_thumbnails( + image, user_file.name, storage=storage + ) + # Skip marking as images if thumbnails cannot be generated (i.e. PSD files). + user_file.is_image = True + user_file.image_width = image.width + user_file.image_height = image.height + except IOError: + pass # Not an image + except Exception as exc: + logger.warning( + f"Failed to generate thumbnails for user file of type " + f"{mime_type}: {exc}" + ) + finally: + if image is not None: + del image user_file.save() diff --git a/backend/tests/baserow/api/user_files/test_user_files_views.py b/backend/tests/baserow/api/user_files/test_user_files_views.py index 2310d92d80..fbf0c7c7c8 100644 --- a/backend/tests/baserow/api/user_files/test_user_files_views.py +++ b/backend/tests/baserow/api/user_files/test_user_files_views.py @@ -4,6 +4,7 @@ from django.core.files.storage import FileSystemStorage from django.core.files.uploadedfile import SimpleUploadedFile from django.shortcuts import reverse +from django.test import override_settings import pytest import responses @@ -19,6 +20,22 @@ from baserow.core.models import UserFile +@pytest.mark.django_db +@override_settings(FILE_UPLOAD_ACTIVE_CONTENT_POLICY="block") +def test_upload_file_active_content_blocked(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + + response = api_client.post( + reverse("api:user_files:upload_file"), + data={"file": SimpleUploadedFile("index.html", b"")}, + format="multipart", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + + assert response.status_code == HTTP_400_BAD_REQUEST + assert response.json()["error"] == "ERROR_INVALID_FILE" + + @pytest.mark.django_db def test_upload_file_with_jwt_auth(api_client, data_fixture, tmpdir): user, token = data_fixture.create_user_and_token( diff --git a/backend/tests/baserow/contrib/builder/api/domains/test_domain_public_views.py b/backend/tests/baserow/contrib/builder/api/domains/test_domain_public_views.py index 63e375f9c7..05ef30024b 100644 --- a/backend/tests/baserow/contrib/builder/api/domains/test_domain_public_views.py +++ b/backend/tests/baserow/contrib/builder/api/domains/test_domain_public_views.py @@ -646,6 +646,7 @@ def test_ask_public_builder_domain_exists(api_client, data_fixture): @override_settings( PUBLIC_BACKEND_HOSTNAME="backend.localhost", PUBLIC_WEB_FRONTEND_HOSTNAME="web-frontend.localhost", + MEDIA_URL_HOSTNAME="media.localhost", ) def test_ask_public_builder_domain_exists_with_public_backend_and_web_frontend_domains( api_client, data_fixture @@ -662,6 +663,10 @@ def test_ask_public_builder_domain_exists_with_public_backend_and_web_frontend_d response = api_client.get(url) assert response.status_code == 200 + url = reverse("api:builder:domains:ask_exists") + "?domain=media.localhost" + response = api_client.get(url) + assert response.status_code == 200 + @pytest.mark.django_db @override_settings( diff --git a/backend/tests/baserow/core/user_file/test_user_file_handler.py b/backend/tests/baserow/core/user_file/test_user_file_handler.py index b4b0a53a89..82e1b8f4b5 100644 --- a/backend/tests/baserow/core/user_file/test_user_file_handler.py +++ b/backend/tests/baserow/core/user_file/test_user_file_handler.py @@ -8,6 +8,8 @@ from django.core.exceptions import SuspiciousFileOperation from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage +from django.core.files.uploadedfile import SimpleUploadedFile +from django.test import override_settings import pytest import responses @@ -18,13 +20,14 @@ from baserow.core.models import UserFile from baserow.core.storage import ExportZipFile from baserow.core.user_files.exceptions import ( + ActiveContentBlockedUserFileError, FileSizeTooLargeError, FileURLCouldNotBeReached, InvalidFileStreamError, InvalidFileURLError, MaximumUniqueTriesError, ) -from baserow.core.user_files.handler import UserFileHandler +from baserow.core.user_files.handler import MIME_TYPE_UNKNOWN, UserFileHandler GENERATED_FILE_NAME_LENGTH = 16 # 12 hexdigest + '.' + ext @@ -286,6 +289,60 @@ def test_upload_user_file_with_unsupported_image_format( assert not file_path.isfile() +@pytest.mark.django_db +@override_settings(FILE_UPLOAD_ACTIVE_CONTENT_POLICY="download") +def test_upload_user_file_active_content_download_policy(data_fixture, tmpdir): + user = data_fixture.create_user() + storage = FileSystemStorage(location=str(tmpdir), base_url="http://localhost") + handler = UserFileHandler() + + user_file = handler.upload_user_file( + user, + "logo.svg", + ContentFile(b''), + storage=storage, + ) + + assert user_file.original_extension == "svg" + assert user_file.mime_type == MIME_TYPE_UNKNOWN + assert user_file.is_image is False + assert user_file.image_width is None + assert user_file.image_height is None + assert tmpdir.join("user_files", user_file.name).isfile() + assert not tmpdir.join("thumbnails", "tiny", user_file.name).isfile() + + +@pytest.mark.django_db +@override_settings(FILE_UPLOAD_ACTIVE_CONTENT_POLICY="block") +@pytest.mark.parametrize( + "file_name", + ["index.html", "index.htm", "page.xhtml", "feed.xml", "logo.svg", "logo.svgz"], +) +def test_upload_user_file_active_content_block_policy(data_fixture, tmpdir, file_name): + user = data_fixture.create_user() + storage = FileSystemStorage(location=str(tmpdir), base_url="http://localhost") + + with pytest.raises(ActiveContentBlockedUserFileError): + UserFileHandler().upload_user_file( + user, file_name, ContentFile(b"active content"), storage=storage + ) + + +@pytest.mark.django_db +@override_settings(FILE_UPLOAD_ACTIVE_CONTENT_POLICY="block") +def test_upload_user_file_active_content_block_policy_uses_mime_type( + data_fixture, tmpdir +): + user = data_fixture.create_user() + storage = FileSystemStorage(location=str(tmpdir), base_url="http://localhost") + file = SimpleUploadedFile( + "active-content.txt", b"", content_type="text/html" + ) + + with pytest.raises(ActiveContentBlockedUserFileError): + UserFileHandler().upload_user_file(user, file.name, file, storage=storage) + + @pytest.mark.django_db @responses.activate def test_upload_user_file_by_url(data_fixture, tmpdir): diff --git a/changelog/entries/unreleased/bug/harden_user_file_media_serving.json b/changelog/entries/unreleased/bug/harden_user_file_media_serving.json new file mode 100644 index 0000000000..575a79b48e --- /dev/null +++ b/changelog/entries/unreleased/bug/harden_user_file_media_serving.json @@ -0,0 +1,9 @@ +{ + "type": "bug", + "message": "Hardened user uploaded media serving and neutralized active-content file uploads by default.", + "issue_origin": "github", + "issue_number": null, + "domain": "core", + "bullet_points": [], + "created_at": "2026-04-28" +} diff --git a/deploy/all-in-one/docker-compose.yml b/deploy/all-in-one/docker-compose.yml index ae520e1dbd..38613a7052 100644 --- a/deploy/all-in-one/docker-compose.yml +++ b/deploy/all-in-one/docker-compose.yml @@ -11,6 +11,8 @@ services: EMAIL_SMTP_HOST: 'mailhog' EMAIL_SMTP_PORT: '1025' BASEROW_PUBLIC_URL: + MEDIA_URL: + BASEROW_FILE_UPLOAD_ACTIVE_CONTENT_POLICY: ports: - "80:80" - "443:443" diff --git a/deploy/apache/no-caddy/sub-domain.conf b/deploy/apache/no-caddy/sub-domain.conf index 1f842d0142..a381413346 100644 --- a/deploy/apache/no-caddy/sub-domain.conf +++ b/deploy/apache/no-caddy/sub-domain.conf @@ -5,11 +5,13 @@ ProxyPreserveHost On # Replace with your sub domain ServerName example.localhost -# Serve user uploaded files and add the Content-Disposition header when the filename -# query param is set. +# Serve user uploaded files with download and sandboxing headers. +RewriteRule ^/media/.* - [E=IS_MEDIA:1] RewriteCond %{QUERY_STRING} (?:^|&)dl=([^&]+) RewriteRule ^/media/.* - [E=FILENAME:%1] Header set "Content-Disposition" "attachment; filename=\"%{FILENAME}e\"" env=FILENAME +Header set "X-Content-Type-Options" "nosniff" env=IS_MEDIA +Header set "Content-Security-Policy" "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" env=IS_MEDIA ProxyPass /media ! Alias /media /baserow/media diff --git a/deploy/nginx/no-caddy/nginx.conf b/deploy/nginx/no-caddy/nginx.conf index e5f4fe6a56..469e91b2a2 100644 --- a/deploy/nginx/no-caddy/nginx.conf +++ b/deploy/nginx/no-caddy/nginx.conf @@ -7,6 +7,12 @@ error_log /dev/stdout info; http { access_log /dev/stdout; client_max_body_size 20m; + + map $arg_dl $baserow_media_content_disposition { + default "attachment; filename=$arg_dl"; + "" ""; + } + server { server_name example.localhost; @@ -22,9 +28,9 @@ http { } location /media/ { - if ($arg_dl) { - add_header Content-disposition "attachment; filename=$arg_dl"; - } + add_header Content-Disposition $baserow_media_content_disposition always; + add_header X-Content-Type-Options "nosniff" always; + add_header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" always; # TODO Change to your media folder location! alias /baserow/media/; } diff --git a/docker-compose.no-caddy.yml b/docker-compose.no-caddy.yml index 88855be98b..43a4e00281 100644 --- a/docker-compose.no-caddy.yml +++ b/docker-compose.no-caddy.yml @@ -82,6 +82,7 @@ x-backend-variables: BATCH_ROWS_SIZE_LIMIT: INITIAL_TABLE_DATA_LIMIT: BASEROW_FILE_UPLOAD_SIZE_LIMIT_MB: + BASEROW_FILE_UPLOAD_ACTIVE_CONTENT_POLICY: BASEROW_OPENAI_UPLOADED_FILE_SIZE_LIMIT_MB: BASEROW_UNIQUE_ROW_VALUES_SIZE_LIMIT: @@ -225,6 +226,7 @@ services: - "${HOST_PUBLISH_IP:-127.0.0.1}:3000:3000" environment: BASEROW_PUBLIC_URL: + MEDIA_URL: PRIVATE_BACKEND_URL: ${PRIVATE_BACKEND_URL:-http://backend:8000} PUBLIC_BACKEND_URL: PUBLIC_WEB_FRONTEND_URL: diff --git a/docker-compose.yml b/docker-compose.yml index 4f30b0014e..f6a789787e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -96,6 +96,7 @@ x-backend-variables: BATCH_ROWS_SIZE_LIMIT: INITIAL_TABLE_DATA_LIMIT: BASEROW_FILE_UPLOAD_SIZE_LIMIT_MB: + BASEROW_FILE_UPLOAD_ACTIVE_CONTENT_POLICY: BASEROW_OPENAI_UPLOADED_FILE_SIZE_LIMIT_MB: BASEROW_UNIQUE_ROW_VALUES_SIZE_LIMIT: @@ -273,6 +274,7 @@ services: PRIVATE_WEB_FRONTEND_URL: ${PRIVATE_WEB_FRONTEND_URL:-http://web-frontend:3000} PRIVATE_BACKEND_URL: ${PRIVATE_BACKEND_URL:-http://backend:8000} BASEROW_PUBLIC_URL: ${BASEROW_PUBLIC_URL:-} + MEDIA_URL: ${MEDIA_URL:-} ports: - "${HOST_PUBLISH_IP:-0.0.0.0}:${WEB_FRONTEND_PORT:-80}:80" - "${HOST_PUBLISH_IP:-0.0.0.0}:${WEB_FRONTEND_SSL_PORT:-443}:443" @@ -303,6 +305,7 @@ services: restart: unless-stopped environment: BASEROW_PUBLIC_URL: ${BASEROW_PUBLIC_URL-http://localhost} + MEDIA_URL: BASEROW_EXTRA_PUBLIC_URLS: PRIVATE_BACKEND_URL: ${PRIVATE_BACKEND_URL:-http://backend:8000} PUBLIC_BACKEND_URL: diff --git a/docs/installation/configuration-files/nginx.conf b/docs/installation/configuration-files/nginx.conf index 5ffa15fbd4..9f7ae9e288 100644 --- a/docs/installation/configuration-files/nginx.conf +++ b/docs/installation/configuration-files/nginx.conf @@ -62,6 +62,11 @@ server { } # Media +map $arg_dl $baserow_media_content_disposition { + default "attachment; filename=$arg_dl"; + "" ""; +} + server { listen 80; server_name "*YOUR_MEDIA_DOMAIN*"; @@ -71,24 +76,23 @@ server { gzip_disable "msie6"; location / { - if ($arg_dl) { - add_header Content-disposition "attachment; filename=$arg_dl"; - } + add_header Content-Disposition $baserow_media_content_disposition always; + add_header X-Content-Type-Options "nosniff" always; + add_header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" always; root /baserow/media; } location /user_files { - if ($arg_dl) { - add_header Content-disposition "attachment; filename=$arg_dl"; - } + add_header Content-Disposition $baserow_media_content_disposition always; + add_header X-Content-Type-Options "nosniff" always; + add_header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" always; root /baserow/media; } location /export_files { - if ($arg_dl) { - add_header Content-disposition "attachment; filename=$arg_dl"; - } + add_header Content-Disposition $baserow_media_content_disposition always; + add_header X-Content-Type-Options "nosniff" always; + add_header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" always; root /baserow/media; } } - diff --git a/docs/installation/configuration.md b/docs/installation/configuration.md index 4b96496f12..841e9f066d 100644 --- a/docs/installation/configuration.md +++ b/docs/installation/configuration.md @@ -55,6 +55,7 @@ The installation methods referred to in the variable descriptions are: | INITIAL\_TABLE\_DATA\_LIMIT | The amount of rows that can be imported when creating a table. Defaults to empty which means unlimited rows. | | | BASEROW\_ROW\_PAGE\_SIZE\_LIMIT | The maximum number of rows that can be requested at once. | 200 | | BASEROW\_FILE_UPLOAD\_SIZE\_LIMIT\_MB | The max file size in MB allowed to be uploaded by users into a Baserow File Field. | 1048576 (1 TB or 1024*1024) | +| BASEROW\_FILE\_UPLOAD\_ACTIVE\_CONTENT\_POLICY | Controls how uploads with active-content extensions (`.html`, `.htm`, `.xhtml`, `.xml`, `.svg`, `.svgz`) or MIME types (`text/html`, `text/xml`, `application/xml`, `application/xhtml+xml`, `image/svg+xml`) are handled. Set to `download` to allow them but store them as `application/octet-stream` without image previews. Set to `block` to reject them. | download | | BASEROW\_OPENAI\_UPLOADED\_FILE\_SIZE\_LIMIT\_MB | The max file size in MB allowed to be loaded in RAM and uploaded to OpenAI servers. See also [OpenAI docs](https://platform.openai.com/docs/api-reference/files/create). | 512 | | BATCH\_ROWS\_SIZE\_LIMIT | Controls how many rows can be created, deleted or updated at once using the batch endpoints. | 200 | | BATCH\_ROWS\_SIZE\_LIMIT | Controls how many rows can be created, deleted or updated at once using the batch endpoints. | 200 | @@ -305,7 +306,7 @@ domain than your Baserow, you need to make sure CORS is configured correctly. | Name | Description | Defaults | |----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------| -| MEDIA\_URL | **INTERNAL** The URL at which user uploaded media files will be made available | $PUBLIC\_BACKEND\_URL/media/ | +| MEDIA\_URL | The URL at which user uploaded media files will be made available. Set this to a different origin, for example `https://media.baserow.example.com/media/`, to serve user uploads from an isolated media domain. | $PUBLIC\_BACKEND\_URL/media/ | | MEDIA\_ROOT | **INTERNAL** The folder in which the backend will store user uploaded files | /baserow/media or $DATA_DIR/media for the `baserow/baserow` all-in-one image | | **
** | | | | AWS\_ACCESS\_KEY\_ID | The access key for your AWS account. When set to anything other than empty will switch Baserow to use a S3 compatible bucket for storing user file uploads. | | diff --git a/docs/installation/install-behind-apache.md b/docs/installation/install-behind-apache.md index 645db490ac..0be54723f8 100644 --- a/docs/installation/install-behind-apache.md +++ b/docs/installation/install-behind-apache.md @@ -180,11 +180,13 @@ ProxyPreserveHost On # Replace with your sub domain ServerName example.localhost -# Serve user uploaded files and add the Content-Disposition header when the filename -# query param is set. +# Serve user uploaded files with download and sandboxing headers. +RewriteRule ^/media/.* - [E=IS_MEDIA:1] RewriteCond %{QUERY_STRING} (?:^|&)dl=([^&]+) RewriteRule ^/media/.* - [E=FILENAME:%1] Header set "Content-Disposition" "attachment; filename=\"%{FILENAME}e\"" env=FILENAME +Header set "X-Content-Type-Options" "nosniff" env=IS_MEDIA +Header set "Content-Security-Policy" "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" env=IS_MEDIA ProxyPass /media ! Alias /media /var/www @@ -229,4 +231,3 @@ them (you are getting 403 denied errors when accessing the files) then: your Apache user by running `cd /var/web && chmod 755 *`. * Fix any file permissions found inside the `/var/web` sub-folders to be readable by your Apache user. - diff --git a/docs/installation/install-behind-nginx.md b/docs/installation/install-behind-nginx.md index bd0007996d..7e9de4e937 100644 --- a/docs/installation/install-behind-nginx.md +++ b/docs/installation/install-behind-nginx.md @@ -61,6 +61,11 @@ Create a new `baserow.conf` in `/etc/nginx/sites-available/` with the following > your particular Baserow deployment. ``` +map $arg_dl $baserow_media_content_disposition { + default "attachment; filename=$arg_dl"; + "" ""; +} + server { server_name baserow.example.com; @@ -168,9 +173,9 @@ server { } location /media/ { - if ($arg_dl) { - add_header Content-disposition "attachment; filename=$arg_dl"; - } + add_header Content-Disposition $baserow_media_content_disposition always; + add_header X-Content-Type-Options "nosniff" always; + add_header Content-Security-Policy "sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'" always; # TODO Change to your media folder location! alias /var/www/; } @@ -207,4 +212,3 @@ them (you are getting 403 denied errors when accessing the files) then: your Nginx user by running `cd /var/web && chmod 755 *`. * Fix any file permissions found inside the `/var/web` sub-folders to be readable by your Nginx user. - diff --git a/docs/installation/install-using-standalone-images.md b/docs/installation/install-using-standalone-images.md index a28cd684c2..d82fed2231 100644 --- a/docs/installation/install-using-standalone-images.md +++ b/docs/installation/install-using-standalone-images.md @@ -54,9 +54,11 @@ images: * Redirect `/api/` and `/ws/` requests to the backend gunicorn service without dropping these prefixes. * Serve the files in the `/baserow/media` folder in the backend gunicorn service - (share with your proxy using a volume) at the `/media` endpoint. Ensure - that requests with a `dl` query parameter have a `Content-disposition` header added - with the value of `attachment; filename=THE_DL_QUERY_PARAM_VALUE` + (share with your proxy using a volume) at the `/media` endpoint. Ensure all media + responses have `X-Content-Type-Options: nosniff` and + `Content-Security-Policy: sandbox; default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none'`. + Requests with a `dl` query parameter can use + `Content-Disposition: attachment; filename=THE_DL_QUERY_PARAM_VALUE`. * Send all other requests to the web-frontend service. * You must provide all email related environment variables to both the backend and celery-worker services. This is because the `celery-worker` service is the one diff --git a/e2e-tests/fixtures/e2e-db.dump b/e2e-tests/fixtures/e2e-db.dump index 1af0563b1a9e9c11be9dbaf439bab911fcc01868..5a05f18fc4a94089bb31220bcf7411d6b71fda23 100644 GIT binary patch delta 130892 zcmb4scYIXU5`WIUceBYRA)8GPA=%J7yPK`jf)IL@Dhf$}01-$61Ox?Xb~;xwG$GiK z9$4{G6au0khy(?FN(*2^svW7n@40t(6T*AH-{<%K@MTY(GiT1soH_Ho{B`TGiurAt z^zPK5M{iamND5($1>t|e{6ES3KQ#h>iTtk@7B@-iVsCDYJ;9hR4qZ?^JZ&8*D} zM~xU|wKcIe3Q9#gwetT-z4;++CHAYop(Cg% zrj*U5Wbd!xa}4aNzrqz{kI2 z4Ls={dr(7EPAGUbD|brX#G;8=`2|H;MH6x+j?Nv?FfYF-cU0~K`DS=6_PE?mmt^@L z4GXi1a)yn~&B_~L_VsCMF3dt>`9?^repo@l*xa0aIjTiUkF2_e4w>z{w|gSfV8;Kn zZuvRma?M4#Q;J%ug%ffoP8wTe_H}D%cs#RHm!8#|Ki1mZK&~*v%&45Zr9o}frK7oL zuYTstL0$Ux>uYYPmhrjzW_HhP-_L9{cYLB(4|CzDtl?vGCQdXD?40>Trg=i{Se1&_ zRY_{svjeXflb1ijjOivcP{(Ry?$I{L`T z9F*Cy+FLm$^L!2^z5W<2)4*amyhiBz1nrp?At!Gq1LvkZ|s%^ETW~MZdTov zhM>N((Vg)BzxUbUJ=h8^go4H6-DdlYu^U|MLftNpC8!>k$sA{lcaz;Nu=D4{F65o@f>CeWBG|#xAK1 z-EOBV*bOO)3NP?ltCRYS5|h1I-HeP@eajMccB><(7WF!!Pogh(N_y{> z?yVW!xhWatgM%=H%^TnI2__Hgi@&YjmwI(&^xQ5C_xoooQO@WldGGbk6=+&70fVPo zyf5^PVf5NTK9$W=tVp%INBdbAb^9eaiXK0&7F+3@BE@;z45-bh~MQtv`BLH_8eJ96U!6!AS!izwp>og^J)lv;by2il6ca_K%gI}&$a8W#r~}cgLqY@j@7yW!qLGco{DKh_ z)r!@mnV&K#bmUlQqtQ@Cv?x|crlZ${IC;^yFv|W`UxTbigzmIz9+vBLIf5Egk|yyU zOLo_iBVP=VA<^|C!XWurR-%sA7SK$KKs08O-b8I?2noS%r`r*fS~*6%b_RlU;7-4G zk9W@u67W~hAM*a`wbki^wFYuj7juH|Y&|ovAb*&-LuSWz{k!)wH+X(JEuP2XL$RdX zz#`)1o4LV;yrSF*IYoH|`B_vtm&M7?C!Qc zn_o1sI={AYeiiSLqT~NZ2hKlv&4m#8Kf@#BtK&oDh@p{WtY8VUG9B5%t#^X_r~ zy*sV_RF9UEn$zy-oH;I=EvS`BVf_D~koq)bHCZEh+k0`4&|3eq*@YpDGcJ}a{dJ-L zYxY@*A_BdrU2rmkp~+y6$34F7fJk?ju4bo!QIJx6>Wegs-!Kcg?75 zCU~s!rm+oi?5#m{sgKcsQ<4{@9_ZY>YxHcih%TP=pcG!0Ca;=mqye?S;?yxI^2TX4 zDi>6di=>-_b&+!GF`4vZ6ppIhgcTjB_l4PhSk1P0BHs(R9+&0R1R%}7_a)d~4S>dltetIxkI?{uh zQ=bNgBr=cI#q&|Tp%WRCH%v$r>=wH4oCsz5oER;aPH)Tqh?Vb68lshqo17{CGY-vc z^33VA=;m0R)=K^3⋘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 L*Eg;IPqP03?~8;1 delta 110490 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 Date: Tue, 28 Apr 2026 18:39:44 +0200 Subject: [PATCH 3/3] Prepare for 2.2.2 (#5271) --- README.md | 4 +- backend/docker/docker-entrypoint.sh | 2 +- backend/src/baserow/config/settings/base.py | 2 +- backend/src/baserow/version.py | 2 +- backend/uv.lock | 4 +- changelog.md | 16 ++++++++ ...evented_users_from_creating_data_sour.json | 0 ...n_context_and_hallucination_guardrail.json | 0 .../bug/harden_user_file_media_serving.json | 0 ...atasources_refetch_loop_in_page_edito.json | 0 ...ification_when_a_workflow_is_disabled.json | 0 .../feature/allow_custom_client_scripts.json | 2 + ...y_cleanup_to_a_separate_periodic_task.json | 0 changelog/releases.json | 4 ++ deploy/all-in-one/README.md | 40 +++++++++---------- deploy/all-in-one/supervisor/start.sh | 2 +- deploy/cloudron/CloudronManifest.json | 2 +- deploy/cloudron/Dockerfile | 2 +- deploy/helm/baserow/Chart.lock | 20 +++++----- deploy/helm/baserow/Chart.yaml | 20 +++++----- deploy/helm/baserow/README.md | 2 +- .../baserow/charts/baserow-common/Chart.yaml | 4 +- .../baserow/charts/baserow-common/README.md | 2 +- .../baserow/charts/baserow-common/values.yaml | 4 +- deploy/helm/baserow/values.yaml | 2 +- deploy/render/Dockerfile | 2 +- docker-compose.all-in-one.yml | 2 +- docker-compose.no-caddy.yml | 10 ++--- docker-compose.yml | 10 ++--- docs/installation/install-behind-apache.md | 12 +++--- docs/installation/install-behind-nginx.md | 12 +++--- docs/installation/install-on-aws.md | 28 ++++++------- docs/installation/install-on-cloudron.md | 4 +- docs/installation/install-on-digital-ocean.md | 4 +- docs/installation/install-on-ubuntu.md | 4 +- .../install-using-standalone-images.md | 12 +++--- .../install-with-docker-compose.md | 2 +- docs/installation/install-with-docker.md | 38 +++++++++--------- docs/installation/install-with-helm.md | 2 +- docs/installation/install-with-k8s.md | 12 +++--- docs/installation/install-with-traefik.md | 2 +- docs/installation/supported.md | 2 +- docs/plugins/creation.md | 2 +- docs/plugins/installation.md | 26 ++++++------ enterprise/backend/pyproject.toml | 2 +- heroku.Dockerfile | 2 +- premium/backend/pyproject.toml | 2 +- web-frontend/docker/docker-entrypoint.sh | 2 +- web-frontend/package.json | 2 +- 49 files changed, 177 insertions(+), 155 deletions(-) rename changelog/entries/{unreleased => 2.2.2}/bug/5118_resolved_a_bug_which_prevented_users_from_creating_data_sour.json (100%) rename changelog/entries/{unreleased => 2.2.2}/bug/5210_kuma_plan_context_and_hallucination_guardrail.json (100%) rename changelog/entries/{unreleased => 2.2.2}/bug/harden_user_file_media_serving.json (100%) rename changelog/entries/{unreleased => 2.2.2}/bug/stop_infinite_dispatchdatasources_refetch_loop_in_page_edito.json (100%) rename changelog/entries/{unreleased => 2.2.2}/feature/5186_send_notification_when_a_workflow_is_disabled.json (100%) rename changelog/entries/{unreleased => 2.2.2}/feature/allow_custom_client_scripts.json (79%) rename changelog/entries/{unreleased => 2.2.2}/refactor/move_automation_history_cleanup_to_a_separate_periodic_task.json (100%) diff --git a/README.md b/README.md index 8bb34b7957..c30b3f7024 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ existing tools and performs at any scale. [![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy/?template=https://github.com/baserow/baserow/tree/master) ```bash -docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.2.1 +docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.2.2 ``` ![Baserow database screenshot](docs/assets/screenshot.png "Baserow database screenshot") @@ -108,7 +108,7 @@ Created by Baserow B.V. - bram@baserow.io. Distributes under the MIT license. See `LICENSE` for more information. -Version: 2.2.1 +Version: 2.2.2 The official repository can be found at https://github.com/baserow/baserow. diff --git a/backend/docker/docker-entrypoint.sh b/backend/docker/docker-entrypoint.sh index 6c8d6d780b..e359a4bf72 100755 --- a/backend/docker/docker-entrypoint.sh +++ b/backend/docker/docker-entrypoint.sh @@ -6,7 +6,7 @@ set -euo pipefail # ENVIRONMENT VARIABLES USED DIRECTLY BY THIS ENTRYPOINT # ====================================================== -export BASEROW_VERSION="2.2.1" +export BASEROW_VERSION="2.2.2" # Used by docker-entrypoint.sh to start the dev server # If not configured you'll receive this: CommandError: "0.0.0.0:" is not a valid port number or address:port pair. diff --git a/backend/src/baserow/config/settings/base.py b/backend/src/baserow/config/settings/base.py index 6f8a8c823f..64356a0632 100644 --- a/backend/src/baserow/config/settings/base.py +++ b/backend/src/baserow/config/settings/base.py @@ -494,7 +494,7 @@ "name": "MIT", "url": "https://github.com/baserow/baserow/blob/develop/LICENSE", }, - "VERSION": "2.2.1", + "VERSION": "2.2.2", "SERVE_INCLUDE_SCHEMA": False, "TAGS": [ {"name": "Settings"}, diff --git a/backend/src/baserow/version.py b/backend/src/baserow/version.py index 3f755ed209..4c337c2066 100644 --- a/backend/src/baserow/version.py +++ b/backend/src/baserow/version.py @@ -1 +1 @@ -VERSION = "2.2.1" +VERSION = "2.2.2" diff --git a/backend/uv.lock b/backend/uv.lock index 1787aade05..b9c2dd6eaa 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -461,12 +461,12 @@ dev = [ [[package]] name = "baserow-enterprise" -version = "2.2.1" +version = "2.2.2" source = { editable = "../enterprise/backend" } [[package]] name = "baserow-premium" -version = "2.2.1" +version = "2.2.2" source = { editable = "../premium/backend" } [[package]] diff --git a/changelog.md b/changelog.md index e82983e18c..6b08d84eda 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,21 @@ # Changelog +## Released 2.2.2 + +### New features +* [Automation] Send notification when a workflow is disabled [#5186](https://github.com/baserow/baserow/issues/5186) +* [Core] Allow self-hosted operators to inject custom client-side scripts via environment variables. + +### Bug fixes +* [Builder] Resolved a bug which prevented users from creating data sources from the data source dropdown's footer. [#5118](https://github.com/baserow/baserow/issues/5118) +* [Core] Give Kuma the current license tier in its context and steer uncertain feature or plan questions to docs search. [#5210](https://github.com/baserow/baserow/issues/5210) +* [Core] Hardened user uploaded media serving and neutralized active-content file uploads by default. +* [Builder] stop infinite `/dispatch-data-sources/` refetch loop in page editor + +### Refactors +* [Automation] Optimize Automation History clean-up by moving it to a separate periodic task. + + ## Released 2.2.1 ### New features diff --git a/changelog/entries/unreleased/bug/5118_resolved_a_bug_which_prevented_users_from_creating_data_sour.json b/changelog/entries/2.2.2/bug/5118_resolved_a_bug_which_prevented_users_from_creating_data_sour.json similarity index 100% rename from changelog/entries/unreleased/bug/5118_resolved_a_bug_which_prevented_users_from_creating_data_sour.json rename to changelog/entries/2.2.2/bug/5118_resolved_a_bug_which_prevented_users_from_creating_data_sour.json diff --git a/changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json b/changelog/entries/2.2.2/bug/5210_kuma_plan_context_and_hallucination_guardrail.json similarity index 100% rename from changelog/entries/unreleased/bug/5210_kuma_plan_context_and_hallucination_guardrail.json rename to changelog/entries/2.2.2/bug/5210_kuma_plan_context_and_hallucination_guardrail.json diff --git a/changelog/entries/unreleased/bug/harden_user_file_media_serving.json b/changelog/entries/2.2.2/bug/harden_user_file_media_serving.json similarity index 100% rename from changelog/entries/unreleased/bug/harden_user_file_media_serving.json rename to changelog/entries/2.2.2/bug/harden_user_file_media_serving.json diff --git a/changelog/entries/unreleased/bug/stop_infinite_dispatchdatasources_refetch_loop_in_page_edito.json b/changelog/entries/2.2.2/bug/stop_infinite_dispatchdatasources_refetch_loop_in_page_edito.json similarity index 100% rename from changelog/entries/unreleased/bug/stop_infinite_dispatchdatasources_refetch_loop_in_page_edito.json rename to changelog/entries/2.2.2/bug/stop_infinite_dispatchdatasources_refetch_loop_in_page_edito.json diff --git a/changelog/entries/unreleased/feature/5186_send_notification_when_a_workflow_is_disabled.json b/changelog/entries/2.2.2/feature/5186_send_notification_when_a_workflow_is_disabled.json similarity index 100% rename from changelog/entries/unreleased/feature/5186_send_notification_when_a_workflow_is_disabled.json rename to changelog/entries/2.2.2/feature/5186_send_notification_when_a_workflow_is_disabled.json diff --git a/changelog/entries/unreleased/feature/allow_custom_client_scripts.json b/changelog/entries/2.2.2/feature/allow_custom_client_scripts.json similarity index 79% rename from changelog/entries/unreleased/feature/allow_custom_client_scripts.json rename to changelog/entries/2.2.2/feature/allow_custom_client_scripts.json index cf4c299d26..029b21fc1e 100644 --- a/changelog/entries/unreleased/feature/allow_custom_client_scripts.json +++ b/changelog/entries/2.2.2/feature/allow_custom_client_scripts.json @@ -1,6 +1,8 @@ { "type": "feature", "message": "Allow self-hosted operators to inject custom client-side scripts via environment variables.", + "issue_origin": "github", + "issue_number": null, "domain": "core", "bullet_points": [], "created_at": "2026-04-21" diff --git a/changelog/entries/unreleased/refactor/move_automation_history_cleanup_to_a_separate_periodic_task.json b/changelog/entries/2.2.2/refactor/move_automation_history_cleanup_to_a_separate_periodic_task.json similarity index 100% rename from changelog/entries/unreleased/refactor/move_automation_history_cleanup_to_a_separate_periodic_task.json rename to changelog/entries/2.2.2/refactor/move_automation_history_cleanup_to_a_separate_periodic_task.json diff --git a/changelog/releases.json b/changelog/releases.json index 0f84b2c957..bfb3313bf1 100644 --- a/changelog/releases.json +++ b/changelog/releases.json @@ -1,5 +1,9 @@ { "releases": [ + { + "name": "2.2.2", + "created_at": "2026-04-28" + }, { "name": "2.2.1", "created_at": "2026-04-22" diff --git a/deploy/all-in-one/README.md b/deploy/all-in-one/README.md index 4f4df51e3d..c672ee9ec8 100644 --- a/deploy/all-in-one/README.md +++ b/deploy/all-in-one/README.md @@ -15,7 +15,7 @@ tool gives you the powers of a developer without leaving your browser. [Vue.js](https://vuejs.org/) and [PostgreSQL](https://www.postgresql.org/). ```bash -docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.2.1 +docker run -v baserow_data:/baserow/data -p 80:80 -p 443:443 baserow/baserow:2.2.2 ``` ## Quick Reference @@ -52,7 +52,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` * Change `BASEROW_PUBLIC_URL` to `https://YOUR_DOMAIN` or `http://YOUR_IP` to enable @@ -75,7 +75,7 @@ docker run \ ## Image Feature Overview -The `baserow/baserow:2.2.1` image by default runs all of Baserow's various services in +The `baserow/baserow:2.2.2` image by default runs all of Baserow's various services in a single container for maximum ease of use. > This image is designed for simple single server deployments or simple container @@ -223,7 +223,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Behind a reverse proxy already handling ssl @@ -236,7 +236,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### On a nonstandard HTTP port @@ -249,7 +249,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 3001:80 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external PostgresSQL server @@ -268,7 +268,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external Redis server @@ -289,7 +289,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external email server @@ -309,7 +309,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With a Postgresql server running on the same host as the Baserow docker container @@ -347,7 +347,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ -p 443:443 \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Supply secrets using files @@ -374,7 +374,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ -p 443:443 \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Start just the embedded database @@ -387,7 +387,7 @@ docker run -it \ --name baserow \ -p 5432:5432 \ -v baserow_data:/baserow/data \ - baserow/baserow:2.2.1 \ + baserow/baserow:2.2.2 \ start-only-db # Now get the password from docker exec -it baserow cat /baserow/data/.pgpass @@ -419,7 +419,7 @@ docker run -it \ --rm \ --name baserow \ -v baserow_data:/baserow/data \ - baserow/baserow:2.2.1 \ + baserow/baserow:2.2.2 \ backend-cmd-with-db manage dbshell ``` @@ -542,19 +542,19 @@ the command below. ```bash # First read the help message for this command -docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.1 \ +docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.2 \ backend-cmd-with-db backup --help # Stop Baserow instance docker stop baserow # The command below backs up Baserow to the backups folder in the baserow_data volume: -docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.1 \ +docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.2 \ backend-cmd-with-db backup -f /baserow/data/backups/backup.tar.gz # Or backup to a file on your host instead run something like: docker run -it --rm -v baserow_data:/baserow/data -v $PWD:/baserow/host \ - baserow/baserow:2.2.1 backend-cmd-with-db backup -f /baserow/host/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db backup -f /baserow/host/backup.tar.gz ``` ### Restore only Baserow's Postgres Database @@ -570,13 +570,13 @@ docker stop baserow docker run -it --rm \ -v old_baserow_data_volume_containing_the_backup_tar_gz:/baserow/old_data \ -v new_baserow_data_volume_to_restore_into:/baserow/data \ - baserow/baserow:2.2.1 backend-cmd-with-db restore -f /baserow/old_data/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db restore -f /baserow/old_data/backup.tar.gz # Or to restore from a file on your host instead run something like: docker run -it --rm \ -v baserow_data:/baserow/data -v \ $(pwd):/baserow/host \ - baserow/baserow:2.2.1 backend-cmd-with-db restore -f /baserow/host/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db restore -f /baserow/host/backup.tar.gz ``` ## Running healthchecks on Baserow @@ -627,7 +627,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` Or you can just store it directly in the volume at `baserow_data/env` meaning it will be @@ -636,7 +636,7 @@ loaded whenever you mount in this data volume. ### Building your own image from Baserow ```dockerfile -FROM baserow/baserow:2.2.1 +FROM baserow/baserow:2.2.2 # Any .sh files found in /baserow/supervisor/env/ will be sourced and loaded at startup # useful for storing your own environment variable overrides. diff --git a/deploy/all-in-one/supervisor/start.sh b/deploy/all-in-one/supervisor/start.sh index 2f9645f871..94a6623e74 100755 --- a/deploy/all-in-one/supervisor/start.sh +++ b/deploy/all-in-one/supervisor/start.sh @@ -14,7 +14,7 @@ cat << EOF ██████╔╝██║ ██║███████║███████╗██║ ██║╚██████╔╝╚███╔███╔╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══╝╚══╝ -Version 2.2.1 +Version 2.2.2 ========================================================================================= EOF diff --git a/deploy/cloudron/CloudronManifest.json b/deploy/cloudron/CloudronManifest.json index 5ffb1dfdc1..df5237f36a 100644 --- a/deploy/cloudron/CloudronManifest.json +++ b/deploy/cloudron/CloudronManifest.json @@ -8,7 +8,7 @@ "contactEmail": "bram@baserow.io", "icon": "file://logo.png", "tags": ["no-code", "nocode", "database", "data", "collaborate", "airtable"], - "version": "2.2.1", + "version": "2.2.2", "healthCheckPath": "/api/_health/", "httpPort": 80, "addons": { diff --git a/deploy/cloudron/Dockerfile b/deploy/cloudron/Dockerfile index d664583e2c..abcc9fcdb4 100644 --- a/deploy/cloudron/Dockerfile +++ b/deploy/cloudron/Dockerfile @@ -1,4 +1,4 @@ -ARG FROM_IMAGE=baserow/baserow:2.2.1 +ARG FROM_IMAGE=baserow/baserow:2.2.2 # This is pinned as version pinning is done by the CI setting FROM_IMAGE. # hadolint ignore=DL3006 FROM $FROM_IMAGE AS image_base diff --git a/deploy/helm/baserow/Chart.lock b/deploy/helm/baserow/Chart.lock index 33fb420ae3..cca5b2a8b1 100644 --- a/deploy/helm/baserow/Chart.lock +++ b/deploy/helm/baserow/Chart.lock @@ -1,28 +1,28 @@ dependencies: - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: baserow repository: file://charts/baserow-common - version: 1.0.51 + version: 1.0.52 - name: redis repository: https://charts.bitnami.com/bitnami version: 19.5.5 @@ -35,5 +35,5 @@ dependencies: - name: caddy-ingress-controller repository: https://caddyserver.github.io/ingress version: 1.1.0 -digest: sha256:85683908e75597f5f0b821a562461fceca2f05308b7ef683d28d401f60373b44 -generated: "2026-04-22T20:47:28.551027+02:00" +digest: sha256:f76cc703ae9597738bde9b67ff4db4455ef1a7f9edf2cb53d20fb4e978f66ada +generated: "2026-04-28T18:12:51.830902+02:00" diff --git a/deploy/helm/baserow/Chart.yaml b/deploy/helm/baserow/Chart.yaml index 9ad388b07a..eee7be4e97 100644 --- a/deploy/helm/baserow/Chart.yaml +++ b/deploy/helm/baserow/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: baserow description: The open platform to create scalable databases and applications—without coding. type: application -version: 1.0.51 -appVersion: "2.2.1" +version: 1.0.52 +appVersion: "2.2.2" home: https://github.com/baserow/baserow/blob/develop/deploy/helm/baserow?ref_type=heads icon: https://baserow.io/img/favicon_192.png sources: @@ -13,43 +13,43 @@ sources: dependencies: - name: baserow alias: baserow-backend-asgi - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-backend-wsgi - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-frontend - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-celery-beat-worker - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-celery-export-worker - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-celery-worker - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" - name: baserow alias: baserow-celery-flower - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" condition: baserow-celery-flower.enabled - name: baserow alias: baserow-embeddings - version: "1.0.51" + version: "1.0.52" repository: "file://charts/baserow-common" condition: baserow-embeddings.enabled diff --git a/deploy/helm/baserow/README.md b/deploy/helm/baserow/README.md index d2862749c4..fe7be8d44f 100644 --- a/deploy/helm/baserow/README.md +++ b/deploy/helm/baserow/README.md @@ -232,7 +232,7 @@ caddy: | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- | ----------------------- | | `global.baserow.imageRegistry` | Global Docker image registry | `baserow` | | `global.baserow.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | -| `global.baserow.image.tag` | Global Docker image tag | `2.2.1` | +| `global.baserow.image.tag` | Global Docker image tag | `2.2.2` | | `global.baserow.serviceAccount.shared` | Set to true to share the service account between all application components. | `true` | | `global.baserow.serviceAccount.create` | Set to true to create a service account to share between all application components. | `true` | | `global.baserow.serviceAccount.name` | Configure a name for service account to share between all application components. | `baserow` | diff --git a/deploy/helm/baserow/charts/baserow-common/Chart.yaml b/deploy/helm/baserow/charts/baserow-common/Chart.yaml index 0139cc2c30..711b886fef 100644 --- a/deploy/helm/baserow/charts/baserow-common/Chart.yaml +++ b/deploy/helm/baserow/charts/baserow-common/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.0.51 +version: 1.0.52 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "2.2.1" +appVersion: "2.2.2" diff --git a/deploy/helm/baserow/charts/baserow-common/README.md b/deploy/helm/baserow/charts/baserow-common/README.md index 959f5944d3..a97d7c21c0 100644 --- a/deploy/helm/baserow/charts/baserow-common/README.md +++ b/deploy/helm/baserow/charts/baserow-common/README.md @@ -6,7 +6,7 @@ | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | `global.baserow.imageRegistry` | Global Docker image registry | `baserow` | | `global.baserow.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | -| `global.baserow.image.tag` | Global Docker image tag | `2.2.1` | +| `global.baserow.image.tag` | Global Docker image tag | `2.2.2` | | `global.baserow.serviceAccount.shared` | Set to true to share the service account between all application components. | `true` | | `global.baserow.serviceAccount.create` | Set to true to create a service account to share between all application components. | `true` | | `global.baserow.serviceAccount.name` | Configure a name for service account to share between all application components. | `baserow` | diff --git a/deploy/helm/baserow/charts/baserow-common/values.yaml b/deploy/helm/baserow/charts/baserow-common/values.yaml index 26835a76bc..284ca07605 100644 --- a/deploy/helm/baserow/charts/baserow-common/values.yaml +++ b/deploy/helm/baserow/charts/baserow-common/values.yaml @@ -38,7 +38,7 @@ global: baserow: imageRegistry: baserow image: - tag: 2.2.1 + tag: 2.2.2 imagePullSecrets: [] serviceAccount: shared: true @@ -83,7 +83,7 @@ global: ## image: repository: baserow/baserow # Docker image repository - tag: 2.2.1 # Docker image tag + tag: 2.2.2 # Docker image tag pullPolicy: IfNotPresent # Image pull policy ## @param workingDir Application container working directory diff --git a/deploy/helm/baserow/values.yaml b/deploy/helm/baserow/values.yaml index eac56cd3a7..731c8da6ec 100644 --- a/deploy/helm/baserow/values.yaml +++ b/deploy/helm/baserow/values.yaml @@ -43,7 +43,7 @@ global: baserow: imageRegistry: baserow image: - tag: 2.2.1 + tag: 2.2.2 imagePullSecrets: [] serviceAccount: shared: true diff --git a/deploy/render/Dockerfile b/deploy/render/Dockerfile index eaff0227b9..58e42af021 100644 --- a/deploy/render/Dockerfile +++ b/deploy/render/Dockerfile @@ -1,4 +1,4 @@ -ARG FROM_IMAGE=baserow/baserow:2.2.1 +ARG FROM_IMAGE=baserow/baserow:2.2.2 # This is pinned as version pinning is done by the CI setting FROM_IMAGE. # hadolint ignore=DL3006 FROM $FROM_IMAGE AS image_base diff --git a/docker-compose.all-in-one.yml b/docker-compose.all-in-one.yml index b80aa0e5fb..de3f6d15e3 100644 --- a/docker-compose.all-in-one.yml +++ b/docker-compose.all-in-one.yml @@ -3,7 +3,7 @@ services: baserow: container_name: baserow - image: baserow/baserow:${BASEROW_VERSION:-2.2.1} + image: baserow/baserow:${BASEROW_VERSION:-2.2.2} environment: BASEROW_PUBLIC_URL: 'http://localhost' ports: diff --git a/docker-compose.no-caddy.yml b/docker-compose.no-caddy.yml index 43a4e00281..ccdfa56767 100644 --- a/docker-compose.no-caddy.yml +++ b/docker-compose.no-caddy.yml @@ -205,7 +205,7 @@ x-backend-variables: services: backend: - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 restart: unless-stopped ports: - "${HOST_PUBLISH_IP:-127.0.0.1}:8000:8000" @@ -220,7 +220,7 @@ services: local: web-frontend: - image: baserow/web-frontend:2.2.1 + image: baserow/web-frontend:2.2.2 restart: unless-stopped ports: - "${HOST_PUBLISH_IP:-127.0.0.1}:3000:3000" @@ -272,7 +272,7 @@ services: local: celery: - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 restart: unless-stopped environment: <<: *backend-variables @@ -293,7 +293,7 @@ services: local: celery-export-worker: - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 restart: unless-stopped command: celery-exportworker environment: @@ -314,7 +314,7 @@ services: local: celery-beat-worker: - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 restart: unless-stopped command: celery-beat environment: diff --git a/docker-compose.yml b/docker-compose.yml index f6a789787e..2236937a4e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -287,7 +287,7 @@ services: local: backend: - image: baserow/backend:${BASEROW_VERSION:-2.2.1} + image: baserow/backend:${BASEROW_VERSION:-2.2.2} restart: unless-stopped environment: @@ -301,7 +301,7 @@ services: local: web-frontend: - image: baserow/web-frontend:${BASEROW_VERSION:-2.2.1} + image: baserow/web-frontend:${BASEROW_VERSION:-2.2.2} restart: unless-stopped environment: BASEROW_PUBLIC_URL: ${BASEROW_PUBLIC_URL-http://localhost} @@ -358,7 +358,7 @@ services: local: celery: - image: baserow/backend:${BASEROW_VERSION:-2.2.1} + image: baserow/backend:${BASEROW_VERSION:-2.2.2} restart: unless-stopped environment: <<: *backend-variables @@ -380,7 +380,7 @@ services: local: celery-export-worker: - image: baserow/backend:${BASEROW_VERSION:-2.2.1} + image: baserow/backend:${BASEROW_VERSION:-2.2.2} restart: unless-stopped command: celery-exportworker environment: @@ -402,7 +402,7 @@ services: local: celery-beat-worker: - image: baserow/backend:${BASEROW_VERSION:-2.2.1} + image: baserow/backend:${BASEROW_VERSION:-2.2.2} restart: unless-stopped command: celery-beat healthcheck: diff --git a/docs/installation/install-behind-apache.md b/docs/installation/install-behind-apache.md index 0be54723f8..1afc283f39 100644 --- a/docs/installation/install-behind-apache.md +++ b/docs/installation/install-behind-apache.md @@ -3,7 +3,7 @@ If you have an [Apache server](https://www.apache.com/) this guide will explain how to configure it to pass requests through to Baserow. -We strongly recommend you use our `baserow/baserow:2.2.1` image or the example +We strongly recommend you use our `baserow/baserow:2.2.2` image or the example `docker-compose.yml` files (excluding the `.no-caddy.yml` variant) provided in our [git repository](https://github.com/baserow/baserow/tree/master/deploy/apache/). @@ -18,8 +18,8 @@ simplifies your life by: > If you do not want to use our embedded Caddy service behind your Apache then > make sure you are using one of the two following deployment methods: > -> * Your own container setup with our single service `baserow/backend:2.2.1` - and `baserow/web-frontend:2.2.1` images. +> * Your own container setup with our single service `baserow/backend:2.2.2` + and `baserow/web-frontend:2.2.2` images. > * Or our `docker-compose.no-caddy.yml` example file in our [git repository](https://github.com/baserow/baserow/tree/master/deploy/apache/). > > Then you should use **Option 2: Without our embedded Caddy** section instead. @@ -32,7 +32,7 @@ simplifies your life by: Follow this option if you are using: -* The all-in-one Baserow image `baserow/baserow:2.2.1` +* The all-in-one Baserow image `baserow/baserow:2.2.2` * Any of the example compose files found in the root of our git repository `docker-compose.yml`/`docker-compose.all-in-one.yml` @@ -115,7 +115,7 @@ You should now be able to access Baserow on you configured subdomain. Follow this option if you are using: -* Our standalone `baserow/backend:2.2.1` and `baserow/web-frontend:2.2.1` images with +* Our standalone `baserow/backend:2.2.2` and `baserow/web-frontend:2.2.2` images with your own container orchestrator. * Or the `docker-compose.no-caddy.yml` example docker compose file in the root of our git repository. @@ -147,7 +147,7 @@ sudo systemctl restart apache2 You need to ensure user uploaded files are accessible in a folder for Apache to serve. In the rest of the guide we will use the example `/var/web` folder for this purpose. -If you are using the `baserow/backend:2.2.1` image then you can do this by adding +If you are using the `baserow/backend:2.2.2` image then you can do this by adding `-v /var/web:/baserow/data/media` to your normal `docker run` command used to launch the Baserow backend. diff --git a/docs/installation/install-behind-nginx.md b/docs/installation/install-behind-nginx.md index 7e9de4e937..1c36a09e2b 100644 --- a/docs/installation/install-behind-nginx.md +++ b/docs/installation/install-behind-nginx.md @@ -3,7 +3,7 @@ If you have an [Nginx server](https://www.nginx.com/) this guide will explain how to configure it to pass requests through to Baserow. -We strongly recommend you use our `baserow/baserow:2.2.1` image or the example +We strongly recommend you use our `baserow/baserow:2.2.2` image or the example `docker-compose.yml` files (excluding the `.no-caddy.yml` variant) provided in our [git repository](https://github.com/baserow/baserow/tree/master/deploy/nginx/). @@ -18,8 +18,8 @@ simplifies your life by: > If you do not want to use our embedded Caddy service behind your Nginx then > make sure you are using one of the two following deployment methods: > -> * Your own container setup with our single service `baserow/backend:2.2.1` - and `baserow/web-frontend:2.2.1` images. +> * Your own container setup with our single service `baserow/backend:2.2.2` + and `baserow/web-frontend:2.2.2` images. > * Or our `docker-compose.no-caddy.yml` example file in our [git repository](https://github.com/baserow/baserow/tree/master/deploy/nginx/). > > Then you should use **Option 2: Without our embedded Caddy** section instead. @@ -32,7 +32,7 @@ simplifies your life by: Follow this option if you are using: -* The all-in-one Baserow image `baserow/baserow:2.2.1` +* The all-in-one Baserow image `baserow/baserow:2.2.2` * Any of the example compose files found in the root of our git repository `docker-compose.yml`/`docker-compose.all-in-one.yml` @@ -112,7 +112,7 @@ You should now be able to access Baserow on you configured subdomain. Follow this option if you are using: -* Our standalone `baserow/backend:2.2.1` and `baserow/web-frontend:2.2.1` images with +* Our standalone `baserow/backend:2.2.2` and `baserow/web-frontend:2.2.2` images with your own container orchestrator. * Or the `docker-compose.no-caddy.yml` example docker compose file in the root of our git repository. @@ -131,7 +131,7 @@ but you might have to run different commands. You need to ensure user uploaded files are accessible in a folder for Nginx to serve. In the rest of the guide we will use the example `/var/web` folder for this purpose. -If you are using the `baserow/backend:2.2.1` image then you can do this by adding +If you are using the `baserow/backend:2.2.2` image then you can do this by adding `-v /var/web:/baserow/data/media` to your normal `docker run` command used to launch the Baserow backend. diff --git a/docs/installation/install-on-aws.md b/docs/installation/install-on-aws.md index cf7103ad82..a027c3d301 100644 --- a/docs/installation/install-on-aws.md +++ b/docs/installation/install-on-aws.md @@ -49,7 +49,7 @@ overview this is what any AWS deployment of Baserow will need: ## Option 1) Deploying the all-in-one image to Fargate/ECS -The `baserow/baserow:2.2.1` image runs all of Baserow’s various services inside the +The `baserow/baserow:2.2.2` image runs all of Baserow’s various services inside the container for ease of use. This image is designed for single server deployments or simple deployments to @@ -67,7 +67,7 @@ Run. * You don't need to worry about configuring and linking together the different services that make up a Baserow deployment. * Configuring load balancers is easier as you can just directly route through all - requests to any horizontally scaled container running `baserow/baserow:2.2.1`. + requests to any horizontally scaled container running `baserow/baserow:2.2.2`. #### Cons @@ -75,7 +75,7 @@ Run. * Potentially higher resource usage overall as each of the all-in-one containers will come with its internal services, so you have less granular control over scaling specific services. - * For example if you deploy 10 `baserow/baserow:2.2.1` containers horizontally you + * For example if you deploy 10 `baserow/baserow:2.2.2` containers horizontally you by default end up with: * 10 web-frontend services * 10 backend services @@ -188,18 +188,18 @@ Generally, the Redis server is not the bottleneck in Baserow deployments as they Now create a target group on port 80 and ALB ready to route traffic to the Baserow containers. -When setting up the health check for the ALB the `baserow/baserow:2.2.1` container +When setting up the health check for the ALB the `baserow/baserow:2.2.2` container ,which you'll be deploying next, choose port `80` and health check URL `/api/_health/`. We recommend a long grace period of 900 seconds to account for first-time migrations being run on the first container's startup. #### 5) Launching Baserow on ECS/Fargate -Now we are ready to spin up our `baserow/baserow:2.2.1` containers. See below for a +Now we are ready to spin up our `baserow/baserow:2.2.2` containers. See below for a full task definition and environment variables. We recommend launching the containers with 2vCPUs and 4 GB of RAM each to start with. In short, you will want to: -1. Select the `baserow/baserow:2.2.1` image. +1. Select the `baserow/baserow:2.2.2` image. 2. Add a port mapping of `80` on TCP as this is where this images HTTP server is listening by default. 3. Mark the container as essential. @@ -244,7 +244,7 @@ container_definitions = < We recommend setting the timeout of each HTTP API request to 60 seconds in the @@ -484,7 +484,7 @@ This service is our HTTP REST API service. When creating the task definition you This service is our Websocket API service and when configuring the task definition you should: -1. Use the `baserow/backend:2.2.1` +1. Use the `baserow/backend:2.2.2` 2. Under docker configuration set `gunicorn` as the Command. 3. We recommend 2vCPUs and 4 GB of RAM per container to start with. 4. Map the container port `8000`/`TCP` @@ -496,7 +496,7 @@ should: This service is our asynchronous high priority task worker queue used for realtime collaboration and sending emails. -1. Use the `baserow/backend:2.2.1` image with `celery-worker` as the image command. +1. Use the `baserow/backend:2.2.2` image with `celery-worker` as the image command. 2. Under docker configuration set `celery-worker` as the Command. 3. No port mappings needed. 4. We recommend 2vCPUs and 4 GB of RAM per container to start with. @@ -509,7 +509,7 @@ This service is our asynchronous slow/low priority task worker queue for batch processes and running potentially slow operations for users like table exports and imports etc. -1. Use the `baserow/backend:2.2.1` image. +1. Use the `baserow/backend:2.2.2` image. 2. Under docker configuration set `celery-exportworker` as the Command. 3. No port mappings needed. 4. We recommend 2vCPUs and 4 GB of RAM per container to start with. @@ -520,7 +520,7 @@ imports etc. This service is our CRON task scheduler that can have multiple replicas deployed. -1. Use the `baserow/backend:2.2.1` image. +1. Use the `baserow/backend:2.2.2` image. 2. Under docker configuration set `celery-beat` as the Command. 3. No port mapping needed. 4. We recommend 1vCPUs and 3 GB of RAM per container to start with. @@ -537,7 +537,7 @@ This service is our CRON task scheduler that can have multiple replicas deployed Finally, this service is used for server side rendering and serving the frontend of Baserow. -1. Use the `baserow/web-frontend:2.2.1` image with no arguments needed. +1. Use the `baserow/web-frontend:2.2.2` image with no arguments needed. 2. Map the container port `3000` 3. We recommend 2vCPUs and 4 GB of RAM per container to start with. 4. Mark the container as essential. diff --git a/docs/installation/install-on-cloudron.md b/docs/installation/install-on-cloudron.md index 43e641c970..c36febb031 100644 --- a/docs/installation/install-on-cloudron.md +++ b/docs/installation/install-on-cloudron.md @@ -46,7 +46,7 @@ $ cd baserow/deploy/cloudron After that you can install the Baserow Cloudron app by executing the following commands. ``` -$ cloudron install -l baserow.{YOUR_DOMAIN} --image baserow/cloudron:2.2.1 +$ cloudron install -l baserow.{YOUR_DOMAIN} --image baserow/cloudron:2.2.2 App is being installed. ... App is installed. @@ -89,7 +89,7 @@ the `baserow/deploy/cloudron` folder, you can upgrade your cloudron baserow serv the latest version by running the following command: ``` -cloudron update --app {YOUR_APP_ID} --image baserow/cloudron:2.2.1 +cloudron update --app {YOUR_APP_ID} --image baserow/cloudron:2.2.2 ``` > Note that you must replace the image with the most recent image of Baserow. The diff --git a/docs/installation/install-on-digital-ocean.md b/docs/installation/install-on-digital-ocean.md index f471a43018..387481eec4 100644 --- a/docs/installation/install-on-digital-ocean.md +++ b/docs/installation/install-on-digital-ocean.md @@ -51,7 +51,7 @@ Navigate to the `Apps` page in the left sidebar of your Digital Ocean dashboard. on `Create App`, select `Docker Hub`, and fill out the following: Repository: `baserow/baserow` -Image tag or digest: `2.2.1` +Image tag or digest: `2.2.2` Click on `Next`, then on the `Edit` button of the `baserow-baserow` web service. Here you must change the HTTP Port to 80, and then click on `Back`. Click on the `Next` @@ -124,7 +124,7 @@ environment. In order to update the Baserow version, you simply need to replace the image tag. Navigate to the `Settings` tag of your created app, click on the `baserow-baserow` component, then click on the `Edit` button next to source, change the `Image tag` into -the desired version (latest is `2.2.1`), and click on save. The app will redeploy +the desired version (latest is `2.2.2`), and click on save. The app will redeploy with the latest version. ## External email server diff --git a/docs/installation/install-on-ubuntu.md b/docs/installation/install-on-ubuntu.md index 6204ccd2eb..09fd1ff8ff 100644 --- a/docs/installation/install-on-ubuntu.md +++ b/docs/installation/install-on-ubuntu.md @@ -34,7 +34,7 @@ docker run -e BASEROW_PUBLIC_URL=http://localhost \ -v baserow_data:/baserow/data \ -p 80:80 \ -p 443:443 \ -baserow/baserow:2.2.1 +baserow/baserow:2.2.2 # Watch the logs for Baserow to come available by running: docker logs baserow ``` @@ -147,7 +147,7 @@ docker run \ -v /baserow/media:/baserow/data/media \ -p 80:80 \ -p 443:443 \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 # Check the logs and wait for Baserow to become available docker logs baserow ``` diff --git a/docs/installation/install-using-standalone-images.md b/docs/installation/install-using-standalone-images.md index d82fed2231..79ab22fc19 100644 --- a/docs/installation/install-using-standalone-images.md +++ b/docs/installation/install-using-standalone-images.md @@ -10,9 +10,9 @@ Baserow consists of a number of services, two of which are built and provided as separate standalone images by us: -* `baserow/backend:2.2.1` which by default starts the Gunicorn Django backend server +* `baserow/backend:2.2.2` which by default starts the Gunicorn Django backend server for Baserow but is also used to start the celery workers and celery beat services. -* `baserow/web-frontend:2.2.1` which is a Nuxt server providing Server Side rendering +* `baserow/web-frontend:2.2.2` which is a Nuxt server providing Server Side rendering for the website. If you want to use your own container orchestration software like Kubernetes then these @@ -27,10 +27,10 @@ in the root of our repository. These are all the services you need to set up to run a Baserow using the standalone images: -* `baserow/backend:2.2.1` (default command is `gunicorn`) -* `baserow/backend:2.2.1` with command `celery-worker` -* `baserow/backend:2.2.1` with command `celery-export-worker` -* `baserow/web-frontend:2.2.1` (default command is `nuxt-prod`) +* `baserow/backend:2.2.2` (default command is `gunicorn`) +* `baserow/backend:2.2.2` with command `celery-worker` +* `baserow/backend:2.2.2` with command `celery-export-worker` +* `baserow/web-frontend:2.2.2` (default command is `nuxt-prod`) * A postgres database * A redis server diff --git a/docs/installation/install-with-docker-compose.md b/docs/installation/install-with-docker-compose.md index 313a9375a4..6699667f4f 100644 --- a/docs/installation/install-with-docker-compose.md +++ b/docs/installation/install-with-docker-compose.md @@ -15,7 +15,7 @@ guide on the specifics of how to work with this image. services: baserow: container_name: baserow - image: baserow/baserow:2.2.1 + image: baserow/baserow:2.2.2 environment: BASEROW_PUBLIC_URL: 'http://localhost' ports: diff --git a/docs/installation/install-with-docker.md b/docs/installation/install-with-docker.md index b82188b158..72d2f8ed64 100644 --- a/docs/installation/install-with-docker.md +++ b/docs/installation/install-with-docker.md @@ -29,7 +29,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` * Change `BASEROW_PUBLIC_URL` to `https://YOUR_DOMAIN` or `http://YOUR_IP` to enable @@ -52,7 +52,7 @@ docker run \ ## Image Feature Overview -The `baserow/baserow:2.2.1` image by default runs all of Baserow's various services in +The `baserow/baserow:2.2.2` image by default runs all of Baserow's various services in a single container for maximum ease of use. > This image is designed for simple single server deployments or simple container @@ -200,7 +200,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Behind a reverse proxy already handling ssl @@ -213,7 +213,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### On a nonstandard HTTP port @@ -226,7 +226,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 3001:80 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external PostgresSQL server @@ -245,7 +245,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external Redis server @@ -266,7 +266,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With an external email server @@ -286,7 +286,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### With a Postgresql server running on the same host as the Baserow docker container @@ -324,7 +324,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ -p 443:443 \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Supply secrets using files @@ -351,7 +351,7 @@ docker run \ -v baserow_data:/baserow/data \ -p 80:80 \ -p 443:443 \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` ### Start just the embedded database @@ -364,7 +364,7 @@ docker run -it \ --name baserow \ -p 5432:5432 \ -v baserow_data:/baserow/data \ - baserow/baserow:2.2.1 \ + baserow/baserow:2.2.2 \ start-only-db # Now get the password from docker exec -it baserow cat /baserow/data/.pgpass @@ -396,7 +396,7 @@ docker run -it \ --rm \ --name baserow \ -v baserow_data:/baserow/data \ - baserow/baserow:2.2.1 \ + baserow/baserow:2.2.2 \ backend-cmd-with-db manage dbshell ``` @@ -519,19 +519,19 @@ the command below. ```bash # First read the help message for this command -docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.1 \ +docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.2 \ backend-cmd-with-db backup --help # Stop Baserow instance docker stop baserow # The command below backs up Baserow to the backups folder in the baserow_data volume: -docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.1 \ +docker run -it --rm -v baserow_data:/baserow/data baserow/baserow:2.2.2 \ backend-cmd-with-db backup -f /baserow/data/backups/backup.tar.gz # Or backup to a file on your host instead run something like: docker run -it --rm -v baserow_data:/baserow/data -v $PWD:/baserow/host \ - baserow/baserow:2.2.1 backend-cmd-with-db backup -f /baserow/host/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db backup -f /baserow/host/backup.tar.gz ``` ### Restore only Baserow's Postgres Database @@ -547,13 +547,13 @@ docker stop baserow docker run -it --rm \ -v old_baserow_data_volume_containing_the_backup_tar_gz:/baserow/old_data \ -v new_baserow_data_volume_to_restore_into:/baserow/data \ - baserow/baserow:2.2.1 backend-cmd-with-db restore -f /baserow/old_data/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db restore -f /baserow/old_data/backup.tar.gz # Or to restore from a file on your host instead run something like: docker run -it --rm \ -v baserow_data:/baserow/data -v \ $(pwd):/baserow/host \ - baserow/baserow:2.2.1 backend-cmd-with-db restore -f /baserow/host/backup.tar.gz + baserow/baserow:2.2.2 backend-cmd-with-db restore -f /baserow/host/backup.tar.gz ``` ## Running healthchecks on Baserow @@ -604,7 +604,7 @@ docker run \ -p 80:80 \ -p 443:443 \ --restart unless-stopped \ - baserow/baserow:2.2.1 + baserow/baserow:2.2.2 ``` Or you can just store it directly in the volume at `baserow_data/env` meaning it will be @@ -613,7 +613,7 @@ loaded whenever you mount in this data volume. ### Building your own image from Baserow ```dockerfile -FROM baserow/baserow:2.2.1 +FROM baserow/baserow:2.2.2 # Any .sh files found in /baserow/supervisor/env/ will be sourced and loaded at startup # useful for storing your own environment variable overrides. diff --git a/docs/installation/install-with-helm.md b/docs/installation/install-with-helm.md index c6a6b0739c..cb9b639fbe 100644 --- a/docs/installation/install-with-helm.md +++ b/docs/installation/install-with-helm.md @@ -133,7 +133,7 @@ You can specify a particular Baserow version by updating your `config.yaml`: ```yaml global: baserow: - image: 2.2.1 + image: 2.2.2 ``` Or specify the chart version directly: diff --git a/docs/installation/install-with-k8s.md b/docs/installation/install-with-k8s.md index 86ea504295..7d9fda6f03 100644 --- a/docs/installation/install-with-k8s.md +++ b/docs/installation/install-with-k8s.md @@ -167,7 +167,7 @@ spec: topologyKey: "kubernetes.io/hostname" containers: - name: backend-asgi - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 workingDir: /baserow args: - "gunicorn" @@ -224,7 +224,7 @@ spec: topologyKey: "kubernetes.io/hostname" containers: - name: backend-wsgi - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 workingDir: /baserow args: - "gunicorn-wsgi" @@ -283,7 +283,7 @@ spec: topologyKey: "kubernetes.io/hostname" containers: - name: backend-worker - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 args: - "celery-worker" imagePullPolicy: Always @@ -300,7 +300,7 @@ spec: - secretRef: name: YOUR_ENV_SECRET_REF - name: backend-export-worker - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 args: - "celery-exportworker" imagePullPolicy: Always @@ -317,7 +317,7 @@ spec: - secretRef: name: YOUR_ENV_SECRET_REF - name: backend-beat-worker - image: baserow/backend:2.2.1 + image: baserow/backend:2.2.2 args: - "celery-beat" imagePullPolicy: Always @@ -358,7 +358,7 @@ spec: topologyKey: "kubernetes.io/hostname" containers: - name: web-frontend - image: baserow/web-frontend:2.2.1 + image: baserow/web-frontend:2.2.2 args: - nuxt ports: diff --git a/docs/installation/install-with-traefik.md b/docs/installation/install-with-traefik.md index 7d36596c47..0e8b27f8cf 100644 --- a/docs/installation/install-with-traefik.md +++ b/docs/installation/install-with-traefik.md @@ -10,7 +10,7 @@ See below for an example docker-compose file that will enable Baserow with Traef ``` services: baserow: - image: baserow/baserow:2.2.1 + image: baserow/baserow:2.2.2 container_name: baserow labels: # Explicitly tell Traefik to expose this container diff --git a/docs/installation/supported.md b/docs/installation/supported.md index aa03b54865..356da34617 100644 --- a/docs/installation/supported.md +++ b/docs/installation/supported.md @@ -8,7 +8,7 @@ Software versions are divided into the following groups: before the release. * `Recommended`: Recommended software for the best experience. -## Baserow 2.2.1 +## Baserow 2.2.2 | Dependency | Supported versions | Tested versions | Recommended versions | diff --git a/docs/plugins/creation.md b/docs/plugins/creation.md index 628c34532c..643ff22be4 100644 --- a/docs/plugins/creation.md +++ b/docs/plugins/creation.md @@ -122,7 +122,7 @@ containing metadata about your plugin. It should have the following JSON structu { "name": "TODO", "version": "TODO", - "supported_baserow_versions": "2.2.1", + "supported_baserow_versions": "2.2.2", "plugin_api_version": "0.0.1-alpha", "description": "TODO", "author": "TODO", diff --git a/docs/plugins/installation.md b/docs/plugins/installation.md index e17c58d831..1dbd9a6da2 100644 --- a/docs/plugins/installation.md +++ b/docs/plugins/installation.md @@ -36,7 +36,7 @@ build your own image based off the Baserow all-in-one image. 4. Next copy the contents shown into your `Dockerfile` ```dockerfile -FROM baserow/baserow:2.2.1 +FROM baserow/baserow:2.2.2 # You can install a plugin found in a git repo: RUN /baserow/plugins/install_plugin.sh \ @@ -70,9 +70,9 @@ RUN /baserow/plugins/install_plugin.sh \ 5. Choose which of the `RUN` commands you'd like to use to install your plugins and delete the rest, replace the example URLs with ones pointing to your plugin. 6. Now build your custom Baserow with the plugin installed by running: - `docker build -t my-customized-baserow:2.2.1 .` + `docker build -t my-customized-baserow:2.2.2 .` 7. Finally, you can run your new customized image just like the normal Baserow image: - `docker run -p 80:80 -v baserow_data:/baserow/data my-customized-baserow:2.2.1` + `docker run -p 80:80 -v baserow_data:/baserow/data my-customized-baserow:2.2.2` ### Installing in an existing Baserow all-in-one container @@ -111,7 +111,7 @@ docker run \ -v baserow_data:/baserow/data \ # ... All your normal launch args go here -e BASEROW_PLUGIN_GIT_REPOS=https://example.com/example/plugin1.git,https://example.com/example/plugin2.git - baserow:2.2.1 + baserow:2.2.2 ``` These variables will only trigger and installation when found on startup of the @@ -120,7 +120,7 @@ container. To uninstall a plugin you must still manually follow the instructions ### Caveats when installing into an existing container If you ever delete the container you've installed plugins into at runtime and re-create -it, the new container is created from the `baserow/baserow:2.2.1` image which does not +it, the new container is created from the `baserow/baserow:2.2.2` image which does not have any plugins installed. However, when a plugin is installed at runtime or build time it is stored in the @@ -135,7 +135,7 @@ scratch. ### Installing into standalone Baserow service images -Baserow also provides `baserow/backend:2.2.1` and `baserow/web-frontend:2.2.1` images +Baserow also provides `baserow/backend:2.2.2` and `baserow/web-frontend:2.2.2` images which only run the respective backend/celery/web-frontend services. These images are used for more advanced self-hosted deployments like a multi-service docker-compose, k8s etc. @@ -145,8 +145,8 @@ used with docker run and a specified command and the plugin env vars shown above example: ``` -docker run --rm baserow/backend:2.2.1 install-plugin ... -docker run -e BASEROW_PLUGIN_GIT_REPOS=https://example.com/example/plugin1.git,https://example.com/example/plugin2.git --rm baserow/backend:2.2.1 +docker run --rm baserow/backend:2.2.2 install-plugin ... +docker run -e BASEROW_PLUGIN_GIT_REPOS=https://example.com/example/plugin1.git,https://example.com/example/plugin2.git --rm baserow/backend:2.2.2 ``` You can use these scripts exactly as you would in the sections above to install a plugin @@ -169,13 +169,13 @@ associated data permanently. [Docker install guide backup section](../installation/install-with-docker.md) for more details on how to do this. 2. Stop your Baserow server first - `docker stop baserow` -3. `docker run --rm -v baserow_data:/baserow/data baserow:2.2.1 uninstall-plugin plugin_name` +3. `docker run --rm -v baserow_data:/baserow/data baserow:2.2.2 uninstall-plugin plugin_name` 4. Now the plugin has uninstalled itself and all associated data has been removed. 5. Edit your custom `Dockerfile` and remove the plugin. -6. Rebuild your image - `docker build -t my-customized-baserow:2.2.1 .` +6. Rebuild your image - `docker build -t my-customized-baserow:2.2.2 .` 7. Remove the old container using the old image - `docker rm baserow` 8. Run your new image with the plugin removed - - `docker run -p 80:80 -v baserow_data:/baserow/data my-customized-baserow:2.2.1` + - `docker run -p 80:80 -v baserow_data:/baserow/data my-customized-baserow:2.2.2` 9. If you fail to do this if you ever recreate the container, your custom image still has the plugin installed and the new container will start up again with the plugin re-installed. @@ -207,7 +207,7 @@ associated data permanently. restart as the environment variable will still contain the old plugin. To do this you must: 1. `docker stop baserow` - 2. `docker run --rm -v baserow_data:/baserow/data baserow:2.2.1 uninstall-plugin plugin_name` + 2. `docker run --rm -v baserow_data:/baserow/data baserow:2.2.2 uninstall-plugin plugin_name` 3. Now the plugin has uninstalled itself and all associated data has been removed. 4. Finally, recreate your Baserow container by using the same `docker run` command you launched it with, just make sure the plugin you uninstalled has been removed @@ -222,7 +222,7 @@ check what plugins are currently installed. docker run \ --rm \ -v baserow_data:/baserow/data \ - baserow:2.2.1 list-plugins + baserow:2.2.2 list-plugins # or on a running container diff --git a/enterprise/backend/pyproject.toml b/enterprise/backend/pyproject.toml index 44edc0c496..abe311da25 100644 --- a/enterprise/backend/pyproject.toml +++ b/enterprise/backend/pyproject.toml @@ -12,7 +12,7 @@ description = """Baserow is an open source no-code database tool and Airtable \ # mixed license license = { file = "../LICENSE" } requires-python = "==3.14.*" -version = "2.2.1" +version = "2.2.2" classifiers = [] [project.urls] diff --git a/heroku.Dockerfile b/heroku.Dockerfile index 6b334692cf..f5d38bff90 100644 --- a/heroku.Dockerfile +++ b/heroku.Dockerfile @@ -1,4 +1,4 @@ -ARG FROM_IMAGE=baserow/baserow:2.2.1 +ARG FROM_IMAGE=baserow/baserow:2.2.2 # This is pinned as version pinning is done by the CI setting FROM_IMAGE. # hadolint ignore=DL3006 FROM $FROM_IMAGE AS image_base diff --git a/premium/backend/pyproject.toml b/premium/backend/pyproject.toml index cb82b2b1f2..30dea3795a 100644 --- a/premium/backend/pyproject.toml +++ b/premium/backend/pyproject.toml @@ -12,7 +12,7 @@ description = """Baserow is an open source no-code database tool and Airtable \ # mixed license license = { file = "../LICENSE" } requires-python = "==3.14.*" -version = "2.2.1" +version = "2.2.2" classifiers = [] [project.urls] diff --git a/web-frontend/docker/docker-entrypoint.sh b/web-frontend/docker/docker-entrypoint.sh index 39eb8e7ec2..b05cba1bd3 100755 --- a/web-frontend/docker/docker-entrypoint.sh +++ b/web-frontend/docker/docker-entrypoint.sh @@ -2,7 +2,7 @@ # Bash strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/ set -euo pipefail -export BASEROW_VERSION="2.2.1" +export BASEROW_VERSION="2.2.2" BASEROW_WEBFRONTEND_PORT="${BASEROW_WEBFRONTEND_PORT:-3000}" show_help() { diff --git a/web-frontend/package.json b/web-frontend/package.json index 2ab87e7551..b8563286a4 100644 --- a/web-frontend/package.json +++ b/web-frontend/package.json @@ -1,6 +1,6 @@ { "name": "baserow", - "version": "2.2.1", + "version": "2.2.2", "private": true, "type": "module", "scripts": {