Andreas Reinhold / reiniandClaude Opus 5 c95d0c43c2
linter / quality (push) Successful in 1m7s
tests / ci (8.5) (push) Successful in 2m16s
docker / build-and-push (push) Successful in 7m5s
docker / test (8.5) (push) Successful in 2m25s
docker / release (push) Successful in 5s
Load the website's Plausible site script
Plausible gives each new site its own script and an init call instead
of the generic script with data-domain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 16:21:51 +02:00
2026-07-23 11:16:59 +02:00
2026-07-23 11:16:59 +02:00
2026-02-12 16:11:57 +01:00
2026-02-12 16:11:57 +01:00
2026-02-12 16:11:57 +01:00
2026-02-12 16:11:57 +01:00
2026-09-13 15:06:47 +02:00
2026-02-12 16:11:57 +01:00

SealShare

A simple, self-hosted file sharing solution built with Laravel. Upload files, get a shareable link, done. All files are encrypted at rest with AES-256-GCM.

Website: sealshare.nonameweb.ch

Screenshots

Uploading files and folders with share options A new share with its link and QR code button

The recipient's download page on a phone

Features

  • File Uploading — Drag & drop or browse to upload single/multiple files and folders with real-time progress
  • Shareable Links — Each upload generates a unique link for recipients, also as a QR code (saved as a PNG) or through the device's share sheet
  • Encryption at Rest — Files are encrypted on the server as they arrive, with AES-256-GCM (chunked, streaming); with a share password the key is derived from it and never stored. It is not end-to-end encryption: the server handles the files unencrypted while they are uploaded and downloaded
  • Password Protection — Optionally protect shares with a password
  • Expiration — Shares auto-expire after a configurable duration (1 hour to 30 days)
  • Download Limits — Set a maximum number of downloads per share
  • ZIP Downloads — Download all files in a share as a single ZIP archive
  • Auto-Cleanup — Expired shares and files are automatically deleted (hourly)
  • Admin Dashboard — View, manage, and delete all shares
  • Admin Settings — Configure upload limits, storage quotas, branding, and more
  • Site Branding — Custom logo, title, and description
  • Colour Profiles — Eight Material 3 colour profiles (Indigo, Blue, Teal, Green, Amber, Rose, Violet, Graphite); the admin picks one for every page, mail and error page
  • System Password — Optional global password gate to restrict upload access
  • User Authentication — Login, password reset, email verification
  • Two-Factor Authentication — TOTP-based 2FA via Laravel Fortify
  • Light and Dark Themes — Material 3 Expressive design that follows the system theme, or light or dark by choice
  • Setup Wizard — First-run wizard to create the initial admin account

Tech Stack

Layer Technology
Framework Laravel 13
Application Server FrankenPHP (via Laravel Octane)
Frontend Livewire 4, Tailwind CSS 4, Livewire Material (Material 3 Expressive)
Authentication Laravel Fortify
Encryption Chunked AES-256-GCM with PBKDF2-SHA256 key derivation
ZIP Downloads Native PHP ZipArchive
Testing Pest 5 with browser tests (Playwright)
Code Style Laravel Pint
Build Tool Vite

Installation — Development

# Build and start the dev container
docker compose -f docker-compose.dev.yml up -d --build

# View logs (including Vite output)
docker compose -f docker-compose.dev.yml logs -f

The app is available at http://localhost:8000 with Vite HMR on port 5173.

Installation — Production

mkdir sealshare && cd sealshare
curl -O https://gitea.nonameweb.ch/noNameWEB/SealShare/raw/branch/main/docker-compose.example.yml
cp docker-compose.example.yml docker-compose.yml

# Generate an app key and paste it into docker-compose.yml
docker run --rm gitea.nonameweb.ch/nonameweb/sealshare:latest php artisan key:generate --show

# Edit docker-compose.yml — set APP_KEY, APP_URL, and SERVER_NAME
# Then start:
docker compose up -d

Migrations run automatically on startup. Open your configured domain — the Setup Wizard will create the first admin account.

Key environment variables:

Variable Required Description
APP_KEY Yes Laravel encryption key
APP_URL Yes Full URL (e.g. https://share.example.com)
SERVER_NAME Yes Domain for auto-TLS (e.g. share.example.com)

Volumes:

Volume Path Purpose
sealshare_storage /app/storage/app Encrypted uploaded files
sealshare_database /app/database SQLite database
caddy_data /data TLS certificates
caddy_config /config Caddy configuration

Large files:

Uploads beyond the defaults need these limits raised together:

Limit Where Default
PHP_UPLOAD_MAX_FILESIZE / PHP_POST_MAX_SIZE Environment 4G — hard cap per file / per upload batch
Max file size / Max size per share Admin → Settings 100 MB / 2 GB
LIVEWIRE_MAX_UPLOAD_TIME Environment 30 minutes per upload
OCTANE_MAX_EXECUTION_TIME / PHP_MAX_EXECUTION_TIME Environment 300 seconds — encrypting a large file takes a while

Behind a reverse proxy, raise its request body limit and read timeout as well (nginx: client_max_body_size, proxy_read_timeout).

Manual (without Docker)

git clone https://gitea.nonameweb.ch/noNameWEB/SealShare.git
cd SealShare

composer install --no-dev --optimize-autoloader
npm install && npm run build

cp .env.example .env
php artisan key:generate

# Edit .env — set APP_ENV=production, APP_DEBUG=false, APP_URL=https://your-domain.com

touch database/database.sqlite
php artisan migrate --force
php artisan storage:link

php artisan config:cache
php artisan route:cache
php artisan view:cache

Start with Octane:

php artisan octane:frankenphp --host=0.0.0.0 --port=80

Or point your web server (Nginx/Apache) to the public/ directory for a traditional PHP-FPM setup.

Add the scheduler to your crontab:

* * * * * cd /path-to-sealshare && php artisan schedule:run >> /dev/null 2>&1

License

This project is open-source software licensed under the MIT License.

S
Description
No description provided
Readme MIT
2.6 MiB
v2.0.1
Latest
2026-09-13 15:59:35 +00:00
Languages
PHP 47.9%
CSS 27.9%
HTML 11.6%
Blade 9.8%
JavaScript 1.9%
Other 0.9%