Skip to content
Hoody.com

Every container gets a full filesystem when it is created. That filesystem persists across restarts, snapshots, and copy operations.


Container management:

File access:


Storage is not adjustable at the container level yet. The system allocates it when you create the container, and no API parameter sets a storage size per container.

Each container starts with:

  • Full Linux filesystem (root directory /)
  • Persistent across container restarts
  • Survives snapshots and restores
  • Maintained during copy operations
  • Standard Linux filesystem with full POSIX support

When you create a container with hoody_kit: true, Hoody Kit services that keep state on disk use /hoody/storage as their data directory. Exact layout is service-dependent; a typical tree looks like:

Terminal window
/hoody/storage/
├── hoody-terminal/ # terminal session data, screenshots
├── hoody-display/ # display screenshots and thumbnails
├── hoody-exec/ # exec scripts and cache
├── hoody-browser/ # browser builds, fingerprint profiles, extensions, history
├── hoody-code/ # hoody-code workspace settings
├── hoody-curl/ # hoody-curl job storage
├── hoody-run/ # hoody-run app data
├── hoody-agent/ # agent service state
├── hoody-daemon/ # hoody-daemon configs
├── hoody-notifications/ # hoody-notifications data
├── hoody-tunnel/ # hoody-tunnel configs
├── logs/ # aggregated service logs
└── ... # plus any service-specific subdirectories

The files service also keeps its own protected state under /hoody/storage. It isn’t reachable through the file API or WebDAV and isn’t a public interface. Stateless services (pipe, ssh, dynamic http/https ports) don’t create a dedicated directory here. hoody-pipe, for instance, relays transfers, live broadcasts and WebSocket messages without writing payloads to disk. Its buffers and short-lived transfer receipts stay in memory; there is no saved stream to replay.

You don’t create or configure /hoody/storage. Creating a container with Hoody Kit establishes it.

That convention has practical consequences:

  • All service data sits in one predictable location.
  • Backing up your application data is a copy of one directory, or an instant ZIP download from hoody-files (folder-as-zip works on both the WebDAV-style root path and the /api/v1/files REST surface via ?zip). The ZIP download leaves out protected service state; a plain copy inside the container does not. For a complete backup, use a container snapshot.
  • Service state is simple to inspect.
  • The layout is the same in every container.

Container Root (/)
├── /home/ # User directories (writable)
├── /hoody/
│ ├── /hoody/storage/ # Hoody Kit service data (yours)
│ ├── /hoody/databases/ # Conventional home for SQLite databases (yours)
│ ├── /hoody/shares/ # Mounted shared storage (if any)
│ ├── /hoody/mounts/ # Remote backends mounted by hoody-files
│ │ └── permanent/ # Your named mounts (POST /api/v1/mounts, hoody share)
│ ├── /hoody/plugins/ # Kit binaries (platform-managed)
│ └── /hoody/secrets/ # Service credentials (platform-managed)
├── /ramdisk/ # RAM-backed storage (if enabled)
├── /tmp/ # Temporary files (cleared on restart)
└── ... (standard Linux filesystem)

Three locations behave specially:

  1. /hoody/storage - Hoody Kit service data (automatic)
  2. /hoody/databases - The conventional home for SQLite databases, where hoody-sqlite resolves bare names
  3. /ramdisk - Optional RAM-backed storage (capacity drawn from a shared per-server RAM pool: 512 MiB by default, capped at 50% of server memory)

See dedicated pages for details on /hoody/databases and /ramdisk.


What survives each operation:

Terminal window
POST /api/v1/containers/{id}/restart

All filesystem data persists:

  • /hoody/storage - intact
  • /hoody/databases - intact
  • /ramdisk - intact
  • User files - intact
  • Installed packages - intact

/ramdisk is the exception: it is RAM-based, survives container stop, start, and restart, and is cleared on host reboot. See /ramdisk for details.


The system allocates storage as part of container creation:

Terminal window
# Create a container; storage is allocated automatically
hoody containers create --project $PROJECT_ID --server-id $SERVER_ID --name "my-app" --hoody-kit

There is no storage-size parameter to send. The system allocates storage at the host level.


You can reach container storage in several ways:

HTTP API

Hoody Files - Direct HTTP access to filesystem

Terminal window
GET /api/v1/files/hoody/storage/hoody-exec/scripts/default/1/hello.ts
  • Read/write files via HTTP
  • Download with SHA256 verification
  • List directories with JSON/HTML output
  • Stream large files

Local mounting

Mount Locally - SFTP (Hoody API SSH proxy) / WebDAV (hoody-files)

Mount container filesystem on your local machine:

  • macOS Finder / Windows Explorer
  • FileZilla, Cyberduck, WinSCP
  • Command-line SFTP/WebDAV clients

WebDAV is served by hoody-files; SFTP comes from the Hoody API’s SSH proxy.

Terminal access

Hoody Terminal - Web-based shell

Terminal window
ls -la /hoody/storage/
cat /hoody/databases/app.db
echo "data" > /ramdisk/cache.txt

Full shell access via browser.

SSH access

SSH - Secure shell

Terminal window
ssh root@{projectId}-{containerId}-ssh.{serverName}.containers.hoody.com # same shape as every other service, minus the instance number
cd /hoody/storage

Optional - terminal access works without SSH.


Terminal window
# Code, dependencies, build artifacts
/home/user/projects/ # Your code
/hoody/storage/hoody-exec/scripts/default/1/ # HTTP-callable scripts
/ramdisk/build/ # RAM-backed build cache

Use /ramdisk for build artifacts and the regular filesystem for source code, which has to persist.

Terminal window
/hoody/databases/production.db # Where hoody-sqlite and the tooling look
/hoody/databases/staging.db # Local to this container; no replication

