We removed our free Sandbox April 25th.
You can read more on our blog.

S3FS Shared Filesystem

Note

We’ve seen issues with the fuse libraries. We no longer recommend this type of configuration for production systems and suggest using a package like https://github.com/boto/boto

If you need to share files between multiple services (or between multiple instances of a scaled services), you can mount FUSE-based filesystems like S3FS or GlusterFS (just to name a few).

We will show here how you can use S3FS to access a S3 bucket from your dotCloud service.

Requirements

You will need your own S3 bucket in your own AWS account. Note that S3 is pretty cheap, and if you create a bucket in the default region, it will be in the same region as the main dotCloud cluster; meaning that you won’t have to pay for data transfer. You will mostly pay for storage, which amounts to pennies if your data is small.

The recipe described here only works for code services. It won’t work with MySQL, PostgreSQL, and Redis services.

Before starting, make sure that you have:

  • your S3 bucket name,
  • an AWS access key and secret key with full access to the bucket.

Also, your app should be using the Granite runtime. At the end of the build, if you see Waiting for the service to become responsive..., it means that you are using it. If you don’t see that line, it means that your app is still on the old builder and that you have to create a new app (since all new apps use Granite by default).

System Packages

We will need the FUSE userspace tools and libraries. While we could install them manually, it will be faster & easier to ask the dotCloud platform to install them for you!

Edit your dotcloud.yml file, and add a systempackages section similar to the following one:

www:
  type: php
  approot: src
  systempackages:
    - libfuse2
    - fuse-utils

The next time you will push your code, the platform will detect this section and install those packages for you.

S3FS binary and helper script

You will need to install the S3FS binary. You can install your own, or download our precompiled S3FS binary. Our version has only one slight difference: it skips some initial checks on the S3 bucket, allowing you to mount the bucket anyway when you don’t have the permission to list all the buckets. That way. you can create sets of credentials that have only read/write access to a bucket, and no other access, and use them with S3FS.

You will also need the S3FS script, which takes care of extracting the required parameters from the dotCloud environment.

Download both files (or use your own versions if you prefer), make sure that they are both executable (with chmod +x), and put them in your approot.

Put both files the S3FS binary in your approot.

Setup Supervisor

To make sure that the S3 bucket is mounted automatically, we will use a small Supervisor configuration file snippet. Create a supervisord.conf file in your approot, and insert the following section (if you already have a supervisord.conf file, no problem, just append the section):

[program:s3fs]
command=/home/dotcloud/current/run.s3fs
stdout_logfile=/var/log/supervisor/s3fs.log
stderr_logfile=/var/log/supervisor/s3fs.log

Configure S3FS

You will have to set the bucket name, AWS credentials, and desired mountpoint. To avoid having to store secure credentials along with your code (which might be in a shared or public repository), we will use the dotCloud environment variables. The following 4 variables should be set:

  • S3FS_BUCKET: name of the S3 bucket; you don’t need to include a s3:// prefix or anything like that.
  • S3FS_MOUNTPOINT: absolute path to which the bucket should be mounted this directory will be created automatically if it doesn’t exist. We suggest to use /home/dotcloud/store.
  • S3FS_ACCESSKEY: the AWS access key (it should be about 20 characters long).
  • S3FS_SECRETKEY: the AWS secret key (it should be about 40 characters long).

To set them, you will run a command like the following one:

$ dotcloud var set yourappname \
           S3FS_BUCKET=yourbucketname \
           S3FS_MOUNTPOINT=/home/dotcloud/store \
           S3FS_ACCESSKEY=AKI1234567ABCDEFGHIJ \
           S3FS_SECRETKEY=abcdefghij1234567890ABCDEFGHIJ+987654321

After pushing your app and setting the variables, your S3 bucket should be available. You can check that by logging in with dotcloud ssh and going to the mountpoint directory.

Custom Service

Note

The custom service is a beta feature. If you are not part of the beta group, you can safely ignore this section. Otherwise, if you started to use the custom service and want to add S3FS, read on – the procedure is slightly different.

If you are using a custom service (i.e., one that has type: custom in the dotcloud.yml), you should adapt two things.

First, you need to make sure that the builder script will copy your files with the rest of the code.

Next, since the custom service does not use supervisord.conf snippets, you will have to use a processes directory instead.

If your current custom service looks like this:

www:
  type: custom
  buildscript: foo/builder
  ports:
    www: http
  process: ~/run

You will have to make sure that foo/builder copies s3fs and run.s3fs in the target build directory, and update the dotcloud.yml to add systempackages and upgrade process to processes, as shown below:

www:
  type: custom
  buildscript: foo/builder
  ports:
    www: http
  process:
    foo: ~/run
    s3fs: ~/run.s3fs

Troubleshooting

The S3FS process logs are visible with dotcloud logs. If anything goes wrong, your best bet is to double-check your AWS credentials. Remember that all dotCloud services include s3cmd, a small and convenient S3 command-line client. Try s3cmd --configure and then s3cmd ls s3://nameofthebucket to see what happens. s3cmd is usually more informative than S3FS.

Note

There may be issues when connecting to s3 buckets with existing content. It may require re-creating the directories on the newly mounted directory for the existing data to appear. Before trying this suggested workaround, it is recommended that you backup your data.

http://code.google.com/p/s3fs/issues/detail?id=73