# Source: https://docs.upsun.com/create-apps/image-properties/mounts.md

# mounts

Directories that are writable even after the app is built. Allocated disk for mounts is defined with a separate resource configuration call using `upsun resources:set`.

Optional in [single-runtime](https://docs.upsun.com/create-apps/app-reference/single-runtime-image.md#primary-application-properties) and [composable](https://docs.upsun.com/create-apps/app-reference/composable-image.md#primary-application-properties) images.

After your app is built, its file system is read-only.
To make changes to your app's code, you need to use Git.

For enhanced flexibility, Upsun allows you to define and use writable directories called "mounts".
Mounts give you write access to files generated by your app (such as cache and log files)
and uploaded files without going through Git.

When you define a mount, you are mounting an external directory to your app container,
much like you would plug a hard drive into your computer to transfer data.

**Note**: 

 - Mounts aren’t available during the build.
 - When you [back up an environment](https://docs.upsun.com/environments/backup.md), the mounts on that environment are also backed up.

### Define a mount

To define a mount, use the following configuration:

```yaml {}
applications:
  <APP_NAME>:
    type: nodejs:24
    source:
      root: "/"
    mounts:
      '<MOUNT_PATH>':
        source: <MOUNT_TYPE>
        source_path: <SOURCE_PATH_LOCATION>
```

    .upsun/config.yaml

```yaml {}
applications:
  <APP_NAME>:
    type: "composable:25.11"
    source:
      root: "/"
    stack:
      runtimes: [ "nodejs@24" ]
    mounts:
      '<MOUNT_PATH>':
        source: <MOUNT_TYPE>
        source_path: <SOURCE_PATH_LOCATION>
```

<MOUNT_PATH> is the path to your mount **within the app container** (relative to the app's root).
If you already have a directory with that name, you get a warning that it isn't accessible after the build.
See how to [troubleshoot the warning](https://docs.upsun.com../troubleshoot-mounts.md#overlapping-folders).

| Name          | Type                 | Required | Description |
| ------------- | -------------------- | -------- | ----------- |
| `source`      | `storage`, `instance`, `tmp` (also called `temporary`), or `service` | Yes | Specifies the type of the mount:- By design, `storage` mounts can be shared between instances of the same app. You can also configure them so they are [shared between different apps](#share-a-mount-between-several-apps).-`instance` mounts are local mounts; set to 8 GB. Unique to your app, they are useful to store files that remain local to the app instance, such as application logs.- `tmp` (or `temporary`) mounts are local ephemeral mounts, where an external directory is mounted to the `/tmp` directory of your app.The content of a `tmp` mount **may be removed during infrastructure maintenance operations**. Therefore, `tmp` mounts allow you to **store files that you’re not afraid to lose**, such as your application cache that can be seamlessly rebuilt.Note that the `/tmp` directory has **a maximum allocation of 8 GB**.- `service` mounts can be useful if you want to explicitly define and use a [Network Storage](https://docs.upsun.com/add-services/network-storage.md) service to share data between different apps (instead of using a `storage` mount).|
| `source_path` | `string`             | No      | Specifies where the mount points **inside the external directory**. - If you explicitly set a `source_path`, your mount points to a specific subdirectory in the external directory.  - If the `source_path` is an empty string (`""`), your mount points to the entire external directory. - If you don't define a `source_path`, Upsun uses the <MOUNT_PATH> as default value, without leading or trailing slashes. For example, if your mount lives in the `/web/uploads/` directory in your app container, it will point to a directory named `web/uploads` in the external directory.     **WARNING:** Changing the name of your mount affects the `source_path` when it's undefined. See [how to ensure continuity](#change-name) and maintain access to your files. |
| `service`     | `string`             |         | The purpose of the `service` key depends on your use case.   In a multi-app context where a `storage` mount is shared between apps, `service` is required. Its value is the name of the app whose mount you want to share. See how to [share a mount between several apps](#share-a-mount-between-several-apps).   In a multi-app context where a [Network Storage service](https://docs.upsun.com/add-services/network-storage.md) (`service` mount) is shared between apps, `service` is required and specifies the name of that Network Storage. |

The accessibility to the web of a mounted directory depends on the [`web.locations` configuration](https://docs.upsun.com/create-apps/image-properties/web.md).
Files can be all public, all private, or with different rules for different paths and file types.

Note that when you remove a `tmp` mount from your `.upsun/config.yaml` file,
the mounted directory isn't deleted.
The files still exist on disk until manually removed,
or until the app container is moved to another host during a maintenance operation.

### Example configuration

```yaml {}
applications:
  <APP_NAME>:
    type: "nodejs@24"
    source:
      root: "/"
    mounts:
      'web/uploads':
        source: storage
        source_path: uploads
      '/.tmp_platformsh':
        source: tmp
        source_path: files/.tmp_platformsh
      '/build':
        source: storage
        source_path: files/build
      '/.cache':
        source: tmp
        source_path: files/.cache
      '/node_modules/.cache':
        source: tmp
        source_path: files/node_modules/.cache
```

    .upsun/config.yaml

```yaml {}
applications:
  <APP_NAME>:
    type: "composable:25.11"
    source:
      root: "/"
    stack:
      runtimes: [ "nodejs@24" ]
    mounts:
      'web/uploads':
        source: storage
        source_path: uploads
      '/.tmp_platformsh':
        source: tmp
        source_path: files/.tmp_platformsh
      '/build':
        source: storage
        source_path: files/build
      '/.cache':
        source: tmp
        source_path: files/.cache
      '/node_modules/.cache':
        source: tmp
        source_path: files/node_modules/.cache
```

### Ensure continuity when changing the name of your mount {#change-name}

Changing the name of your mount affects the default `source_path`.

Suppose you have a `/my/cache/` mount with an undefined `source_path`:

```yaml {}
applications:
  <APP_NAME>:
    type: "nodejs@24"
    mounts:
      '/my/cache/':
        source: tmp
```

    .upsun/config.yaml

```yaml {}
applications:
  <APP_NAME>:
    type: "composable:25.11"
    mounts:
      '/my/cache/':
        source: tmp
```

If you rename the mount to `/cache/files/`, it will point to a new, empty `/cache/files/` directory.

To ensure continuity, you must explicitly define the `source_path` as the previous name of the mount, without leading
or trailing slashes:

```yaml {}
applications:
  <APP_NAME>:
    type: "nodejs@24"
    mounts:
      '/cache/files/':
        source: tmp
        source_path: /my/cache
```

    .upsun/config.yaml

```yaml {}
applications:
  <APP_NAME>:
    type: "composable:25.11"
    mounts:
      '/cache/files/':
        source: tmp
        source_path: /my/cache
```

The `/cache/files/` mount now points to the original `/my/cache/` directory, maintaining access to all your existing
files in that directory.

### Share a mount between several apps

By design, [`storage` mounts](https://docs.upsun.com/create-apps/image-properties/mounts.md) are shared **between different instances of the same app**,
which enables [horizontal scaling](https://docs.upsun.com/manage-resources.md).

In a [multi-application context](https://docs.upsun.com/create-apps/multi-app.md),
you can even share a `storage` mount **between different applications** in the same project.

To do so, you need to define a `storage` mount in each of your app containers,
and point each of those mounts to the same shared external network directory.

Use the following configuration:

```yaml {}
applications:
  app1:
    type: "nodejs@24"
    mounts:
      '<MOUNT_PATH_1>':
        source: storage
        source_path: <SOURCE_PATH_LOCATION>

  app2:
    type: "nodejs@24"
    mounts:
      '<MOUNT_PATH_2>':
        source: storage
        service: app1
        source_path: <SOURCE_PATH_LOCATION>
```

    .upsun/config.yaml

```yaml {}
applications:
  app1:
    type: "composable:25.11"
    mounts:
      '<MOUNT_PATH_1>':
        source: storage
        source_path: <SOURCE_PATH_LOCATION>

  app2:
    type: "composable:25.11"
    mounts:
      '<MOUNT_PATH_2>':
        source: storage
        service: app1
        source_path: <SOURCE_PATH_LOCATION>
```

- <MOUNT_PATH_1> and <MOUNT_PATH_2> are the paths to each mount **within their
  respective app container** (relative to the app's root).
- When configuring the first `storage` mount, you don't need to include the `service` key.
  The first mount implicitly points to an external network directory.
  The `service` key is required for subsequent mounts, to ensure they use the same external network directory as the
  first mount.
- The `source_path` allows you to point each mount to the same subdirectory **within the shared external network
  directory**.

#### Example

Suppose you have a `backend` app and a `frontend` app, and you want both apps to share data from the same mount. 
To achieve this, complete the following steps:

1. In your `backend` app configuration, define a `storage` mount:

```yaml {}
applications:
  backend:
  type: "nodejs@24"
    mounts:
      var/uploads: #The path to your mount within the backend app container.
        source: storage
        source_path: backend/uploads #The path to the source of the mount within the external network directory.
```

    .upsun/config.yaml

```yaml {}
applications:
  backend:
    type: "composable:25.11"
    mounts:
      var/uploads: #The path to your mount within the backend app container.
        source: storage
        source_path: backend/uploads #The path to the source of the mount within the external network directory.
```

  This creates a `storage` mount named `var/uploads` in the `backend` app container.
  The mount points to the `backend/uploads` directory within an external network directory.

2. In your `frontend` app configuration, define another `storage` mount:

```yaml {}
applications:
   backend:
     type: "nodejs@24"
     mounts:
       var/uploads:
         source: storage
         source_path: backend/uploads

   frontend:
     type: "nodejs@24"
     mounts:
       web/uploads: #The path to your mount within the frontend app container.
         source: storage
         service: backend #The name of the other app, so the mount can point to the same external network directory as that other app's mount.
         source_path: backend/uploads #The path to the source of the mount within the shared external network directory.
```

    .upsun/config.yaml

```yaml {}
applications:
  backend:
    type: "composable:25.11"
    mounts:
      var/uploads:
        source: storage
        source_path: backend/uploads

  frontend:
    type: "composable:25.11"
    mounts:
      web/uploads: #The path to your mount within the frontend app container.
        source: storage
        service: backend #The name of the other app, so the mount can point to the same external network directory as that other app's mount.
        source_path: backend/uploads #The path to the source of the mount within the shared external network directory.
```

   This creates another `storage` mount named `web/uploads` in the `frontend` app container.

   The `service` key allows you to specify that the `web/uploads` mount should use the same external network directory
   as the mount previously defined in the `backend` app container.

   The `source_path` key specifies which subdirectory within the external network directory both mounts should share (
   here, the `backend/uploads` directory).

Note that another way to share data between apps through a mount is by
explicitly [defining a Network Storage service](https://docs.upsun.com/add-services/network-storage.md).

### Composable image only: Local mounts

If you need a local mount (i.e. unique per container),
Upsun allows you to mount a directory within the `/tmp` directory of your app.
However, the following limitations apply:

- Content from `tmp` mounts is removed when your app container is moved to another host during an infrastructure
  maintenance operation
- The `/tmp` directory has a [maximum allocation of 8 GB](https://docs.upsun.com/create-apps/troubleshoot-disks.md#no-space-left-on-device)

Therefore, `tmp` mounts are ideal to store non-critical data, such as your application cache which can be seamlessly
rebuilt,
but aren't suitable for storing files that are necessary for your app to run smoothly.

Note that Upsun will provide new local mounts in the near future.

### Overlapping mounts

The locations of mounts as they are visible to application containers can overlap somewhat.
For example:

```yaml  {location=".upsun/config.yaml"}
applications:
  myapp:
    # ...
    mounts:
      'var/cache_a':
        source: storage
        source_path: cacheA
      'var/cache_b':
        source: tmp
        source_path: cacheB
      'var/cache_c':
        source: instance
        source_path: cacheC
```

In this case, it does not matter that each mount is of a different `source` type.
Each mount is restricted to a subfolder within `var`, and all is well.

The following, however, is not allowed and will result in a failure:

```yaml  {location=".upsun/config.yaml"}
applications:
  myapp:
    # ...
    mounts:
      'var/':
        source: storage
        source_path: cacheA
      'var/cache_b':
        source: tmp
        source_path: cacheB
      'var/cache_c':
        source: instance
        source_path: cacheC
```

The `storage` mount type specifically exists to share data between instances of the same application, whereas `tmp` and `instance` are meant to restrict data to build time and runtime of a single application instance, respectively.
These allowances are not compatible, and will result in an error if pushed.