xunc · Container session¶
xuns runs inside a Docker container; the host only creates the container, forwards environment variables and wires the output back to your terminal.
git clone https://github.com/MenxLi/xun.git
cd xun
make build-docker # build the frontend first, then docker build -t xun -f docker/Dockerfile .
xunc # sandbox: an ephemeral workspace inside the container
xunc . # bind-mount the current directory as /workspace in the container
xunc --copy . # copy the current directory into /workspace (nothing is written back to the host)
Parameters¶
| Parameter | Form | Default | Description |
|---|---|---|---|
mount |
positional, optional | nothing mounted | host directory bind-mounted as /workspace in the container (resolve() is applied first) |
--copy |
flag | False |
copy that directory into /workspace instead; errors out when mount is not given |
--image |
string | xun |
image to use |
--name |
string | xun-<first 8 chars of md5> |
container name; by default the hash is taken from the mount path (from the image name when nothing is mounted) |
--network |
bridge / host |
bridge |
bridge publishes the --port ports; host shares the host network namespace (on macOS the Docker VM's, so the host browser cannot open the URL) |
--port |
list of strings | 18960 |
ports to publish on the host; accepts comma-separated values or repeated flags; --port "" publishes no ports at all |
--env |
list of strings | empty | comma-separated: NAME=VALUE assigns directly; a token without = acts as a wildcard forwarded from the host |
--exec |
string | see below | command to run inside the container; an empty string uses the image's default CMD |
When --exec is not given: if mount was provided it uses xuns . --host 0.0.0.0 (the positional . is /workspace, so the session workspace is the mount point itself), otherwise xuns '' --host '0.0.0.0' (one temporary workspace per session).
The three shapes of the working directory¶
| Invocation | /workspace in the container |
Where the data goes |
|---|---|---|
xunc |
the empty directory shipped in the image | gone as soon as the container is destroyed |
xunc . |
bind mount (read-write) | lands directly in the host directory, writes are persisted |
xunc --copy . |
a copy | changes inside the container do not go back to the host |
Note that working_dir is set to /workspace whenever mount is given, so the agent inside the container starts in the mount point.
Environment variable forwarding¶
XUN_* and _XUN_* are always forwarded into the container, with no explicit declaration needed. --env adds to that baseline:
xunc . --env "XUN_AUTO_CONFIRM=true,_XUN_DEFAULT_MAX_ITER=384,HTTPS_PROXY"
NAME=VALUE: assign directly- bare
NAMEorMY_*: forwarded from the host environment by fnmatch XUN_HOMEcannot be overridden (it is fixed to/.xunin the image); forcing an assignment prints a warning and is ignored
Copying the xun home¶
When the container is created, the host xun home ($XUN_HOME, or .xun/ inside the host's current directory when it is unset) is copied into the container's /.xun, taking only config.json and extensions/ (HOME_COPY_INCLUDE) — session history and x/ (the xunx user store) are not carried over. That is why the container can still read the same secret placeholders and extensions.
Lifecycle and output¶
The container is created with auto_remove=True, stdin_open, tty and working_dir=/workspace (when mounted). xunc forwards host stdin into the container and echoes container output back to the host; after Ctrl+C the container is force-removed. So the URL you see in the browser is the one printed by xuns inside the container:
Agents are available at the following URLs:
http://0.0.0.0:18960/chat/?session=%2F&token=... (aka http://localhost:18960/chat/?...)
In bridge mode the host port equals the container port (18960 is published by default), so simply copy the localhost:18960 line; with --port "" there is no reachable port, which suits one-off --exec tasks such as how this repository generates its documentation:
xunc . \
--env "XUN_AUTO_CONFIRM=true,_XUN_DEFAULT_MAX_ITER=384" \
--exec "xun --non-interactive '请按照docs/AGENTS.md的要求制作文档'" \
--name "xun-doc" \
--port ""
The repository's Makefile freezes this one-shot pattern into two targets: make doc (build the bilingual documentation from scratch) and make doc-update (refresh it according to the most recent source changes). Both pass only --env "XUN_AUTO_CONFIRM=true" (unlike the example above, which also forwards _XUN_DEFAULT_MAX_ITER); only the --exec prompt differs.
Containers are disposable
xunc removes its container automatically on exit, so the ephemeral workspace inside it and any saved sessions are lost. Use a bind mount (xunc .) to keep data, or switch to the persistent xunx instead.