mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-12 19:50:57 +05:00
Scope Docker WAL guard to SQLite
This commit is contained in:
parent
654f07e579
commit
dccd7fd0a3
@ -423,15 +423,14 @@ class DatabaseConfig(BaseConfigSet):
|
||||
SQLITE_LOCK_RETRY_TIMEOUT: float = Field(default=60.0, alias="ARCHIVEBOX_SQLITE_LOCK_RETRY_TIMEOUT", ge=0)
|
||||
SQLITE_LOCK_RETRY_INTERVAL: float = Field(default=5.0, alias="ARCHIVEBOX_SQLITE_LOCK_RETRY_INTERVAL", gt=0)
|
||||
|
||||
@field_validator("SQLITE_JOURNAL_MODE", mode="after")
|
||||
@classmethod
|
||||
def reject_docker_wal(cls, value: str) -> str:
|
||||
if IN_DOCKER and value.upper() == "WAL":
|
||||
@model_validator(mode="after")
|
||||
def reject_docker_sqlite_wal(self):
|
||||
if IN_DOCKER and self.DATABASE_ENGINE.lower() == "sqlite" and self.SQLITE_JOURNAL_MODE.upper() == "WAL":
|
||||
raise ValueError(
|
||||
"SQLITE_JOURNAL_MODE=WAL is unsafe for Docker collections because host bind mounts cross SQLite "
|
||||
"locking domains; use DELETE (the Docker default) or PostgreSQL",
|
||||
)
|
||||
return value
|
||||
return self
|
||||
|
||||
|
||||
class ArchivingConfig(BaseConfigSet):
|
||||
|
||||
@ -268,6 +268,37 @@ def test_docker_rejects_explicit_wal_override(tmp_path):
|
||||
assert "WAL is unsafe for Docker collections" in result.stderr
|
||||
|
||||
|
||||
def test_docker_postgres_ignores_irrelevant_sqlite_wal_override(tmp_path):
|
||||
"""The Docker SQLite safety invariant must not reject PostgreSQL.
|
||||
|
||||
Operators can switch an existing deployment to PostgreSQL while an old
|
||||
SQLITE_JOURNAL_MODE setting remains in ArchiveBox.conf or the environment.
|
||||
PostgreSQL never consumes that SQLite pragma, so rejecting the otherwise
|
||||
valid configuration would prevent ArchiveBox from starting without making
|
||||
any database safer.
|
||||
"""
|
||||
env = os.environ.copy()
|
||||
env["IN_DOCKER"] = "True"
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-c",
|
||||
(
|
||||
"from archivebox.config.common import DatabaseConfig;"
|
||||
"config=DatabaseConfig(DATABASE_ENGINE='postgres',SQLITE_JOURNAL_MODE='WAL');"
|
||||
"print(config.DATABASE_ENGINE)"
|
||||
),
|
||||
],
|
||||
cwd=tmp_path,
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert result.stdout.strip() == "postgres"
|
||||
|
||||
|
||||
def test_server_shows_usage_info(initialized_archive):
|
||||
"""Test that server command shows usage or starts."""
|
||||
|
||||
|
||||
@ -717,13 +717,13 @@ With the default [`DATABASE_ENGINE`](#database_engine)`=sqlite`, this is the pat
|
||||
|
||||
---
|
||||
#### `SQLITE_JOURNAL_MODE`
|
||||
**Possible Values:** [`WAL`]/`DELETE`/`TRUNCATE`/`PERSIST`/`MEMORY`/`OFF`
|
||||
**Possible Values:** [`WAL` on native installs]/[`DELETE` in Docker]/`TRUNCATE`/`PERSIST`/`MEMORY`/`OFF`
|
||||
SQLite [journal mode](https://www.sqlite.org/pragma.html#pragma_journal_mode), applied via `PRAGMA journal_mode = ...` on every new connection. Settable as `ARCHIVEBOX_SQLITE_JOURNAL_MODE`.
|
||||
|
||||
The default `WAL` (Write-Ahead Logging) lets readers and a single writer operate concurrently without blocking each other — readers see a stable snapshot while a write is in progress, instead of being serialized behind it. This is a substantial win for ArchiveBox, where the web UI, admin, and CLI workers frequently read the index while an extractor is writing.
|
||||
The default is `WAL` (Write-Ahead Logging) on native installs and `DELETE` in Docker. WAL lets readers and a single writer operate concurrently without blocking each other, but its shared-memory locking is unsafe when a Docker bind mount exposes the same live database to host-side SQLite processes. Docker therefore rejects an explicit WAL override for the SQLite backend; use PostgreSQL for safe cross-runtime concurrency.
|
||||
|
||||
> [!WARNING]
|
||||
> Do not change this unless you have a specific reason. `DELETE` and `TRUNCATE` serialize all readers against any writer (much worse concurrency). `MEMORY` and `OFF` disable durable journaling and can corrupt the database on crash or power loss. `WAL` requires the database to live on a real local filesystem — it does not work correctly over network filesystems like NFS or SMB.
|
||||
> Do not change this unless you have a specific reason. `DELETE` and `TRUNCATE` serialize readers against writers. `MEMORY` and `OFF` disable durable journaling and can corrupt the database on crash or power loss. WAL requires one local filesystem and one locking domain; it is unsafe across network filesystems and Docker host bind mounts.
|
||||
|
||||
---
|
||||
#### `SQLITE_MMAP_SIZE`
|
||||
|
||||
Loading…
Reference in New Issue
Block a user