No description
  • HTML 68%
  • Python 31.5%
  • Dockerfile 0.5%
Find a file
carson 0ef01a43ee
Some checks failed
Docker / build (push) Failing after 23s
docker fix fix fix fix
2026-05-12 20:30:44 -04:00
.forgejo/workflows docker fix fix fix fix 2026-05-12 20:30:44 -04:00
Images fixed readme 2026-02-18 17:51:04 -05:00
webpage added title and switched to jninja 2026-02-17 21:08:29 -05:00
.dockerignore fixed docker deployment 2026-02-17 22:16:41 -05:00
.env.example fixed docker deployment 2026-02-17 22:16:41 -05:00
.gitignore fixed docker deployment 2026-02-17 22:16:41 -05:00
build.log fixed docker deployment 2026-02-17 22:16:41 -05:00
Dockerfile fixed docker deployment 2026-02-17 22:16:41 -05:00
entrypoint.py fixed docker deployment 2026-02-17 22:16:41 -05:00
README.md Update README.md 2026-02-24 22:59:14 +00:00
requirements.txt fixed docker deployment 2026-02-17 22:16:41 -05:00
start.py fixed docker deployment 2026-02-17 22:16:41 -05:00

Here To There

title

Here To There is a small self-hosted file handoff app. Upload a file on one device, share a short code, and download it on another device.

What It Does

  • Browser upload and download flow
  • Short retrieval code format: ID-CHECKSUM (example: 12-ABCD)
  • Files encrypted at rest with Fernet
  • QR code generation for quick mobile retrieval
  • Automatic cleanup of old uploads

Important Security Notes

This project is for personal or trusted-network use.

  • Anyone with a valid code can download the file.
  • Run behind HTTPS if exposed outside your LAN.
  • Use a strong random CHECKSUM_SECRET.
  • Use a valid Fernet ENCRYPTION_KEY.
  • For sensitive files, consider additional client-side encryption before upload.

Requirements

  • Python 3.10+
  • Dependencies from requirements.txt

Configuration (.env)

Create .env in the project root (or copy .env.example):

DOMAIN=http://localhost:8170
PORT=8170
CLEAR_TIME_MINUTES=10
MAX_FILE_SIZE_MB=100
CHECKSUM_SECRET=REPLACE_WITH_LONG_RANDOM_SECRET
ENCRYPTION_KEY=REPLACE_WITH_VALID_FERNET_KEY
TITLE=Here to There

Config Fields

  • DOMAIN: Public base URL used to generate download links.
  • PORT: Flask server port.
  • CLEAR_TIME_MINUTES: Minutes before old upload folders are deleted.
  • MAX_FILE_SIZE_MB: Maximum allowed upload size in MB.
  • CHECKSUM_SECRET: Secret used to generate and validate code checksums.
  • ENCRYPTION_KEY: Fernet key used to encrypt/decrypt file contents.
  • TITLE: App title shown on the homepage.

Generate a Fernet key for the ENCRYPTION_KEY:

python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Run Locally

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python start.py

Open http://localhost:8170.

Run With Docker

  1. Pull the image:
docker pull git.carsonmayn.com/carson/heretothere:latest
  1. Generate a Fernet key for the ENCRYPTION_KEY:
pip install cryptography
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
  1. Set config fields in the enviromental variables.
docker run git.carsonmayn.com/carson/heretothere:latest \
-e DOMAIN="example.com" \
-e PORT="8080" \
-e CLEAR_TIME_MINUTES="10" \
-e MAX_FILE_SIZE_MB="100" \
-e CHECKSUM_SECRET = "jriohgeoihhwyvshdv" \
-e ENCRYPTION_KEY = "wouvuwudvowuvcosyudv" \
-e TITLE = "My Heretothere Instance"

The container reads config from environment variables and persists files in ./uploads.

How Storage Works

Uploads are stored under uploads/<id>/:

  • data.enc: Encrypted file payload
  • meta.json: Metadata (currently filename)

Older plaintext upload folders are still downloadable for backward compatibility.

Project Structure

  • start.py: Flask app and upload/download logic
  • webpage/: HTML templates
  • uploads/: Runtime file storage
  • .env.example: Config template
  • dockerfile, docker-compose.yml: Container setup

Troubleshooting

  • Invalid ENCRYPTION_KEY:
    • Set ENCRYPTION_KEY to a valid Fernet key.
  • Upload rejected as too large:
    • Increase MAX_FILE_SIZE_MB in .env.
  • QR endpoint returns invalid domain:
    • Ensure DOMAIN matches the URL users actually access.