> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mounting a Filesystem

> Mount a CloudFS filesystem on a Linux host or container with the JuiceFS Community Edition client, using the metadata URL and your Telnyx API key.

A CloudFS filesystem is mounted with the [JuiceFS](https://juicefs.com) Community Edition client — there is no Telnyx-specific agent or daemon. The client talks to two backends directly: the metadata database (over a managed endpoint) and Telnyx Cloud Storage (over S3). You give it a metadata URL and a set of S3 credentials, and it exposes a POSIX filesystem at a mountpoint. This page is the end-to-end mount recipe, verified against a live filesystem.

If you haven't created a filesystem yet, start with the [Quick Start](/docs/edge-compute/cloudfs/quickstart). For the two-lane architecture behind the credentials below, see [How CloudFS Works](/docs/edge-compute/cloudfs/concepts/how-cloudfs-works).

## Prerequisites

* **The JuiceFS Community Edition client.** Install it per the [JuiceFS docs](https://juicefs.com/docs/community/getting-started/installation) and check with `juicefs version`. This recipe was verified end-to-end with JuiceFS CE 1.4.0.
* **A Linux host or container with FUSE** (a usable `/dev/fuse`). JuiceFS mounts through FUSE.
* **A created CloudFS filesystem**, and the `meta_url` and `meta_token` from its create response. The token is returned **only** at create (and on rotate) — if you didn't store it, you cannot reconstruct it and must rotate to get a new one.

<Note>
  Running JuiceFS inside a Linux container is the most portable way to mount — it needs no FUSE install on the host and behaves identically everywhere, which is why the walkthrough below uses it. You can also mount natively on any Linux or macOS host that has FUSE (macOS requires [macFUSE](https://macfuse.github.io/)).
</Note>

## Credentials the Client Needs

The client holds three things. None of them is a raw database password — the metadata token *is* the password, embedded in the URL.

| Variable         | Where it comes from                                  | Used for                                              |
| ---------------- | ---------------------------------------------------- | ----------------------------------------------------- |
| `TELNYX_API_KEY` | Your Telnyx account                                  | Doubles as the **S3 access key** for the data lane    |
| `META_URL`       | The `meta_url` field of the create/get response      | The metadata connection (metadata endpoint)           |
| `meta_token`     | The `meta_token` field of the create/rotate response | The connection password, carried inline in `META_URL` |

The `meta_url` returned by **create** already has the token inline as the password:

```
postgres://fs_<hex>:cloudfs_tok_...@us-east-1.telnyxcloudfs.com:5432/fs_<hex>?sslmode=require
```

The `meta_url` returned by **`GET /v2/storage/cloudfs/{id}`** is the same string **without** the token:

```
postgres://fs_<hex>@us-east-1.telnyxcloudfs.com:5432/fs_<hex>?sslmode=require
```

If you're working from the tokenless URL, splice your stored `meta_token` in as the password (`postgres://fs_<hex>:<meta_token>@...`). The host is always the region metadata host `us-east-1.telnyxcloudfs.com` — metadata is centralized there regardless of the filesystem's data region.

## Set the Environment

```bash theme={null}
export TELNYX_API_KEY="KEY..."   # your account API key
export META_URL="postgres://fs_<hex>:cloudfs_tok_...@us-east-1.telnyxcloudfs.com:5432/fs_<hex>?sslmode=require"

# S3 credentials for the data lane. The access key is your API key.
# The secret key's signature is ignored by Telnyx Storage — but it must be non-empty.
export AWS_ACCESS_KEY_ID="$TELNYX_API_KEY"
export AWS_SECRET_ACCESS_KEY="placeholder"
```

CloudFS volumes are formatted without embedded object-storage credentials, so JuiceFS picks them up from `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` at mount time. Set them explicitly. Telnyx Cloud Storage authenticates on the **access key alone** and ignores the SigV4 signature, so the secret can be any non-empty string — see [Cloud Storage authentication](/docs/cloud-storage/authentication). An empty secret fails: JuiceFS's AWS SDK rejects it with `static credentials are empty`.

<Warning>
  Do **not** run `juicefs format` against a filesystem whose status is `ready`. Provisioning already formats the volume (the bucket ships with a `juicefs_uuid` object and a fixed volume name), and re-formatting fails with `cannot update volume name`. The one exception is a filesystem in `needs_format` — see [Formatting a needs\_format filesystem](#formatting-a-needs_format-filesystem).
</Warning>

## Mount

Mount in the background and write logs to a file so the mount doesn't block your terminal.

```bash theme={null}
mkdir -p /mnt/agentfs

juicefs mount --no-usage-report --background --log /tmp/juicefs.log "$META_URL" /mnt/agentfs
```

The first positional argument is the metadata URL; the second is the mountpoint. On success the process returns immediately and the filesystem is live at `/mnt/agentfs`. Watch `/tmp/juicefs.log` for the mount status and any warnings.

<Note>
  The `--no-usage-report` flag opts out of JuiceFS's [anonymous usage reporting](https://github.com/juicedata/juicefs#usage-tracking). By default the JuiceFS client reports core metrics (such as its version) to the JuiceFS project on mount; it does not include user data. These docs pass `--no-usage-report` on every mount so CloudFS filesystems don't phone home by default — drop the flag if you'd like to share usage data with the upstream project.
</Note>

### Formatting a `needs_format` Filesystem

If `GET /v2/storage/cloudfs/{id}` reports `"status": "needs_format"`, the bucket and metadata database exist but the volume was never formatted, and mounting fails with `database is not formatted, please run juicefs format ... first`. This is the one case where you run `juicefs format` — once, then mount as normal:

```bash theme={null}
# Only for status: needs_format. The volume name is the s3_bucket value.
juicefs format --storage s3 \
  --bucket "<s3_endpoint>/<s3_bucket>" \
  "$META_URL" <s3_bucket>
```

`<s3_endpoint>` and `<s3_bucket>` come from the filesystem's detail response, and the JuiceFS volume name **must** be the `s3_bucket` value (`cloudfs-fs-<hex>`) — any other name is rejected. Keep `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` exported (`format` probes the bucket over S3) and leave `--access-key` / `--secret-key` unset: the stored volume config then carries no credentials, same as a factory-formatted filesystem. Note that `--no-usage-report` is a `mount` flag — `format` doesn't accept it.

## In a Container (Docker)

The container needs FUSE and the `juicefs` binary. Run it privileged and pass the FUSE device through with `--device /dev/fuse`.

```bash theme={null}
docker run --rm -it \
  --privileged \
  --device /dev/fuse \
  -e TELNYX_API_KEY="$TELNYX_API_KEY" \
  -e META_URL="postgres://fs_<hex>:cloudfs_tok_...@us-east-1.telnyxcloudfs.com:5432/fs_<hex>?sslmode=require" \
  ubuntu:24.04 bash
```

Inside the container, install the client and mount:

```bash theme={null}
apt-get update && apt-get install -y curl fuse   # use fuse3 if fuse is unavailable
curl -sSL https://d.juicefs.com/install | sh -   # installs the JuiceFS CE client
juicefs version                                  # verified with 1.4.0

export AWS_ACCESS_KEY_ID="$TELNYX_API_KEY"
export AWS_SECRET_ACCESS_KEY="placeholder"

mkdir -p /mnt/agentfs
juicefs mount --no-usage-report --background --log /tmp/juicefs.log "$META_URL" /mnt/agentfs
```

<Note>
  `--privileged` and `--device /dev/fuse` are what let FUSE mount inside the container. Without them the mount fails to open `/dev/fuse`. If you bake the `juicefs` binary and `fuse` into your own image, you can skip the install step and go straight to `juicefs mount`.
</Note>

## Verify the Mount

```bash theme={null}
# Confirm the mountpoint is a real mount
mountpoint /mnt/agentfs

# CloudFS reports a very large logical capacity (~1.0 PB)
df -h /mnt/agentfs

# Round-trip a file
echo "hello cloudfs" > /mnt/agentfs/hello.txt
cat /mnt/agentfs/hello.txt

# Larger read/write test — write 10 MiB, read it back
dd if=/dev/urandom of=/mnt/agentfs/blob bs=1M count=10
md5sum /mnt/agentfs/blob
```

Anything you write is chunked into 4 MiB block objects in the filesystem's Cloud Storage bucket and persists across unmount/remount. A normal filesystem workflow works on top of it — for example `git init` and `git commit` inside the mountpoint behave as expected.

## Unmount

```bash theme={null}
juicefs umount /mnt/agentfs
```

Unmounting only tears down the local FUSE mount; it does not touch the metadata database or the bucket. Remounting the same `META_URL` brings all files back.

## Troubleshooting

| Symptom                                                                                                                                                               | Cause                                                                                                                                                                                  | Fix                                                                                                                                  |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `static credentials are empty` at mount                                                                                                                               | `AWS_SECRET_ACCESS_KEY` is empty                                                                                                                                                       | Set it to any non-empty placeholder — the signature is ignored, but the value can't be blank                                         |
| Mount succeeds, but writes hang for \~5 minutes and then fail (`flush … timeout`, `PutObject … exceeded maximum number of attempts` in the log), leaving 0-byte files | `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` missing or misnamed — mounting only talks to the metadata lane, so it comes up without S3 credentials; the data flush is what needs them | Export both variables, exact names, in the environment of the mount process (inside the container, not just on the host) and remount |
| `database is not formatted` at mount                                                                                                                                  | The filesystem's status is `needs_format`                                                                                                                                              | [Format it once](#formatting-a-needs_format-filesystem), then mount                                                                  |
| `cannot update volume name`                                                                                                                                           | You ran `juicefs format` against a `ready` (already-formatted) filesystem                                                                                                              | Don't — `format` is only for `needs_format`. Otherwise, only `mount`                                                                 |

## Next Steps

* [Concurrent Access](/docs/edge-compute/cloudfs/concurrent-access) — mount the same filesystem from many clients at once, and coordinate writers with locks
* [How CloudFS Works](/docs/edge-compute/cloudfs/concepts/how-cloudfs-works) — the metadata and data lanes, and what lives where
* [API Reference](/api-reference/cloudfs-filesystems/list-cloudfs-filesystems) — create, list, get, update, delete, and rotate the metadata token
* [Overview](/docs/edge-compute/cloudfs) — what CloudFS is and when to reach for it
