Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UploadServer 2

UploadServer 2 is a local-first, browser-based file transfer server for Debian and Linux. It gives a private directory a polished drag-and-drop interface for uploading, downloading, searching, sorting, previewing, and navigating files. The primary command is uploadserver2.

The server is designed for practical self-hosting: uploaded content remains under one configured directory, transfers are streamed, and a temporary public Cloudflare Quick Tunnel starts by default unless --no-tunnel is provided.

Features

Area Included behavior
Transfer Multiple uploads, drag-and-drop, browser progress, streamed writes, streamed downloads
File manager Recursive folders and files, file type, size, UTC-modified date, search, sort, refresh, empty/loading/error states
Transport Real HTTP/2-capable Hypercorn stack, HTTP/2 over TLS, HTTP/1.1 fallback, h2c support
Security Path traversal defenses, symlink rejection, opaque API identifiers, atomic temporary uploads, no delete operation
Access Optional HTTP Basic Authentication without hard-coded credentials
Operations Debian package, man page, unprivileged systemd service, default cloudflared tunnel, local or remote terminal client

Installation

The primary deliverable is uploadserver2_2.0.0_all.deb.

sudo apt install ./uploadserver2_2.0.0_all.deb

Using apt install ./...deb is recommended because apt resolves the package's Debian dependencies automatically. The package bundles its pure-Python runtime dependencies and only requires Debian system Python 3.11 or newer. No virtual environment or manual pip command is required after installation. For an already-installed package with the same version, use sudo apt install --reinstall ./uploadserver2_2.0.0_all.deb.

Browser and console clients

The same server URL works from either client mode. Start the server normally for the browser, or start it with --console for a local terminal UI; both modes expose the same HTTP service and the same Cloudflare URL. The browser is the easiest choice on a desktop:

cd /path/to/share
uploadserver2

On a headless VPS, connect to that URL from another machine without a desktop:

uploadserver2 --console https://your-random-name.trycloudflare.com

The remote console recursively lists folders and files and can stream any file type for download. Press u to upload a local VPS file, d to download the selected remote file, Enter or p to preview remote text/source files, r to refresh, and q to exit. A folder can be selected before pressing u to upload into that folder. For Basic Authentication, use --username and --password, or set UPLOADSERVER2_USERNAME and UPLOADSERVER2_PASSWORD.

Usage

uploadserver2                         # port 8080, Cloudflare tunnel enabled
uploadserver2 --no-tunnel              # local-only port 8080
uploadserver2 -P 9000 --no-tunnel      # local-only custom port
uploadserver2 -P 8080                  # custom spelling of the default port
uploadserver2 --console --no-tunnel     # terminal UI, local-only
uploadserver2 --console URL              # terminal client for a remote server
uploadserver2 --help
uploadserver2 --version

When you run uploadserver2 interactively, it serves the exact directory you are currently in, just like a simple Python HTTP server. Existing files and every nested subdirectory beneath that directory appear recursively in the web interface. New uploads go to the launch directory by default; select a displayed folder's Upload here action to target a nested directory. To choose another root, pass --directory PATH. The systemd unit explicitly uses /var/lib/uploadserver2/files and runs as the dedicated uploadserver2 user.

The default port is 8080. A normal uploadserver2 launch downloads the official GitHub cloudflared binary to ~/.local/bin/cloudflared if it is not already installed, then prints a temporary public URL. Use --no-tunnel for local-only operation. Add --console to open the terminal UI while the browser server continues running.

Useful options include:

--host HOST              listen address
--port PORT              listen port
--directory PATH         upload directory
--config PATH            TOML configuration file
--cert PATH              PEM TLS certificate
--key PATH               PEM TLS private key
--auth                   enable Basic Authentication
--max-size SIZE          per-file limit, such as 500MB or 10GB
--log-level LEVEL        DEBUG, INFO, WARNING, or ERROR

CLI values override the configuration file. A positional port such as uploadserver2 8080 is equivalent to --port 8080.

HTTP/2 and TLS

UploadServer 2 uses a real HTTP/2-capable ASGI server. For browser-friendly HTTPS and HTTP/2, provide both a certificate and private key:

uploadserver2 8443 --cert server.crt --key server.key --directory "$HOME/Uploads"

For local development, a self-signed certificate can be generated with OpenSSL:

openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
  -keyout server.key -out server.crt -subj '/CN=localhost'

Browsers will display a trust warning for a self-signed certificate. Without TLS, the server supports HTTP/1.1 and HTTP/2 cleartext (h2c) for clients that negotiate it; ordinary browsers generally use the HTTP/1.1 fallback.

Authentication

Authentication protects the GUI, file list, uploads, downloads, previews, and all API routes. Credentials are never hard-coded and passwords are never logged.

Set credentials in the environment and enable authentication:

export UPLOADSERVER2_USERNAME=alice
export UPLOADSERVER2_PASSWORD='use-a-long-random-password'
uploadserver2 8080 --auth

They may also be placed in /etc/uploadserver2/config.toml, although environment variables are preferable for secrets. Authentication uses HTTP Basic Authentication, so use TLS when credentials must cross an untrusted network.

Free Cloudflare Tunnel

Tunnel mode is enabled by default. Cloudflare Quick Tunnels provide a free, temporary public URL for testing without requiring a Cloudflare account. Cloudflare documents the feature at try.cloudflare.com and in its Quick Tunnel documentation. Quick Tunnels are intended for testing and development, not production hosting.

When tunnel mode starts, UploadServer first checks for cloudflared. If it is missing, it downloads the official architecture-matched binary from the Cloudflare GitHub releases to ~/.local/bin/cloudflared, marks it executable, and starts it without requiring root. You can also install it yourself from Cloudflare's official Linux downloads page.

Run UploadServer from the directory you want to share:

cd /path/to/my-files
export UPLOADSERVER2_USERNAME=shareuser
export UPLOADSERVER2_PASSWORD='use-a-long-random-password'
uploadserver2 -P 8080 --auth

UploadServer runs the official Quick Tunnel command cloudflared tunnel --url http://127.0.0.1:8080, prints the generated https://....trycloudflare.com public URL, and stops cloudflared when the server exits. Anyone with that URL can reach the file server, so use --auth, share the URL carefully, and stop the process when finished. Use --no-tunnel if you only want local access.

Configuration

The Debian package ships /etc/uploadserver2/config.toml:

[uploadserver2]
host = "127.0.0.1"
port = 8080
directory = "/var/lib/uploadserver2/files"
cert = ""
key = ""
auth = false
username = ""
password = ""
max_size = "10GB"
log_level = "INFO"
tunnel = true

Security model

The API never accepts raw filesystem paths. File identifiers are URL-safe opaque encodings of a single filename. Upload names are reduced to a basename, NUL bytes are removed, resolved paths are required to remain below the configured directory, and symlinks are rejected. Uploads land in a random hidden .part file and are atomically renamed only after the complete transfer and size validation. Download responses use file streaming, and the frontend treats names as text rather than injecting untrusted HTML.

Bind to 127.0.0.1 for local use. If binding to all interfaces or using --tunnel, apply authentication, TLS, network controls, and a carefully chosen upload directory. Uploaded files are treated as data and are never executed by UploadServer 2.

systemd

The package installs an optional unit but does not enable it automatically. It intentionally passes the Debian configuration explicitly, so the service continues to use /var/lib/uploadserver2/files rather than the invoking user's ~/Uploads directory:

sudoedit /etc/uploadserver2/config.toml
sudo systemctl enable --now uploadserver2.service
journalctl -u uploadserver2.service -f

The service runs as the dedicated unprivileged uploadserver2 user and writes to /var/lib/uploadserver2/files. It is configured to restart after failure, use journald, and avoid broad filesystem writes.

Debian package build

Install Debian packaging tools, then run:

dpkg-buildpackage -us -uc

The resulting package is uploadserver2_2.0.0_all.deb. The source tree contains all Python source, vendored runtime files, maintainer scripts, the systemd unit, man page, default configuration, and .gitignore needed for a reproducible build. No network access or manual pip command is required for the Python runtime dependencies.

From a fresh Debian/Ubuntu build machine:

sudo apt update
sudo apt install -y build-essential debhelper devscripts dpkg-dev python3
cd uploadserver2
dpkg-buildpackage -us -uc
sudo apt install ../uploadserver2_2.0.0_all.deb

The Debian package itself declares the system packages needed at install time. The optional first-run cloudflared bootstrap is separate: if cloudflared is missing, UploadServer downloads the architecture-matched official GitHub release into the invoking user's ~/.local/bin directory.

Troubleshooting

If a port is already in use, choose another port such as uploadserver2 -P 9090. If the configured directory cannot be created or written, select a directory owned by the running user. TLS requires both --cert and --key, and both files must exist. Authentication requires credentials in configuration or UPLOADSERVER2_USERNAME and UPLOADSERVER2_PASSWORD. If the default tunnel cannot connect, check outbound HTTPS and Cloudflare Tunnel connectivity, or run with --no-tunnel for local testing.

For command details, run man uploadserver2 after installation.

About

A self-hosted HTTP/2 file server with a polished web interface, recursive directory browsing, streamed uploads/downloads, terminal and remote console clients, text previews, Basic Authentication, and optional Cloudflare Quick Tunnel support.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages