ScreenshotNeo

BlogHow-to

ArchiveBox Docker Volume Permissions Error: How to Fix It

Fix ArchiveBox Docker write errors by checking the mounted path, numeric UID/GID, and filesystem permissions before changing ownership.

By the ScreenshotNeo team4 October 20268 min read

Start by identifying the exact path ArchiveBox cannot write to, then compare the container’s numeric user and group IDs with the permissions granted by the mounted filesystem. Check the resolved Compose configuration and logs before changing ownership. Set PUID and PGID to match the identity allowed to write, or correct the mount or server-side ACL. A read-only mount or a server that denies writes cannot be fixed by changing permissions inside the container.

ArchiveBox’s Docker entrypoint uses root for setup, then runs ArchiveBox and Chrome as a non-root user. It selects the first non-root numeric owner found in the collection; for a new or root-owned collection, it falls back to 911:911. The username shown in the container is not enough to determine whether a host bind mount or NAS share will permit writes: numeric IDs and filesystem policy matter. See the official ArchiveBox troubleshooting guidance and Docker image documentation.

1. Find the failing path and operation

Do not start with a recursive ownership change. A failure writing the SQLite index, creating a snapshot, or accessing runtime files may involve different paths and storage. First capture the resolved mounts and the exact error:

docker compose config
docker compose logs --tail=200 archivebox

In the resolved Compose output, confirm that:

  • The intended host directory or named volume is mounted at the expected in-container path.
  • The mount is not marked read-only, and no override file changes the mount source or options.
  • The failing path from the logs is actually under the mount you are inspecting.

Look for the operation that failed, such as creating a directory, writing a file, deleting a temporary probe, or updating the index. Preserve the exact path and error text; they determine which filesystem and permission checks apply.

2. Compare numeric user and group IDs

ArchiveBox documents PUID and PGID for cases where the host or remote filesystem requires a particular numeric identity. These values must match an identity that the filesystem permits to write. A matching username does not guarantee matching numeric IDs.

Inspect the host-side collection owner and the relevant container configuration. For a local Linux bind mount, for example:

# On the Docker host: inspect the collection directory's numeric owner and mode
stat -c '%u:%g %a %n' /path/to/archivebox-data

Then configure the service to use the numeric IDs that have write access on the host. Replace the example values with the actual permitted IDs:

services:
  archivebox:
    image: archivebox/archivebox:latest
    environment:
      PUID: "1000"
      PGID: "1000"
    volumes:
      - /path/to/archivebox-data:/data

Use the image and mount paths from your deployment rather than copying these illustrative paths blindly. If the collection is new or owned by root, the entrypoint’s documented fallback is 911:911; that fallback is not a universal answer for an existing host directory, NAS, or remote mount.

3. Check mount type and storage policy

Storage arrangement What to check Likely next step
Local bind mount Source path, read-only option, numeric owner, group, mode, and ACL Align PUID/PGID with an identity that has write access, or correct the host directory permissions.
Docker named volume Resolved volume mount and its effective ownership and access Inspect the actual volume used by Compose; do not assume a similarly named host directory is the mounted storage.
NFS, NAS, or other remote mount Server export/share policy, UID/GID mapping, ACL, and read-only status Correct the server-side mapping or ACL and ensure the selected identity is allowed to write.
Rclone/FUSE mount Effective mount owner, group, FUSE options, and Docker host visibility Match the mount’s effective IDs to ArchiveBox’s configured IDs and verify the mount is visible to the Docker daemon.

ArchiveBox’s troubleshooting documentation says: “A read-only mount or NFS export that denies both the selected user and root cannot be repaired from inside the container.” Fix the export, share permissions, or mount mode at the source.

The Docker image guidance documents an Rclone/FUSE pattern using options such as --allow-other, --uid 911, --gid 911, --vfs-cache-mode full, and --vfs-links. Treat these as an example whose IDs must match the effective mount and ArchiveBox configuration, not a universal recipe. Docker Desktop runs its daemon in a VM, so a FUSE mount on the host does not automatically behave like a mount on a Linux Docker host.

4. Keep SQLite and application state on reliable local storage

With SQLite, keep index.sqlite3, configuration, logs, and temporary/runtime files on reliable local storage. The official Docker guidance says that only data/archive/ may be remote; PostgreSQL is the supported exception for the main index. If archive payloads are remote, verify that their server-side ownership and write behavior match the configured numeric identity.

