Files
dokku/docs/advanced-usage/persistent-storage.md
Jose Diaz-Gonzalez c50f39b4fa docs: more cleanup
2021-07-09 22:46:52 -04:00

151 lines
7.2 KiB
Markdown

# Persistent Storage
> New as of 0.5.0
The preferred method to mount external containers to a Dokku managed container, is to use the Dokku storage plugin.
```
storage:list <app> # List bind mounts for app's container(s) (host:container)
storage:mount <app> <host-dir:container-dir> # Create a new bind mount
storage:report [<app>] [<flag>] # Displays a checks report for one or more apps
storage:unmount <app> <host-dir:container-dir> # Remove an existing bind mount
```
> The storage plugin is compatible with storage mounts created with the docker-options. The storage plugin will only list mounts from the deploy/run phase.
The storage plugin supports the following mount points:
- explicit paths that exist on the host
- docker volumes
## Usage
This example demonstrates how to mount the recommended directory to `/storage` inside an application called `node-js-app`. For simplicity, the Dokku project recommends using the directory `/var/lib/dokku/data/storage` directory as the root host path for mounts. This directory is created on Dokku installation.
```shell
# we use a subdirectory inside of the host directory to scope it to just the app
dokku storage:mount node-js-app /var/lib/dokku/data/storage/node-js-app:/storage
```
Dokku will then mount the shared contents of `/var/lib/dokku/data/storage/node-js-app` to `/storage` inside the container. Mounts are only available for containers crated via `run` and by the deploy process, and not during the build process. In addition, the host path is never auto-created by either Dokku or Docker, and should be an explicit path, not one relative to the current working directory.
> If the `/storage` path within the container had pre-existing content, the container files will be overrwritten. This may be an issue for users that create assets at build time but then mount a directory at the same place during runtime. Files are not merged.
Once you have mounted persistent storage, you will also need to restart the application. See the
[process scaling documentation](/docs/processes/process-management.md) for more information.
```shell
dokku ps:restart app-name
```
A more complete workflow may require making a custom directory for your application and mounting it within your `/app/storage` directory instead. The mount point is *not* relative to your application's working directory, and is instead relative to the root (`/`) of the container.
```shell
# creating storage for the app 'node-js-app'
mkdir -p /var/lib/dokku/data/storage/node-js-app
# set the directory ownership. Below is an example for herokuish
# but see the `Directory Permissions` section for more details
chown -R 32767:32767 /var/lib/dokku/data/storage/node-js-app
# mount the directory into your container's /app/storage directory, relative to root
dokku storage:mount app-name /var/lib/dokku/data/storage/node-js-app:/app/storage
```
You can mount one or more directories as desired by following the above pattern.
### Directory Permissions
The host directory should always be owned by the container user and group id. If this is not the case, files may not persist when written to mounted storage.
- Buildpacks via Herokuish: Use `32767:32767` as the file permissions
- For Cloud Native Buildpacks: This will depend on the builder in question, but can be retrieved via the `CNB_USER_ID` and `CNB_GROUP_ID` environment variables on the builder image. Common builders are as follows:
- heroku/buildpacks: `1000:1000`
- cloudfoundry/cnb: `2000:2000`
- packeto: `2000:2000`
- Dockerfile and Docker Image: Use the user and group id which corresponds to the one running the process within the container.
### Displaying storage reports for an app
> New as of 0.8.1
You can get a report about the app's storage status using the `storage:report` command:
```shell
dokku storage:report
```
```
=====> node-js-app storage information
Storage build mounts:
Storage deploy mounts: -v /var/lib/dokku/data/storage/node-js-app:/app/storage
Storage run mounts: -v /var/lib/dokku/data/storage/node-js-app:/app/storage
=====> python-sample storage information
Storage build mounts:
Storage deploy mounts:
Storage run mounts:
=====> ruby-sample storage information
Storage build mounts:
Storage deploy mounts:
Storage run mounts:
```
You can run the command for a specific app also.
```shell
dokku storage:report node-js-app
```
```
=====> node-js-app storage information
Storage build mounts:
Storage deploy mounts: -v /var/lib/dokku/data/storage/node-js-app:/app/storage
Storage run mounts: -v /var/lib/dokku/data/storage/node-js-app:/app/storage
```
You can pass flags which will output only the value of the specific information you want. For example:
```shell
dokku storage:report node-js-app --storage-deploy-mounts
```
## Use Cases
### Sharing storage across deploys
Dokku is powered by Docker containers, which recommends in their [best practices](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#containers-should-be-ephemeral) that containers be treated as ephemeral. In order to manage persistent storage for web applications, like user uploads or large binary assets like images, a directory outside the container should be mounted.
### Shared storage between containers
When scaling your app, you may require a common location to access shared assets between containers, a storage mount can be used in this situation.
### Shared storage across environments
Your app may be used in a cluster that requires containers or resources not running on the same host access your data. Mounting a shared file service (like S3FS or EFS) inside your container will give you great flexibility.
### Backing up
Your app may have services that are running in memory and need to be backed up locally (like a key store). Mount a non ephemeral storage mount will allow backups that are not lost when the app is shut down.
### Build phase
By default, Dokku will only bind storage mounts during the deploy and run phases. Under certain conditions, one might want to bind a storage mount during the build phase. This can be accomplished by using the `docker-options` plugin directly.
```shell
dokku docker-options:add node-js-app build "-v /tmp/python-test:/opt/test"
```
You cannot use mounted volumes during the build phase of a Dockerfile deploy. This is because Docker does not support volumes when executing `docker build`.
> Note: **This can cause data loss** if you bind a mount under `/app` in buildpack apps as herokuish will attempt to remove the original app path during the build phase.
## Application User and Persistent Storage file ownership (buildpack apps only)
> New as of 0.7.1
By default, Dokku will execute your buildpack application processes as the `herokuishuser` user. You may override this by setting the `DOKKU_APP_USER` config variable.
> NOTE: this user must exist in your herokuish image.
Additionally, the default `docker-local` scheduler that comes with Dokku will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`. See the [docker-local scheduler documentation](/docs/advanced-usage/schedulers/docker-local.md#disabling-chown-of-persistent-storage) docs for more information.