Self-Hosting Pingvin Share: WeTransfer Alternative with Docker
You need to send a large file to someone. WeTransfer caps free transfers at 2 GB. Google Drive wants your firstborn child’s data. Dropbox links expire at inconvenient times. And you’re already running a home server — so why not host your own file sharing platform?
Pingvin Share is a self-hosted, open-source file sharing platform that does exactly what WeTransfer does, but on your hardware, with your rules, and no file size limits beyond your disk space.
Why Pingvin Share
The self-hosted file sharing space has a few options — FileBrowser, ProjectSend, Nextcloud’s sharing feature. Here’s what makes Pingvin Share stand out:
- Dead simple — One container, one volume mount. You’re up in under a minute.
- No file size limits — Share as much as your disk can hold. No arbitrary caps.
- Expiration dates — Set shares to auto-expire after hours, days, or weeks.
- Password protection — Lock shares behind passwords for sensitive files.
- Visitor limits — Restrict how many times a share link can be accessed.
- Reverse shares — Let others upload files to you through a secure link — perfect for collecting documents.
- Email notifications — Automatically email recipients when a share is ready.
- ClamAV integration — Scan uploaded files for malware automatically.
- S3 storage — Store files on S3-compatible storage (MinIO, Backblaze B2, AWS) instead of local disk.
- OIDC and LDAP — Integrate with your existing authentication stack (Authentik, Authelia, Keycloak).
- Clean UI — Modern, responsive interface that doesn’t look like it was built in 2008.
The trade-off: Pingvin Share is focused purely on temporary file sharing. If you need permanent file storage, collaboration, or document editing, look at Nextcloud. But for “send this file to that person” workflows, Pingvin Share is lighter and simpler.
Note on project status: The original developer has shifted focus to Pocket ID and is no longer actively maintaining Pingvin Share. The project is stable, functional, and open to community forks. For a file sharing tool, stability matters more than frequent updates — the core functionality works well as-is.
Prerequisites
- A Linux server with Docker and Docker Compose installed
- At least 512 MB of free RAM
- Sufficient disk space for your shared files
- A domain name if you want external access with HTTPS
Step 1: Create the Project Directory
mkdir -p ~/docker/pingvin-share && cd ~/docker/pingvin-share
Step 2: Create the Docker Compose File
Create a docker-compose.yml file:
services:
pingvin-share:
image: stonith404/pingvin-share
container_name: pingvin-share
restart: unless-stopped
ports:
- "3000:3000"
environment:
- TRUST_PROXY=false
volumes:
- "./data:/opt/app/backend/data"
- "./data/images:/opt/app/frontend/public/img"
That’s it. Seriously. One service, two volume mounts.
Step 3: Start Pingvin Share
docker compose up -d
Wait a few seconds, then open http://your-server-ip:3000 in your browser.
The default admin credentials are:
- Email:
[email protected] - Password:
admin
Change these immediately — go to the admin panel and update the email and password.
Step 4: Configure Basic Settings
Navigate to /admin/config in the web UI. Key settings to configure right away:
General
- App Name — Change “Pingvin Share” to your custom brand name.
- App URL — Set this to your public URL (e.g.,
https://share.yourdomain.com). This is critical for share links to work correctly.
Share Settings
- Max share size — Default is unlimited. Set a reasonable limit if you’re concerned about disk usage (e.g.,
10737418240for 10 GB). - Default expiration — How long shares last by default. 7 days is a sensible default.
- Max expiration — The maximum time a share can remain active.
- Zip download — Enable to let recipients download all files in a share as a single ZIP.
Email (SMTP)
Configure SMTP to enable email notifications for share recipients:
- SMTP Host — Your mail server (e.g.,
smtp.gmail.com,smtp.fastmail.com, or your self-hosted Mailcow/Stalwart instance). - SMTP Port — Usually
587for STARTTLS. - SMTP Username/Password — Your email credentials or app password.
- Sender email — The “from” address on notification emails.
Step 5: Set Up a Reverse Proxy
For HTTPS access, put Pingvin Share behind a reverse proxy. Here’s configurations for the most common options:
Caddy (Recommended)
Nginx
server {
listen 443 ssl;
server_name share.yourdomain.com;
ssl_certificate /etc/ssl/certs/yourdomain.crt;
ssl_certificate_key /etc/ssl/private/yourdomain.key;
client_max_body_size 10G;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Important: When using a reverse proxy, set TRUST_PROXY=true in your Docker Compose environment so Pingvin Share correctly reads the X-Forwarded-For header for rate limiting and logging.
Also note the client_max_body_size 10G directive in Nginx — without this, Nginx will reject large uploads with a 413 Request Entity Too Large error. Adjust the value to match your max share size. Caddy has no default upload limit.
Nginx Proxy Manager
Add a new proxy host pointing to pingvin-share on port 3000. Under the “Advanced” tab, add:
Step 6: Set User ID Permissions (Optional)
If you run Docker rootless or need specific file ownership, set PUID and PGID:
services:
pingvin-share:
image: stonith404/pingvin-share
environment:
- TRUST_PROXY=true
- PUID=1000
- PGID=1000
volumes:
- "./data:/opt/app/backend/data"
- "./data/images:/opt/app/frontend/public/img"
Find your user’s IDs with id on the host machine.
Step 7: Add ClamAV for Malware Scanning (Optional)
If other people will upload files to your instance (via reverse shares or public access), adding ClamAV is a smart move:
services:
pingvin-share:
image: stonith404/pingvin-share
container_name: pingvin-share
restart: unless-stopped
ports:
- "3000:3000"
environment:
- TRUST_PROXY=true
volumes:
- "./data:/opt/app/backend/data"
- "./data/images:/opt/app/frontend/public/img"
depends_on:
clamav:
condition: service_healthy
clamav:
image: clamav/clamav
container_name: pingvin-clamav
restart: unless-stopped
ClamAV takes 1-2 minutes to start while it loads virus definitions. Pingvin Share will wait for the health check to pass before starting. The logs should show “ClamAV is active” once everything is ready.
Resource warning: ClamAV uses approximately 1 GB of RAM for its virus signature database. If you’re running on a low-memory server (2 GB or less), skip this and rely on other security measures.
Step 8: Configure S3 Storage (Optional)
Instead of storing files on local disk, you can use S3-compatible storage. This is useful for offloading large files to cheap object storage like Backblaze B2 or MinIO.
In the admin panel (/admin/config), under the storage section:
- Storage provider — Select “S3”
- S3 Endpoint — Your S3 endpoint (e.g.,
s3.us-west-002.backblazeb2.com) - S3 Region — The region of your bucket
- S3 Bucket — Your bucket name
- S3 Access Key / Secret Key — Your S3 credentials
Files will now be stored in your S3 bucket instead of the local ./data directory.
Step 9: Set Up Authentication (Optional)
Pingvin Share supports OIDC and LDAP for single sign-on. If you’re already running Authentik, Authelia, or Keycloak, you can let users log in through your existing identity provider.
Configure this in the admin panel under /admin/config → Social Login / OIDC settings. You’ll need:
- Issuer URL — Your OIDC provider’s discovery URL
- Client ID — Created in your OIDC provider
- Client Secret — Created in your OIDC provider
Using Pingvin Share
Creating a Share
- Click Create Share on the dashboard.
- Drag and drop files or click to browse.
- Set optional parameters: expiration, password, visitor limit, description.
- Click Share to generate a link.
- Copy the link or email it directly to recipients.
Reverse Shares
Reverse shares flip the flow — instead of you sending files, others send files to you. This is great for:
- Collecting documents from clients
- Receiving homework submissions
- Gathering photos from event attendees
Create a reverse share from the dashboard, set constraints (max file size, max files, expiration), and send the link. Uploads land in your Pingvin Share instance.
User Management
The admin panel lets you create additional user accounts, each with their own shares and storage. You can also disable registration to keep your instance private.
Backup Strategy
Pingvin Share stores everything in the ./data directory:
#!/bin/bash
# backup-pingvin.sh
BACKUP_DIR="/path/to/backups"
SOURCE_DIR="$HOME/docker/pingvin-share/data"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Stop container for consistent backup
docker compose -f ~/docker/pingvin-share/docker-compose.yml stop
# Create backup
tar -czf "$BACKUP_DIR/pingvin-share-$TIMESTAMP.tar.gz" -C "$SOURCE_DIR" .
# Restart
docker compose -f ~/docker/pingvin-share/docker-compose.yml up -d
echo "Backup complete: pingvin-share-$TIMESTAMP.tar.gz"
The data directory contains the SQLite database and all uploaded files. For S3 storage, you only need to back up the SQLite database (at ./data/pingvin-share.db).
Configuration via YAML
If you prefer configuration-as-code over the web UI, mount a config.yaml file:
services:
pingvin-share:
image: stonith404/pingvin-share
volumes:
- "./data:/opt/app/backend/data"
- "./data/images:/opt/app/frontend/public/img"
- "./config.yaml:/opt/app/config.yaml"
Create your config.yaml based on the example in the repository. Note that when using YAML configuration, the web UI settings page becomes read-only.
Troubleshooting
Large uploads fail with timeout
If large file uploads fail, check:
- Reverse proxy limits — Nginx’s
client_max_body_sizemust be large enough. Caddy has no limit by default. - Proxy timeouts — Add
proxy_read_timeout 3600s;andproxy_send_timeout 3600s;to your Nginx config. - PHP limits — Not applicable here (Pingvin Share is Node.js-based), but worth noting if you’re used to PHP apps.
Share links show wrong URL
Set the App URL in admin settings to your public-facing URL. Without this, generated links use localhost:3000.
ClamAV fails to start
ClamAV needs to download virus definitions on first boot. Ensure your server has internet access and wait 2-3 minutes. Check logs with:
docker logs pingvin-clamav
Permission denied on data directory
Ensure the PUID/PGID environment variables match the owner of your ./data directory:
# Check current ownership
ls -la ./data
# Fix if needed
sudo chown -R 1000:1000 ./data
Pingvin Share vs Alternatives
| Feature | Pingvin Share | Send (Firefox) | FileBrowser | Nextcloud |
|---|---|---|---|---|
| One-click sharing | ✅ | ✅ | ❌ | ❌ |
| Expiring links | ✅ | ✅ | ❌ | ✅ |
| Password protection | ✅ | ✅ | ❌ | ✅ |
| Reverse shares | ✅ | ❌ | ❌ | ✅ |
| No file size limit | ✅ | ❌ (2.5 GB) | ✅ | ✅ |
| S3 storage | ✅ | ❌ | ❌ | ✅ |
| ClamAV scanning | ✅ | ❌ | ❌ | ✅ |
| Resource usage | Low | Low | Low | High |
| Setup complexity | Minimal | Moderate | Minimal | Complex |
Wrapping Up
Pingvin Share does one thing well: temporary file sharing. No bloat, no complicated setup, no surprise storage limits. If you’ve ever thought “I just need to send this file to someone,” this is the tool.
The setup is as simple as Docker gets — one container, two volumes, done. Add ClamAV if untrusted users will upload, add a reverse proxy for HTTPS, and you have a production-ready WeTransfer replacement running on your own hardware.