A simple light-weight file upload and file sharing tool
Find a file
2026-01-23 18:18:37 +00:00
.github chore(deps): bump actions/checkout from 5 to 6 2026-01-02 09:45:47 +00:00
crates chore: load data concurrently 2026-01-23 18:18:37 +00:00
cypress feat: add team settings E2E tests 2025-07-27 13:38:01 +01:00
etc fix: add file extension to ffmpeg command 2025-07-28 14:45:54 +01:00
media chore: update screenshot used in README 2024-08-12 15:46:00 +01:00
.dockerignore fix: clean up docker ignores 2025-07-28 13:26:33 +01:00
.gitignore chore: split into separate crates 2025-07-23 13:03:36 +01:00
.ignore chore: split into separate crates 2025-07-23 13:03:36 +01:00
bacon.toml chore: split into separate crates 2025-07-23 13:03:36 +01:00
Cargo.toml fix: remove unused Cargo.toml declaration 2025-07-28 15:34:59 +01:00
Dockerfile feat: gate LibreOffice behind a feature and add two images 2025-07-28 13:26:33 +01:00
LICENSE Initial commit 2023-10-14 10:36:18 +00:00
README.md chore: add next milestone percentage 2025-08-05 13:29:11 +01:00

parcel A simple file upload tool

Screenshot of Parcel after a successful upload

GitHub Release GitHub License Check Deploy Next release milestone

Parcel is a simple light-weight file upload application with a nice UI and a small set of features.

  • Support multiple users and administrators, including MFA
  • Users can be grouped into teams, with shared uploads
  • Uploaded files can be made public to allow download from anywhere
  • Number of downloads can be limited, and downloads can have an expiry date
  • Public downloads can be password protected
  • Files are stored in separate cache directory
  • Data is stored in an SQLite database
  • Written in Rust using the Poem web framework
  • Styled using Tailwind CSS
  • Using Preact and Web Components

Running Parcel

The easiest way to run Parcel is with Docker, using the blakerain/parcel image on Dockerhub:

docker run blakerain/parcel

Parcel can be controlled through arguments or environment variables. The environment variables are a useful way to control Parcel when creating a Docker container.

Environment Name Default Description
DB sqlite://parcel.db SQLite connection string
CACHE_DIR ./cache Directory for file cache
COOKIE_SECRET Secret used for session cookie encryption
ANALYTICS_DOMAIN Domain to use for analytics script
PLAUSIBLE_SCRIPT URL for Plausible Analytics script

For example, if you had created a volume parcel_data and mounted it under /data you could tell Parcel to store the DB and file cache in that location by setting the DB environment variable to sqlite:///data/parcel.db and CACHE_DIR to /data/cache.

If you do not set the COOKIE_SECRET, you will end up being logged out every time that the container starts. To mitigate this, pass a value for COOKIE_SECRET when starting the container.

docker run -d \
  --name my-parcel \
  -e DB=sqlite:///data/parcel.db \
  -e CACHE_DIR=/data/cache \
  -e COOKIE_SECRET=$(openssl rand -base64 32 | tr -d '\n' ; echo) \
  -e ANALYTICS_DOMAIN=parcel.example.com \
  -e PLAUSIBLE_SCRIPT=https://pa.example.com/js/script.js \
  -v parcel_data:/data

Development

When running as a development server, bacon is mighty helpful. You may also wish to set up a cookie key (in the COOKIE_SECRET environment variable) to avoid being signed out after a restart:

# Initial setup of a cookie key
COOKIE_SECRET=$(openssl rand -base64 32 | tr -d '\n' ; echo)
export COOKIE_SECRET

# Run the server, but recompile/restart on any changes
bacon

Please Note: The icon used for this application is the package-open icon from the Lucide icon pack.