A simple file sharing app allows users to upload and share files.
Project URL: FileStashes
- A user can upload and share files.
- Sharing links are randomly generated.
- Sharing links will expire (in 1 hour).
The following tools are developed based on the following versions. Other versions may work but not tested.
- Ruby version: 3.2.2
- Rails version: 7.1.2
-
Starting from Rails 7,
vipsbecomes the default variant processor. If you are using MacOS, you may need to installvipsmanually. See this issue and referencebrew install vips
-
To show preview of PDF and video files, you need to install
popplerandffmpegmanually. See referencebrew install poppler ffmpeg
-
Check out the repository
git clone git@github.com:absoluteyl/file-stashes.git
-
Install dependencies
bundle install
-
Generate master key and credentials
# Generate master key EDITOR=echo rails credentials:edit -
We use dotenv to manage environment variables. Copy
.envfrom example and fill in required values for your own environment.cp .env.example .env
-
Create and setup the database
rails db:setup
-
Start the Rails server
rails s
-
Build docker image
docker build -t file-stashes:latest . -
Generate self-signed ssl certificate using mkcert
# (Optional) If you don't have mkcert installed, install it first: brew install mkcert # (Optional) Install root certificate after installation mkcert -install # Generate certificate for domain "docker.localhost" and their sub-domains mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem "docker.localhost" "*.docker.localhost"
-
Copy
docker-compose.ymlfrom examplecp docker-compose.yml.example docker-compose.yml
-
Run docker containers
# (Optional) add -d to run in background docker-compose up
As shown in the following diagram, the app is composed of 4 components:
- App: A rails app that provides web interface for users to upload and share files.
- Storage: AWS S3 bucket that stores files uploaded by users.
- Database: A MySQL database that stores metadata of files.
- Cache: A Redis instance that stores sharing links and their expiration time.
Above diagram also shows the flow of uploading and sharing a file. Rails' native storage library - ActiveStorage provides an interface to flexible switch between storage services like AWS S3, Google Storage or Azure Blob. In this case, we use AWS S3 as the storage service for it's remarkable SLA. While uploading a file, ActiveStorage will also store metadata of the file to the MySQL.
After the file is been uploaded, user can generate a temporary share link to the file. The share link is composed by a random generated token of 16 hex characters. This token is stored in Redis with expiration time of 1 hour. When another user visits the share link, the app will check if the token exists in Redis. If it exists, the app will redirect the user to the file detail page where user can preview or download the file. Otherwise, the app will return 404 error.
Since the app is been dockerized, it's easy to scale in/out the app horizontally by workload. We can use a load balancer to distribute the traffic to multiple app instances. The app instances can share the same database and cache instance. To reduce the data transfer cost of storage, we can also use a CDN to cache the files to avoid constantly fetching files from S3.
