Share a local folder
Section titled “Share a local folder”hoody share makes a folder on your computer appear inside a container, at /hoody/mounts/permanent/<name>. Programs in the container read and write it like any other directory, and every change lands in the folder on your computer.
It is the reverse of Mount Locally, which puts the container’s files on your computer. Here the files stay on your computer and the container reaches them over the network for as long as the hoody share command runs.
Once the folder is shared, every Hoody surface can use it:
- the files API and the SDK (
box.files.*); - the files web manager;
- the terminal, exec scripts and the agent, as root or through
sudo(see Limits).
Commands summary
Section titled “Commands summary”hoody share <dir> [--name <name>] [--read-only] [--container <id>] [--rclone <path>] [--drain-timeout <s>]hoody share list [--json]hoody share stop <name> [--container <id>] [--force] [--json]| Command | What it does |
|---|---|
hoody share <dir> | Shares <dir> into the container and keeps serving it until you stop it |
hoody share list | Lists the shares started from your account on this computer |
hoody share stop <name> | Stops a share, or cleans up one whose process is gone |
| Option | Meaning |
|---|---|
--name <name> | The folder’s name in the container. Defaults to the base name of <dir> |
--read-only | Refuses every write, in the container and through the share’s URL |
--container <id> | The container to share into. Without it, hoody share <dir> uses the global -c <id>, then HOODY_CONTAINER or your configured default container, and refuses to start when there is none. With stop, it picks which container’s share to stop |
--rclone <path> | The rclone binary to run. Defaults to rclone on your PATH |
--drain-timeout <s> | hoody share <dir> only. How long a stop waits for the container to send its writes to your computer, in whole seconds. Defaults to 300 |
--force | hoody share stop only. Discard the writes the container holds that never reached your computer, instead of waiting for them. See Stop a share |
--json | With list and stop: print the result as JSON |
Requirements
Section titled “Requirements”- rclone v1.61.0 or newer on your computer.
hoody shareruns rclone to serve the folder. Install it from rclone.org, or withbrew install rcloneon macOS,apt install rcloneordnf install rcloneon Linux, orwinget install Rclone.Rcloneon Windows. The CLI runsrclonefrom yourPATH, or the binary you name with--rclone. It checks the version when a share starts and refuses an older one. - The Hoody CLI, signed in to the account that owns the container.
- A container with an up-to-date Hoody Kit. The share uses the container’s files and tunnel kits. The files kit must be recent enough to confirm, when a mount is removed, that everything written in the container has been sent. A share into a container with an older files kit is refused before anything is created, with
the files kit of container <id> is too old for hoody share: its mount DELETE cannot wait for the mount's uploads. Update the container's files kit, then share again.
How it works
Section titled “How it works”rclone serves the folder over WebDAV on your computer’s loopback address. A hoody-tunnel binding publishes that server at an HTTPS address on the container’s own domain, and hoody-files mounts that address at /hoody/mounts/permanent/<name>. Your computer opens the tunnel connection, so it never accepts an inbound connection.
Every share gets its own random user name and password. The CLI generates them when the share starts and never prints them, writes them to disk on your computer, or puts them on a command line. The URL refuses any request that does not carry them. In the container, hoody-files stores the password the same way it stores every other storage backend credential.
The mount uses hoody-files’ normal write cache. A write in the container is saved in the container first and uploaded to your computer a few seconds later. Listings are not cached, so the container always sees the folder as it is on your computer. A write is not checked against changes made on your computer in the meantime; see The last save wins.
Share a folder
Section titled “Share a folder”# Share ./photos into a container as /hoody/mounts/permanent/photoshoody -c "$CONTAINER_ID" share ./photos
hoody -c "$CONTAINER_ID" share ./photos --name pics
# Share without allowing any writeshoody -c "$CONTAINER_ID" share ~/docs --read-only
# The same, with the container named on the command itselfhoody share ./photos --container "$CONTAINER_ID"<dir> must be an existing folder. Once the share is up, the command prints a line ✓ <folder> is shared, then the path under In the container:, the host of the share’s URL under Through:, and the hoody share stop command that stops it. It then stays in the foreground: the folder is shared for as long as the command runs, so keep the terminal open.
list and stop are subcommands, so a folder that is called list or stop is shared by writing its path: hoody share ./list. On Linux and macOS, a folder argument with a colon before its first /, such as notes:2026, is refused because rclone would read it as one of its remotes. Write ./notes:2026 instead.
Name rules
Section titled “Name rules”The name becomes the last part of the mount path, so it follows these rules:
- 1 to 64 characters;
- letters, digits,
.,_and-only; - not
.or.., and not starting with-.
A folder whose base name breaks a rule needs --name. The CLI refuses the name with share name "<name>" is not allowed, states the rule, and ends with an example such as Example: --name my-photos.
A name can be used only once per container. If the container already has a mount at /hoody/mounts/permanent/<name>, the files kit refuses the share’s mount and the error asks whether something is already mounted there; pick another --name. A second hoody share of the same name into the same container, while the first still runs, is refused with "<name>" is already shared to container <id> by a running hoody share.
Use the folder in the container
Section titled “Use the folder in the container”# As rootls /hoody/mounts/permanent/photos
# As the container's normal usersudo ls /hoody/mounts/permanent/photossudo cp report.pdf /hoody/mounts/permanent/photos/import { HoodyClient } from 'hoody-sdk';
const hoody = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });const box = await hoody.withContainer({ id: CONTAINER_ID, project_id: PROJECT_ID, server: SERVER });
// List the shared folderconst listing = await box.files.get('hoody/mounts/permanent/photos/');
// Write a file; it reaches your computer within a few secondsawait box.files.upload('hoody/mounts/permanent/photos/notes.txt', 'written from the container');# List the shared foldercurl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/files/hoody/mounts/permanent/photos/"
# Upload a file into itcurl -X PUT --data-binary @report.pdf \ "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/files/hoody/mounts/permanent/photos/report.pdf"The shared folder is a hoody-files mount like any other, so the mount rules apply. One that matters in practice: a move between the shared folder and the container’s own files fails with FILE_MOVE_CROSSES_DEVICES. Copy the file, then delete the original.
Read and write behaviour
Section titled “Read and write behaviour”Writes reach your computer within seconds
Section titled “Writes reach your computer within seconds”A write in the container is saved in the container first, then uploaded to the folder on your computer, usually within a few seconds after the file’s last open handle closes. A file kept open for writing, such as a log that stays open, can stay unsent until it is closed. A program sees the write succeed as soon as it is saved in the container, the same as on any other hoody-files mount.
Any program works on the shared folder, including ones that change files in place: a SQLite database, an editor, a log that is appended to. Renames work too, and so does writing a temporary file and renaming it over the original.
Changes on your computer
Section titled “Changes on your computer”A file you create or change on your computer is visible in the container at once. The container does not cache the folder’s listing, so there is no delay before a new file appears. File contents are read from your computer, so the speed of the folder in the container depends on the connection between the container and your computer.
While your computer is asleep or offline
Section titled “While your computer is asleep or offline”The folder is usable only while your computer is online and hoody share is running. Otherwise every program in the container gets an I/O error (Input/output error in a shell), shell redirections such as echo hi > file included:
- Reads fail after about 10 seconds.
- Writes fail within about 10 to 20 seconds of your computer no longer answering.
A write that failed is not delivered when your computer comes back, so the program has to write it again. A write that already succeeded in the container may still be waiting in its write cache when your computer goes offline, so success does not mean it has reached your computer. Keep the share running and let its stop wait confirm delivery before closing it.
The mount stays in place, and hoody-files keeps listing it as active. Keep the hoody share command running: it reconnects when your computer is back online, on the same URL, and reads and writes work again. Nothing has to be remounted. To reconnect, the share first tries to resume its previous tunnel session:
- A closed connection. The tunnel notices it at once and keeps the session for about a minute. If your computer is back within that minute, the session resumes and the share is back on the same URL at once.
- A silent drop. When your computer sleeps or loses its network, the tunnel only notices after up to about 2.5 minutes. Until then the old session still counts as active, so a resume is refused and the port stays held; the share keeps retrying. It is back once the tunnel has noticed the drop, and within the minute after that it resumes the session.
- Away for longer. Once the session is gone, the share binds the same container port again as soon as the old binding is released, which gives it the same URL.
If another binding has taken the share’s port and still holds it after five minutes, the share reports a conflict and stops instead of evicting it.
If the files kit or the container restarts while the share runs, the share checks its mount every 30 seconds and tries to restart it with its original settings. If the mount was removed or reports another error, the CLI reports it instead of recreating it.
The last save wins
Section titled “The last save wins”The share does not merge changes. If the same file is changed on your computer and in the container at the same moment, the version saved last replaces the other one. A container write is saved last when it reaches your computer, a few seconds after the program wrote it. This is how any network share behaves: avoid editing the same file on both sides at once.
Read-only shares
Section titled “Read-only shares”--read-only blocks writes on both sides. The container can read the folder but not change anything in it. On your computer, rclone itself refuses writes too, so no other client of the share’s URL can change the folder either.
List shares
Section titled “List shares”hoody share list lists the shares your account on this computer has started and not yet cleaned up, across all containers. It prints one row per share with the columns NAME, STATUS, CONTAINER, PATH (the path in the container) and LOCAL (the folder on your computer). --json prints the same entries as JSON.
| Status | Meaning |
|---|---|
starting, serving, reconnecting, stopping | The hoody share command for this share is running, in that state |
dead | The hoody share command is gone and the share was not cleaned up |
cleanup pending | The share stopped, but something it created in the container could not be removed, or some writes had not reached your computer |
For each dead or cleanup pending share, list also prints the hoody share stop <name> --container <id> command that cleans it up.
Stop a share
Section titled “Stop a share”Any of these stops a share:
Ctrl+Cin the terminal that runshoody share;hoody share stop <name>from another terminal;- rclone exiting on its own.
A stop first waits until every write made in the container has reached your computer. The share keeps serving the folder during the wait, and reconnects if its connection drops. Then it asks hoody-files to remove the mount once the container has sent what it still holds, and hoody-files confirms when everything is delivered. Only after that confirmation does the share remove the storage backend, close the tunnel and stop rclone.
On the first Ctrl+C the CLI prints Stopping: waiting for the container to send its writes here (Ctrl+C again to stop without waiting). While writes are still on their way, it shows their progress, for example waiting for 3 files not yet on this machine, 1 still open in the container (up to 280 s more), then removing the mount once the container has sent what it still holds (up to 270 s). A stop requested with hoody share stop from another terminal waits the same way, and that terminal shows the same progress.
The wait lasts at most --drain-timeout seconds, 300 by default. A second Ctrl+C ends it at once and prints ! stopping without waiting; what the container has not sent yet stays there. If the wait ends without the confirmation, whether through the timeout, a second Ctrl+C or an error:
- the CLI says what the container still holds, for example
! stopping with 3 files not yet on this machine; they stay in the container (`hoody share stop photos --force` discards them), or! the container did not send everything in time: it still holds 3 files not yet on this machine; - those writes stay in the container and are not deleted: the share keeps its storage backend, and keeps the mount too unless the stop had already removed it;
- the tunnel closes and rclone stops, so they are not delivered either;
- the share is reported as
cleanup pending, and the command exits with status 1.
If rclone exits on its own, nothing serves the folder any more, so the stop does not wait: writes the container still holds stay there the same way.
If the share’s mount was removed outside hoody share, for example through the files API, the container can no longer confirm that everything was sent. The stop then keeps the backend and the share ends cleanup pending. A plain hoody share stop <name> refuses to finish it; only hoody share stop <name> --force does, and it discards whatever the container had not sent.
Stop without waiting
Section titled “Stop without waiting”hoody share stop <name> --force stops a running share without waiting: the container discards the writes it has not sent to your computer, a program that still has a file open in the folder gets errors on it, and the share removes the mount and the backend. The terminal that ran stop --force prints ✓ stopped <name> (container <id>) and exits with status 0. The share’s own terminal prints ! stopped by `hoody share stop --force`: what the container had not sent here was discarded and exits with status 1. Use it only when you do not need those writes.
How a stop ended
Section titled “How a stop ended”The last line in the share’s own terminal says how the stop ended:
| Output | Meaning | Exit status |
|---|---|---|
✓ stopped: everything written in the container is on this machine, and <path> is gone from the container | hoody-files confirmed every write arrived, and the mount is removed | 0 |
✗ stopped, but the container never confirmed it had sent everything here: a write made there may not have reached this machine | Nothing of the share is left in the container, but hoody-files never confirmed delivery, for example because the mount and the backend had already been removed some other way | 1 |
! stopped by `hoody share stop --force`: what the container had not sent here was discarded | Another terminal ran stop --force | 1 |
✗ stopped, but cleanup is pending: <what is left> | Something is still in the container: a mount that holds writes not yet on your computer, a backend kept because delivery was not confirmed, or a resource that could not be removed. The next line gives the hoody share stop command that finishes it, to run with --force when finishing it would discard writes the container still holds | 1 |
# Stop the share named photoshoody share stop photos
# The same name is shared into two containers: say which onehoody share stop photos --container "$CONTAINER_ID"stop looks only at an explicit container: --container <id> or the global -c <id>. HOODY_CONTAINER and your configured default container do not narrow it, so a default never hides a share of that name on another container. If shares into more than one container have that name, stop refuses with "<name>" is shared to more than one container; pass --container with one of: followed by one hoody share stop command per container, and exits with status 2. Only your own account on the computer can stop a share; another user on the same computer cannot.
hoody share stop prints ✓ stopped <name> (container <id>) when the stop finished cleanly, and ✗ with the reason otherwise, exiting with status 1. --json prints the result as JSON instead.
hoody share stop can wait several minutes. Pressing Ctrl+C in its terminal ends the wait in that terminal: it prints ! stopped waiting; `hoody share list` shows what is left; run `hoody share stop <name>` again to finish it (it says if --force is needed) and exits with status 130. A running share goes on stopping in its own terminal. For a share that is not running, whatever cleanup is unfinished stays recorded for the next hoody share stop <name>. If the interrupted stop was already removing the mount, the container can no longer confirm that everything was sent, so that next stop refuses and asks for --force (see Clean up after a crash).
If the container cannot be reached while the share stops, the CLI keeps a record of what is left and reports the share as cleanup pending. hoody share list then shows it as cleanup pending, and running hoody share stop <name> again finishes the cleanup.
Clean up after a crash
Section titled “Clean up after a crash”If the hoody share process ends without stopping, for example because it was killed or the computer restarted, the mount and the backend stay in the container. hoody share list shows the share as dead. Run hoody share stop <name>: it stops the rclone process that share left behind, then removes the mount, waiting up to 10 seconds for hoody-files to confirm it holds nothing unsent. The backend is removed only once that is confirmed; otherwise the share stays cleanup pending. If the process ended while a stop was already removing the mount, the container can no longer confirm that everything was sent, and hoody share stop refuses as described below.
A share that is not running cannot deliver through its stopped local server, so writes the container still holds for it cannot reach your computer, and finishing the cleanup with the share command means discarding them. Before you do, you can recover what you need through the pending uploads API: download the held files with GET /api/v1/pending-uploads/{id}/file?path=..., or deliver complete files to another registered backend with POST /api/v1/pending-uploads/{id}/deliver and {"backend_id":"..."} (this overwrites matching destination files). hoody share stop therefore refuses, and exits with status 1, while the container holds such writes or cannot say whether it does. It also refuses when a mount of the share was removed before the container confirmed it had sent everything, whether by an interrupted stop or some other way, such as through the files API: the share kept its backend then, because the backend may still hold writes that never reached your computer. For example:
✗ share "photos" is not running, and the container holds 3 files that never reached this machine. They cannot be delivered, and stopping discards them: run `hoody share stop photos --force` to discard themRun it again with --force to discard those writes and finish the cleanup; the container then deletes them, and the share removes the backend once hoody-files confirms the discard. If hoody-files cannot confirm it, the share stays cleanup pending, and running --force again finishes it. The same applies to a share left cleanup pending by a stop that ended before every write had arrived.
A new hoody share with the same name into the same container refuses to start until that cleanup is done, with an earlier share of "<name>" was not cleaned up: run `hoody share stop <name>`.
Limits
Section titled “Limits”- Foreground only. The share lasts as long as the
hoody sharecommand. Closing the terminal ends it; a background mode is not available yet. - The container’s
userneedssudo. Root can use the folder directly. The normaluseraccount reaches it throughsudofor now, in the terminal, in exec scripts and in the agent. - Online only. The folder works in the container only while your computer is online and
hoody shareruns. Otherwise reads and writes fail with an I/O error, though writes already accepted into the container’s cache may still be waiting for delivery. - Writes uploading during a container restart. If the container restarts while writes are still uploading to your computer, those writes stay in the container and are not delivered automatically.
- The last save wins. A file changed on both sides at the same moment keeps the version saved last. See The last save wins.
- Windows is not supported yet. Sharing a local folder is supported on Linux and macOS. The commands accept Windows paths, but Windows is not supported.
- One computer per mount. A shared folder comes from one computer. Several computers cannot share into the same mount path.
Use cases
Section titled “Use cases”Work on local files with container tools
Section titled “Work on local files with container tools”Share a project folder and run builds, tests or an agent against it in the container, while the files stay on your computer and remain editable in your local editor.
hoody share ~/Projects/site --name site --container "$CONTAINER_ID"# In the container:sudo ls /hoody/mounts/permanent/siteHand a dataset to a container without uploading it
Section titled “Hand a dataset to a container without uploading it”Share a folder read-only and let a container process it. The container reads the files over the share; nothing is copied into the container’s storage unless your program copies it.
hoody share ./datasets --read-only --container "$CONTAINER_ID"Collect container output on your computer
Section titled “Collect container output on your computer”Point a job’s output directory at the shared folder. Each file the job writes reaches your disk a few seconds later.
Best practices
Section titled “Best practices”Let a stop finish its wait
Section titled “Let a stop finish its wait”Press Ctrl+C once and let the share deliver its pending writes before it removes the mount. A second Ctrl+C leaves undelivered writes in the container, and once the share has stopped it cannot deliver them. Recover any files you need through the pending uploads API before using --force to discard them.
Keep your computer awake while the container uses the folder
Section titled “Keep your computer awake while the container uses the folder”A job that reads or writes the share fails with I/O errors while your computer sleeps or is offline. Keep it awake and online, and the hoody share command running, for as long as the job runs, or write to the container’s own storage and copy the result to the share afterwards.
Share the narrowest folder
Section titled “Share the narrowest folder”Everything under <dir> is reachable from the container. Share the project folder, not your home directory.
Use —read-only when the container only reads
Section titled “Use —read-only when the container only reads”A read-only share protects the folder on your computer from a mistaken write or delete in the container, including one made by an agent.
Stop shares you are not using
Section titled “Stop shares you are not using”A running share keeps an HTTPS address open on the container’s domain. It is protected by the share’s random password, but stopping the share removes it.
Useful questions
Section titled “Useful questions”Where do I find the share’s password?
Section titled “Where do I find the share’s password?”You do not. The CLI generates it for each share and hands it only to rclone on your computer and to hoody-files in the container. You never need it: the container reaches the folder through the mount.
Can I share the same folder into two containers?
Section titled “Can I share the same folder into two containers?”Yes. Run hoody share once per container, each with its own --container. Each run is a separate share with its own URL and password.
What happens to the folder when I stop the share?
Section titled “What happens to the folder when I stop the share?”Nothing. The folder on your computer stays as it is, with every write the container delivered; a stop waits for pending writes before it removes the mount. Only the mount, the backend, the tunnel and the rclone process go away.
Do symbolic links in the folder work?
Section titled “Do symbolic links in the folder work?”rclone serves the folder without following or forwarding symbolic links, so links inside it do not appear in the container.
Troubleshooting
Section titled “Troubleshooting”Input/output error in the container
Section titled “Input/output error in the container”Your computer is asleep or offline, or the hoody share command has stopped: reads fail after about 10 seconds and writes within about 10 to 20 seconds. Check the terminal on your computer. If the command is still running, reads and writes work again once your computer reconnects; write again anything that failed, because a failed write is not kept. If it has stopped, run hoody share stop <name> to clean up, then share the folder again. Writes the container still holds can no longer be delivered; stop asks for --force before it discards them (see Clean up after a crash).
A change made in the container is not on your computer yet
Section titled “A change made in the container is not on your computer yet”Writes reach your computer a few seconds after they are saved in the container. Wait a few seconds and look again. If your computer went offline in between, a successful write may still be waiting in the container’s cache: keep the share running until it reconnects, then let a normal stop confirm delivery. If the program reported an I/O error, it has to write again.
Permission denied as the container’s user
Section titled “Permission denied as the container’s user”The normal user account needs sudo to use the folder for now. Run the command with sudo, or as root.
No container specified
Section titled “No container specified”hoody share <dir> found no container to share into. Pass --container <id> or the global -c <id>, or set HOODY_CONTAINER.
rclone not found or too old
Section titled “rclone not found or too old”The CLI could not run rclone, or found a version older than v1.61.0. Install or update rclone (see Requirements), or point --rclone at the binary to use.
”was not cleaned up” when starting a share
Section titled “”was not cleaned up” when starting a share”An earlier share with the same name into the same container did not finish cleaning up. Run hoody share stop <name>, adding --force if it reports writes that never reached your computer, then start the share again.
”too old to discard” when stopping with —force
Section titled “”too old to discard” when stopping with —force”hoody share stop <name> --force reports the files kit of container <id> is too old to discard what a removed mount or backend left; update it, then run `hoody share stop <name> --force` again, and the share stays cleanup pending. The container’s files kit cannot discard writes left behind by a mount or backend that is already gone. Update the container’s files kit, then run the same command again.
Cleanup stays pending after —force
Section titled “Cleanup stays pending after —force”If hoody share stop <name> --force leaves the share cleanup pending every time you run it, the files kit may hold a record of unsent uploads that is damaged or that it cannot read. While such a record exists, the kit cannot confirm that it discarded everything, so no share stop on that container can finish, with or without --force.
List those records through the files API:
curl "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/pending-uploads/unreadable"# {"success": true, "message": "Unreadable pending uploads", "data": [{"id": "3f0c9a1e2b7d4c5a8e6f1b2c3d4e5f60", "size": 1048576, "reason": "damaged"}]}Each entry has an id, a reason and, when the kit can tell, its size in bytes. unreadable means the kit could not read the record; it may read again later, so running hoody share stop <name> --force again first can be worth it. damaged means the record was read and is cut short or damaged; it will not recover. Delete a record by its ID:
curl -X DELETE "https://{projectId}-{containerId}-files-1.{server}.containers.hoody.com/api/v1/pending-uploads/unreadable/{id}"The kit answers 204 when the record is deleted. Deleting it also deletes every unsent file it held, and cannot be undone. What it held is unknown and may be the only copy of writes that never reached your computer. The folder on your computer is not changed. Other answers:
409PENDING_UPLOAD_BUSY: an upload process that is still running uses the record, so it is not deleted. Try again once that process has ended.500PENDING_UPLOAD_PERSIST_FAILED: the files the record kept could not all be deleted, so the record is kept. Try again; if it keeps failing, check the container’s disk.404PENDING_UPLOAD_NOT_FOUND: no unreadable record has that ID. It was already deleted, or it can be read again and is no longer listed here. List the records again for current IDs.
Once the list is empty, run hoody share stop <name> --force again.
The share stops with a conflict after reconnecting
Section titled “The share stops with a conflict after reconnecting”The share stops with conflict: container port <port> has been held by another tunnel binding for 300 s; the share does not evict it when, while your computer was offline, another tunnel binding took the share’s port on the container and kept it. It stops with conflict: the tunnel came back on another URL when the reconnected tunnel did not get the share’s original URL. A share that stops this way cannot wait for pending writes, so they stay in the container and the share is cleanup pending. Run hoody share stop <name> (with --force to discard those writes), then start the share again.
What’s Next
Section titled “What’s Next”Storage:
- Container Storage → - The container filesystem and
/hoody/mounts - Mount Locally → - The reverse direction: container files on your computer
- Cloud Storage → - Mount remote storage providers through hoody-files
- SQLite Driver → - Where to keep databases instead
Kits: