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

# Volumes

> Learn how to configure persistent volumes on Stormkit to upload, manage and share files across deployments.

## Overview

Stormkit's Volumes feature allows you to maintain persistent files across deployments. This feature is perfect for applications that need to store and manage persistent data such as:

* Configuration files
* User-uploaded content
* Media assets
* Cache files
* Any files that need to persist between updates

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/stormkit-io-stormkit-io/assets/docs/features/demo-volumes.png" alt="Persistent volumes configuration" />
</Frame>

## Enabling Volumes (Self-Hosted)

<Warning>
  This step is necessary only for self-hosted users. Cloud-hosted Stormkit users have volumes pre-configured.
</Warning>

To start using Volumes:

<Steps>
  <Step title="Navigate to Volumes">
    Go to your application's environment and click on the **Volumes** tab in the navigation bar
  </Step>

  <Step title="Configure storage">
    Click on **Configure** to set up your volume storage
  </Step>

  <Step title="Set root path">
    Configure the root path where files will be stored (default: `/shared/volumes`)
  </Step>
</Steps>

<Info>
  You will need `Admin` rights in order to configure the volumes configuration.
</Info>

## Configuration

Currently Stormkit supports file systems as persistent volumes. If you have a specific request (such as AWS S3, Alibaba OSS, Hetzner OSS or other storages), please [create a feature request](https://github.com/stormkit-io/app-stormkit-io/issues).

### File System

* **Root path**: The base path where your files will be stored (default: `/shared/volumes`)

These settings will apply to all applications across your instance.

## Managing Files

<Frame>
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/stormkit-io-stormkit-io/assets/docs/features/demo-volumes-files.png" alt="File explorer interface" />
</Frame>

### Uploading Files

<CardGroup cols={2}>
  <Card title="Upload Files" icon="file-arrow-up">
    Click **Upload file** button to upload individual files to your volume.
  </Card>

  <Card title="Upload Folders" icon="folder-arrow-up">
    Click **Upload folders** button. The folder structure is maintained during upload.
  </Card>
</CardGroup>

### File Operations

For each file in your volume, you can:

* **Change visibility** - Toggle between public and private
* **Download** - Download the file to your local machine
* **Delete** - Remove the file from the volume

## Making Files Public

By default, all uploaded files in your volume are private files. To make them public:

<Steps>
  <Step title="Open file menu">
    Click the three dots menu (...) next to the file
  </Step>

  <Step title="Make public">
    Select **Make public** from the menu
  </Step>

  <Step title="Confirm">
    Confirm your choice in the dialog
  </Step>

  <Step title="Get URL">
    Once public, you'll receive a URL to access the file
  </Step>
</Steps>

<Info>
  Public files can be accessed by anyone with the URL. Private files require authentication to access.
</Info>

## Accessing Files (Self-Hosted, File System)

Self-hosted users using a File System volume can access files directly from the file system.

The folder structure is as follows:

```bash theme={null}
# Folder structure
<root-path>/a<app-id>e<env-id>/<path-to-file>

# Example
root path: /shared/volumes
app id   : 152
env id   : 235
file name: example/file-name.png

# Result
/shared/volumes/a152e235/example/file-name.png
```

### Example: Accessing from Code

```javascript theme={null}
// Node.js example
const fs = require('fs');
const path = require('path');

const volumePath = process.env.VOLUME_PATH || '/shared/volumes';
const appId = process.env.APP_ID;
const envId = process.env.ENV_ID;

const filePath = path.join(volumePath, `a${appId}e${envId}`, 'example/file-name.png');
const fileContent = fs.readFileSync(filePath);
```

## Use Cases

<CardGroup cols={2}>
  <Card title="User Uploads" icon="image">
    Store user-generated content like profile pictures, documents, or media files that persist across deployments.
  </Card>

  <Card title="Configuration" icon="gear">
    Maintain configuration files that can be updated without redeployment.
  </Card>

  <Card title="Static Assets" icon="file">
    Store static assets that are too large to include in your repository.
  </Card>

  <Card title="Cache Storage" icon="database">
    Persist cache files between deployments for improved performance.
  </Card>
</CardGroup>

## Best Practices

* **Regular backups** - The Volumes feature is currently in beta. It's recommended to regularly backup important data
* **Monitor storage usage** - Keep track of your storage consumption
* **Use appropriate visibility** - Only make files public if they truly need to be publicly accessible
* **Organize with folders** - Use folder structures to keep files organized
* **Clean up unused files** - Regularly remove files that are no longer needed

## Limitations

<Warning>
  The Volumes feature is currently in beta.
</Warning>

* File system storage only (cloud storage coming soon)
* Storage limits may apply depending on your plan
* Public URLs are permanent - changing a file to private won't invalidate the URL immediately

## Security Considerations

* **Private by default** - All files are private unless explicitly made public
* **Access control** - Only team members with appropriate permissions can manage volumes
* **Isolated storage** - Each environment has its own isolated storage space
* **Secure URLs** - Public file URLs are served over HTTPS

## Troubleshooting

<AccordionGroup>
  <Accordion title="Cannot upload files">
    * Verify you have Admin rights for the environment
    * Check storage quota limits
    * Ensure file names don't contain special characters
    * Try uploading smaller files first
  </Accordion>

  <Accordion title="Files not accessible from application">
    * Verify the file path is correct
    * Check the folder structure: `a<app-id>e<env-id>`
    * Ensure the application has read permissions
    * Verify the volume is properly configured
  </Accordion>

  <Accordion title="Public URL not working">
    * Wait a few minutes for the change to propagate
    * Clear browser cache
    * Verify the file is marked as public
    * Check if the file still exists in the volume
  </Accordion>
</AccordionGroup>
