forked from admin/VolcanicAgenticCore
feat(docker): bind the data volumes to /media/disk1/containers/volcanic_secretary_core
The entrypoint chowns the three mount roots before dropping to app, since Docker creates missing bind directories as root.
This commit is contained in:
@@ -65,7 +65,8 @@ RUN if [ "$INSTALL_PLAYWRIGHT" = "true" ]; then \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# The entrypoint hard-codes uid/gid 1654. Named volumes copy this ownership on first mount.
|
||||
# The entrypoint hard-codes uid/gid 1654. Named volumes copy this ownership on first mount; bind-mounted roots are
|
||||
# chowned by the entrypoint (not recursively), since Docker creates missing host directories as root.
|
||||
RUN test "$(id -u app)" = 1654 && test "$(id -g app)" = 1654 \
|
||||
&& mkdir -p /data/workspaces /data/agent /data/claude /home/app \
|
||||
&& chown -R app:app /data /home/app
|
||||
@@ -85,4 +86,5 @@ ENV Telegram__WorkspaceRoot=/data/workspaces \
|
||||
# No USER: PID 1 (docker-init with compose's init: true) must stay root, or the agent could read every secret from
|
||||
# /proc/1/environ. setpriv drops to app and execs dotnet, so Environment.ProcessPath is the muxer the bridge needs.
|
||||
# An empty bounding set and no_new_privs keep the agent's processes from regaining root through setuid binaries.
|
||||
ENTRYPOINT ["setpriv", "--reuid=1654", "--regid=1654", "--init-groups", "--inh-caps=-all", "--bounding-set=-all", "--no-new-privs", "--", "dotnet", "Volcanic.AgenticCore.Telegram.dll"]
|
||||
# The shell only chowns the mount roots and execs setpriv, so the process tree is unchanged.
|
||||
ENTRYPOINT ["/bin/sh", "-c", "chown 1654:1654 /data/workspaces /data/agent /data/claude; exec setpriv --reuid=1654 --regid=1654 --init-groups --inh-caps=-all --bounding-set=-all --no-new-privs -- dotnet Volcanic.AgenticCore.Telegram.dll"]
|
||||
|
||||
@@ -32,12 +32,8 @@ services:
|
||||
- PLAYWRIGHT_BROWSER=${PLAYWRIGHT_BROWSER:-}
|
||||
- PLAYWRIGHT_EXTRA_ARGS=${PLAYWRIGHT_EXTRA_ARGS:---no-sandbox}
|
||||
- PLAYWRIGHT_COMMAND=${PLAYWRIGHT_COMMAND:-playwright-mcp}
|
||||
# Bind mounts on the host. Docker creates missing directories as root; the entrypoint hands the three roots to app.
|
||||
volumes:
|
||||
- workspaces:/data/workspaces
|
||||
- agent:/data/agent
|
||||
- claude:/data/claude
|
||||
|
||||
volumes:
|
||||
workspaces:
|
||||
agent:
|
||||
claude:
|
||||
- /media/disk1/containers/volcanic_secretary_core/workspaces:/data/workspaces
|
||||
- /media/disk1/containers/volcanic_secretary_core/agent:/data/agent
|
||||
- /media/disk1/containers/volcanic_secretary_core/claude:/data/claude
|
||||
|
||||
@@ -129,15 +129,20 @@ The image sets these; normally leave them alone:
|
||||
|
||||
## Volumes
|
||||
|
||||
The compose file binds them to directories under `/media/disk1/containers/volcanic_secretary_core/` on the host
|
||||
(`workspaces/`, `agent/`, `claude/`); edit the three `volumes:` lines to put them elsewhere.
|
||||
|
||||
| Volume | Path | Contents |
|
||||
|---|---|---|
|
||||
| `workspaces` | `/data/workspaces` | One directory per chat (`/data/workspaces/<chatId>`): `AGENTS.md` or `CLAUDE.md`, `PERSONA.md`, `MEMORY.md`, `inbox/` (received files), `browser/` (screenshots, downloads), project-level `.volcanic/extensions/`, the Google Calendar token (`.volcanic/google-calendar/token.json`) |
|
||||
| `agent` | `/data/agent` | Sessions (`sessions/telegram-<chatId>/`), `settings.json`, `extensions/*.dll`, chat time zones (`telegram/chat-settings.json`), `scheduler/jobs.json` |
|
||||
| `claude` | `/data/claude` | The Claude login (credentials and onboarding state) |
|
||||
|
||||
Named volumes survive redeploys. Coolify prefixes them with the resource's uuid and deletes them only when you delete
|
||||
the resource together with its volumes. Bind mounts work too if the host directories belong to uid 1654
|
||||
(`chown -R 1654:1654 <dir>`).
|
||||
Bind mounts survive redeploys and deleting the resource. Docker creates missing host directories as root; the
|
||||
entrypoint chowns the three mount roots (not their contents) to uid 1654 before it drops to `app`, so files copied in
|
||||
from elsewhere need `chown -R 1654:1654 <dir>` on the host. Named volumes (`-v workspaces:/data/workspaces`, as in
|
||||
the `docker run` example) work too. On an NTFS disk (`fuseblk`, as `/media/disk1` is) ownership and modes aren't
|
||||
stored: everything shows as root with mode 777, `chown` is a silent no-op, and `app` can still write.
|
||||
|
||||
`HOME` (`/home/app`) isn't a volume: `~/.gitconfig`, `~/.ssh`, `gh` logins and the npm cache are lost on redeploy.
|
||||
|
||||
@@ -211,7 +216,7 @@ given under [First run and Claude login](#first-run-and-claude-login)).
|
||||
| `[executable_missing]` in a reply, or `Claude Code (claude) was not found on PATH` at startup | The image has no working `claude`. Rebuild and check that `claude --version` ran in the build log |
|
||||
| `[auth]` in a reply | The Claude login is missing or expired: `/claude-code-login`, or the `docker exec -u app` command above |
|
||||
| `[mcp_startup]` in a reply | The bridge files are missing from `/app`: `Volcanic.AgenticCore.Extensions.ClaudeCode.Bridge.dll` and `Volcanic.AgenticCore.Extensions.ClaudeCode.Bridge.runtimeconfig.json`. The build checks for both, so rebuild from a clean tree |
|
||||
| `Permission denied` under `/data` | Bind-mounted directories owned by another user: `chown -R 1654:1654 <dir>` on the host |
|
||||
| `Permission denied` under `/data` | Files in the bind-mounted directories owned by another user: `chown -R 1654:1654 /media/disk1/containers/volcanic_secretary_core` on the host |
|
||||
| `Telegram reports another poller or a webhook for this bot (409)` | Another instance polls with the same token (an old container, a local `dotnet run`), or the bot has a webhook. Stop the other instance; remove a webhook with `https://api.telegram.org/bot<token>/deleteWebhook` |
|
||||
| `Telegram rejected the bot token (401 Unauthorized)`, restart loop | Wrong or revoked `TELEGRAM_BOT_TOKEN` |
|
||||
| Browser tools missing or failing | The image was built with `INSTALL_PLAYWRIGHT=false`, `PLAYWRIGHT_ENABLED` is off, or `PLAYWRIGHT_EXTRA_ARGS` lost `--no-sandbox`. Chromium crashes also come from a small `/dev/shm`; keep `shm_size: 1gb` |
|
||||
|
||||
Reference in New Issue
Block a user