Keep SQLite databases in /hoody/databases/: it is where bare database names resolve and where a confined hoody-sqlite is allowed to read. Writes are safe for processes inside the container, and the directory is not shared with any other container. See SQLite Driver.

Terminal window
# User uploads, media files
/hoody/storage/uploads/ # Persistent user data
/ramdisk/processing/ # Temporary file processing

Accept uploads into regular storage and use /ramdisk for temporary processing such as image resizing or video transcoding.


Terminal window
# Container resource stats (includes disk usage)
# The id is positional here - the global -c/--container does not work on this command
hoody containers stats $CONTAINER_ID -o json

From inside the container, via hoody-terminal:

Terminal window
df -h
# Shows filesystem usage
du -sh /hoody/storage/*
# Shows Hoody Kit service data sizes
du -sh /hoody/databases/*
# Shows database sizes

Remove unused data:

Terminal window
# Clear package manager cache
apt-get clean
# Remove old logs
rm -rf /hoody/storage/*/logs/*.old
# Clear ramdisk (frees server memory immediately)
rm -rf /ramdisk/*

Storage is not adjustable per container today. The workaround is to create a new container and move the data across:

  1. Create snapshot of old container
  2. Create new container (receives system-allocated storage)
  3. Transfer data via storage shares
  4. Verify migration
  5. Delete old container

Store your app’s persistent data in /hoody/storage/myapp/ to keep it organized with Hoody Kit services:

Terminal window
mkdir -p /hoody/storage/myapp/data
mkdir -p /hoody/storage/myapp/configs
mkdir -p /hoody/storage/myapp/logs

Keep SQLite databases in /hoody/databases/

Section titled “Keep SQLite databases in /hoody/databases/”

Keep SQLite databases in /hoody/databases/, where the tooling looks for them:

Terminal window
# Conventional
sqlite3 /hoody/databases/app.db

Never put one on a path another container mounts. A network share does not reliably honor the file locks SQLite needs, and that is how a database is corrupted rather than merely locked.

Use it for caches, build artifacts, and temporary processing:

Terminal window
# RAM-backed temporary storage
/ramdisk/npm-cache/
/ramdisk/build-output/
/ramdisk/image-processing/

/ramdisk is cleared on host reboot, not on container restart.

Before modifying large amounts of data or testing destructive operations:

Terminal window
POST /api/v1/containers/{id}/snapshots
{"alias": "before-cleanup-2025-11-10"}

Storage is persistent but not immune to accidental deletion.

Set up monitoring for storage capacity:

Terminal window
# Check if storage >80% full
df -h / | awk 'NR==2 {print $5}' | sed 's/%//'

Integrate with hoody-notifications for alerts.


Can I change storage size after creating a container?

Section titled “Can I change storage size after creating a container?”

No. Storage allocation is not adjustable at the container level. The host allocates it automatically when the container is created.

The workaround is to create a new container and migrate the data through storage shares or a manual copy.

What happens to /hoody/storage if I disable Hoody Kit?

Section titled “What happens to /hoody/storage if I disable Hoody Kit?”

The directory remains (it’s just a directory), but services won’t write to it since they’re not installed. Existing data persists.

Is /hoody/storage a special mount or just a directory?

Section titled “Is /hoody/storage a special mount or just a directory?”

Just a regular directory with a specific purpose: Hoody Kit services use it by convention. It has no special filesystem characteristics.

How is /hoody/storage different from /hoody/databases/?

Section titled “How is /hoody/storage different from /hoody/databases/?”
  • /hoody/storage = Regular directory where Hoody Kit stores service data
  • /hoody/databases/ = Also a regular directory, the conventional home for SQLite databases and where hoody-sqlite resolves bare names

See SQLite Driver for /hoody/databases/ details.

Can I share /hoody/storage between containers?

Section titled “Can I share /hoody/storage between containers?”

Yes. Use Storage Shares:

Terminal window
POST /api/v1/containers/{id}/storage/shares
{
"source_path": "/hoody/storage/myapp",
"target_project_id": "{project}",
"mode": "readonly"
}

Does /hoody/storage count toward storage quota?

Section titled “Does /hoody/storage count toward storage quota?”

Yes. All on-disk usage (including /hoody/storage) counts toward your container’s total storage. The one exception is /ramdisk, which is memory rather than disk and counts toward no disk total. The per-container allocation is system-managed: there is no storage-size parameter on the create or update endpoints, so you can’t resize it directly from the client.


Problem: “No space left on device” errors

Solutions:

  1. Check storage usage:

    Terminal window
    df -h
    du -sh /* | sort -h
  2. Clean package cache:

    Terminal window
    apt-get clean
    apt-get autoremove
  3. Remove old logs:

    Terminal window
    find /hoody/storage -name "*.log" -mtime +30 -delete
  4. Clear /ramdisk if full:

    Terminal window
    rm -rf /ramdisk/*

Problem: Permission denied writing to /hoody/storage

Solution: Containers run as root - this shouldn’t happen. Check:

Terminal window
ls -la /hoody/
# Should show: drwxr-xr-x root root

If permissions are wrong, fix only the affected directory. New files created through the files kit belong to user by default, so for an application directory meant for that user:

Terminal window
chown user:user /hoody/storage/myapp
chmod 755 /hoody/storage/myapp

Do not reset /hoody/storage recursively; that overwrites the intended ownership and modes of other applications’ data.

Problem: Directory doesn’t exist in new container

Cause: Container created with hoody_kit: false

Solution: /hoody/storage is only created when Hoody Kit is installed. If you need it:

Terminal window
mkdir -p /hoody/storage

But services won’t use it without Hoody Kit enabled.


Storage ecosystem:

File access methods: