How to Self-Host PicoShare with Docker Compose
What Is PicoShare?
PicoShare is a minimalist, self-hosted file sharing service. Upload a file, get a shareable link with optional expiry. That’s it — no accounts for recipients, no complicated configuration, no JavaScript frameworks. Just a Go binary, a SQLite database, and a clean web UI.
PicoShare is built by Michael Lynch (mtlynch), known for writing clear, well-engineered software. It’s designed for simplicity: one container, one volume, one environment variable to get started. It replaces quick file sharing needs without the overhead of a full platform like Nextcloud.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 256 MB of free RAM (minimum)
- Disk space for uploaded files
- A domain name (optional but recommended)
Docker Compose Configuration
Create a directory for PicoShare:
mkdir -p ~/picoshare && cd ~/picoshare
Create a docker-compose.yml file:
services:
picoshare:
image: mtlynch/picoshare:1.4.2
container_name: picoshare
ports:
- "127.0.0.1:4001:4001"
environment:
# Shared secret for authentication — CHANGE THIS
PS_SHARED_SECRET: ${PS_SHARED_SECRET}
# Port (default 4001)
PORT: "4001"
volumes:
- picoshare-data:/data
restart: unless-stopped
volumes:
picoshare-data:
Create a .env file:
# CHANGE THIS — use a strong passphrase or generate with: openssl rand -hex 24
PS_SHARED_SECRET=change_me_to_a_strong_secret
Start the stack:
docker compose up -d
Initial Setup
- Open
http://your-server-ip:4001in your browser. - Enter the shared secret you configured in
PS_SHARED_SECRETto authenticate. - Upload a file via the web UI.
- Copy the generated link and share it — recipients don’t need to authenticate.
No user accounts, no setup wizard. The shared secret is the admin password.
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
PS_SHARED_SECRET | (required) | Authentication passphrase for the admin UI |
PORT | 4001 | Server listen port |
PicoShare is intentionally minimal on configuration. File expiry is set per-upload through the web UI — there’s no global default.
Upload Options
When uploading a file, you can set:
- Expiry: Never, or a specific time (1 hour to 1 year)
- Label: Optional human-readable name for the link
- Guest links: Create temporary upload URLs for others to upload files to your instance
Guest Upload Links
PicoShare supports guest upload links — generate a temporary URL that allows someone to upload files to your instance without knowing the shared secret:
- Log in to PicoShare
- Click Guest Links → Create
- Set an expiry and optional upload limit
- Share the guest link — the recipient can upload files through it
Reverse Proxy
Behind Caddy (Reverse Proxy Setup):
share.example.com {
reverse_proxy localhost:4001
}
For large file uploads, ensure your reverse proxy doesn’t impose a body size limit. Caddy has no limit by default. For Nginx, add client_max_body_size 0; to disable the limit.
Backup
PicoShare stores everything (database + files) in a single SQLite database at /data:
# Backup the data volume
docker run --rm -v picoshare-data:/data -v $(pwd):/backup alpine \
tar czf /backup/picoshare-backup-$(date +%Y%m%d).tar.gz /data
See Backup Strategy for a complete approach.
Troubleshooting
Authentication fails
Symptom: Entering the shared secret returns “invalid credentials.”
Fix: Ensure PS_SHARED_SECRET is set correctly in your .env file. The value is case-sensitive. Restart the container after changes: docker compose up -d.
Large file uploads fail
Symptom: Uploads over a few hundred MB fail or timeout.
Fix: PicoShare itself has no upload limit. Check your reverse proxy — Nginx defaults to 1 MB body size. Set client_max_body_size 0; for unlimited. Also check for timeout settings on the proxy.
Files not persisting after restart
Symptom: Uploaded files disappear when the container restarts.
Fix: Ensure the picoshare-data volume is configured correctly. Don’t use docker compose down -v (the -v flag deletes volumes).
Resource Requirements
- RAM: ~20-50 MB idle
- CPU: Low
- Disk: ~20 MB for the application, plus storage for uploaded files (embedded in SQLite)
Verdict
PicoShare is the most minimal file sharing tool you can self-host. One container, one env var, zero dependencies. It’s perfect for quick “here’s a file” sharing without the overhead of Send (which adds Redis and end-to-end encryption) or Zipline (which adds PostgreSQL and a full dashboard).
The trade-off is features — no end-to-end encryption, no ShareX integration, no multi-user support. If you need those, look at Send or Zipline. If you just want to share files with minimal setup, PicoShare is hard to beat.
Frequently Asked Questions
Does PicoShare encrypt files?
No. Files are stored unencrypted in the SQLite database. For end-to-end encryption, use Send.
Can multiple people share files through PicoShare?
There’s one shared admin account (via the shared secret). Guest upload links let others upload without the admin password, but there’s no multi-user management.
How large can uploaded files be?
PicoShare has no built-in file size limit. The constraint is your server’s disk space and any reverse proxy limits.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments