The file system of application containers are ephemeral. Any application data or files stored locally within these containers is lost when the instance is stopped or restarted. To solve this, Helion Stackato provides a ‘filesystem’ service that can be shared between application instances, and even between applications deployed to the same space.
A persistent file system service allows apps to do the following:
A filesystem service can be configured in your manifest.yml file:
services:
mydata: filesystem
You can also run the stackato create-service command:
$ stackato create-service filesystem mydata
Creating Service: OK
$ stackato services
=========== Provisioned Services ============
+----------------+------------+
| Name | Service |
+----------------+------------+
| mydata | filesystem |
+----------------+------------+
Note
File system service is available during pre-staging and should not need to be reconfigured when the application starts.
The filesystem service creates a path which your app can use to store and read files.
If there is only one filesystem service, the STACKATO_FILESYSTEM environment variable can
be used to get the path.
If there is more than one filesystem service, STACKATO_FILESYSTEM is not available.
Instead, a custom environment variable STACKATO_FILESYSTEM_* will be created based on the
name of each filesystem service (with hyphens replaced by underscores).
For example, if your manifest.yml file configures the following services:
services:
my-data: filesystem
plugins: filesystem
Two environment variables would be created:
STACKATO_FILESYSTEM_MY_DATA and STACKATO_FILESYSTEM_PLUGINS.
This naming scheme can be used in conjunction with the
STACKATO_APP_NAME_UPCASE environment variable. For example, in an
app with the following filesystem service defined:
services:
${name}-foo: filesystem
${name}-bar: filesystem
The filesystem mount point for the "foo" filesystem service can be accessed within the container using constructs such as:
FOO=STACKATO_FILESYSTEM_${STACKATO_APP_NAME_UPCASE}_FOO
mkdir ${!FOO}/myapp
Note
To use declarations like these in the hooks: key, put them in a separate bash script. Brace expansion and grouping cannot be used directly in YAML files.
Alternatively, STACKATO_SERVICES contains information for all services:
{
"plugins": {
"dir": "/home/stackato/fs/plugins"
},
"my-data": {
"dir": "/home/stackato/fs/my-data"
},
"mydb": {
"name": "db76e25bc8fc142858653a6cb8c643204",
"hostname": "192.168.0.112",
"host": "192.168.0.112",
"port": 3306,
"user": "u7Fjl8hdb4iNu",
"username": "u7Fjl8hdb4iNu",
"password": "p4XQAhZr8xfHg"
}
}
Because the environment variables are available during the staging process, it is possible to make use of them in the manifest.yml file to configure a filesystem service and create a symlink to it for use by the app. (see example below)
Note
When linking the file system service to the application, using symlinks is strongly recommended.
You can customize a WordPress deployment to use a persistent file system. Before you begin, find out
where all the user generated contents are saved. You may have to make modifications to this general
approach if your application stores user generated content in more than one location. In WordPress,
they are stored in the wp-content directory.
Add the following blocks to manifest.yml:
services:
fs-wp: filesystem
hooks:
post-staging:
# create wp-content in the shared filesystem
- mkdir -p "$STACKATO_FILESYSTEM"/wp-content
# migrate existing wp-content data into the shared filesystem
- mv wp-content/* "$STACKATO_FILESYSTEM"/wp-content
# remove unused wp-content directories
- rm -rf wp-content
# link to wp-content directory in the shared filesystem
- ln -s "$STACKATO_FILESYSTEM"/wp-content wp-content
Note
When moving files onto the mounted filesystem with a mv hook,
you may see an error message similar to:
mv: failed to preserve ownership for... Permission denied
This is a misleading warning, because the files will actually be moved with the correct permissions and ownership.