Moving the index to local storage can address a storage-placement problem, but it does not repair a denied write to the archive mount. Treat those as separate paths and diagnose each one from the logs.

5. Apply the narrow fix and retry initialization

After correcting the actual ID mapping, ACL, mount mode, or storage placement, retry using the documented sequence:

docker compose stop archivebox
docker compose config
docker compose logs --tail=200 archivebox
docker compose run --rm archivebox init
docker compose up -d --wait

Review the configuration and logs again if initialization fails. A restart policy may repeat a failure, but it does not cause or fix the underlying permission problem.

The entrypoint checks access and performs create/delete probes on important output paths. It makes a shallow repair attempt on exact collection paths only when checks fail; it does not recursively scan or change data/archive. Avoid running chown -R or chmod -R 777 across a large collection as a diagnostic shortcut. Such changes can take a long time, alter permissions beyond the failing path, and still cannot override a read-only mount or server-side denial.

6. Advanced fallback: remap IDs only when necessary

Historical ArchiveBox troubleshooting material describes using bindfs to remap ownership when the underlying UID/GID cannot be changed; an older example maps ID 33 to 911. This is an environment-dependent fallback, not the first fix for a current installation. Before adopting it, verify the deployed image’s behavior, the host’s mount semantics, and whether the remapped identity is actually allowed by the remote server. Prefer direct ID alignment or correcting the server ACL when possible.

Common errors and fixes

Symptom Likely cause Fix
Permission denied under the collection path Selected container UID/GID does not have write access on the mounted directory. Compare numeric IDs and configure PUID/PGID to an identity the filesystem permits.
Writes fail even after changing container IDs Mount is read-only, server ACL denies writes, or remote UID mapping differs. Check the resolved mount options and correct the server-side export, share, or mapping.
Expected data directory appears empty or changes do not show up Compose mounts a different host source or named volume than expected. Inspect docker compose config and verify the resolved source and destination.
SQLite index or runtime files fail on NAS storage Application state is on remote storage with unsuitable behavior or permissions. Keep SQLite and application state on reliable local storage; use remote storage only for the supported archive path.
Host FUSE mount is unavailable inside the container on Docker Desktop Docker’s daemon runs in a VM and does not necessarily see the host mount as Linux Docker would. Validate how the daemon exposes the mount; use a storage arrangement supported by that Docker environment.
Failure repeats after every restart Restart policy restarts a container whose underlying mount or permissions remain wrong. Stop the service, fix the mount or identity, then run initialization and start it again.

Performance, reliability, and cost considerations

  • Large archives: Recursive ownership changes can traverse many files and alter a broad tree. Diagnose the exact output path and use the narrowest relevant correction.
  • Remote mounts: Ownership display alone may not show the server’s effective policy. Confirm export/share rules and UID/GID mapping on the server.
  • SQLite: Local reliable storage is the recommended placement for the index and application state; remote storage is documented for the archive payload path under the supported layout.
  • Remapping: Tools such as bindfs add a layer to understand and maintain. Use them only where IDs cannot be aligned directly, and validate behavior for the current image and host.

Or skip the browser setup

If you also need website screenshots for archive workflows, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. Its clean-shot flow accepts consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. AI agents can use its MCP tools, including take_screenshot, get_page_info, and capture_pdf.

Example cURL request (see the ScreenshotNeo API documentation for options):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. The MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Every feature is on every plan. Learn more at ScreenshotNeo.

Sign up for 1,000 free screenshots a month, no card required.

FAQ

Does ArchiveBox run as root?

The entrypoint uses root for setup, then runs ArchiveBox and Chrome as a non-root user. The selected numeric owner therefore matters for writes.

Should I set PUID and PGID to 911?

Only if those IDs are permitted to write to the relevant filesystem. ArchiveBox uses 911:911 as a fallback for a new or root-owned collection, but existing host and remote storage may require different IDs.

Can I fix a denied NAS write from inside Docker?

No, not when the mount is read-only or the server denies writes to both the selected user and root. Correct the mount or server policy.

Can I store the whole ArchiveBox data directory on a remote mount?

For SQLite, the guidance is to keep the index and application state local; only data/archive/ may be remote. PostgreSQL is the supported exception for the main index.

Is chmod -R 777 a good quick fix?

No. It broadens access across the tree and does not bypass read-only mounts or server-side restrictions. Identify the failing path and fix its actual ownership or ACL.