Skip to content

Configuring a shared folder for file uploads

Joost Baaij edited this page Nov 3, 2017 · 1 revision

Often when images, audio, and video are uploaded some processing needs to happen in the background. Since this can potentially take a long time, this is something for a background worker. However, since uploads are initially stored in a single directory on a single disk, this creates a problem when you have more than one server running Pageflow.

Since the background worker needs to manipulate files created on a different server, you need a way to connect the two. The most reliable setup for this is a shared folder that both servers can use. Create it, mount it on each server and then update the Pageflow configuration with the location of the folder.

This does not affect you if you run Pageflow on a single server.

Amazon

On AWS you need to create an Elastic File System (EFS).

When you click Create file system in the AWS console, you're greeted with fairly detailed instructions. Choose the correct VPC and all its Availability Zones, give the EFS a Name and other attributes you need. Encryption is not needed nor useful.

When you accept all defaults, your EFS is created under one single Security Group. This is undesirable. Luckily AWS shows the correct instructions after creation as well. You need two Security Groups; one to SSH into the servers and one access control for the mount targets.

After you've created the Security Group(s) with the firewall rules shown, you still need to to back to both the EC2 instances and the EFS Mount Targets to manually assign these groups to the resources. To do this, click the Action dropdown, choose Networking, then Change Security Groups.

Mounting

Copy and paste the instructions that Amazon gives you. Preferably you don't actually paste the commands into your server's terminal, but use an orchestration tool like Chef or Puppet. This way the changes you're proposing are documented and can even be rolled back.

sudo yum install -y nfs-utils # Red Hat
sudo apt-get install nfs-common # Ubuntu

sudo mkdir -p /efs/uploads # or any other directory you want to use

Then mount the file system using the DNS name. Note that /efs is the mount point and uploads is the directory you want to use for uploads. (After all, shared file systems have many more useful functions)

The directory needs to writeable by different processes, so group permissions are the way to go.

Let's assume the files are created by user nginx and the jobs are running as job. Both users are part of the app_writers group. That will be our ticket out of here:

cd /efs
sudo chown nginx uploads
sudo chgrp app_writers uploads
sudo chmod ug+rwx uploads
sudo chmod g+s uploads # this makes the group permissions apply to all subdirectories created afterwards

You're done!

Change the value in the Pageflow configuration, and restart all Rails servers.

config.paperclip_filesystem_root = '/efs/uploads'
# an environment variable arguably is an even better idea:
config.paperclip_filesystem_root = ENV['PAPERCLIP_FILESYSTEM_ROOT']