PictShare
PictShare gives you multi lingual image hosting service with a simple resizing and upload API on your own infrastructure.
Self-hosted image, GIF, and MP4 hosting with on-the-fly resizing — honestly reviewed for founders who are tired of paying per API call.
TL;DR
- What it is: Open-source (Apache-2.0) self-hosted image, GIF, MP4, and text-snippet hosting platform with a URL-based transformation API — resize, filter, and convert media by editing the URL, no separate processing pipeline needed [2][README].
- Who it’s for: Developers building apps that need cheap, controllable media hosting; homelab operators who want a private Imgur replacement; teams embedding PictShare as a backend for user-generated content [2][4].
- Cost savings: Cloudinary’s free tier caps at 25GB storage and 25GB bandwidth per month; paid plans start around $89/mo. PictShare self-hosted on a $6 VPS is your entire monthly bill [README].
- Key strength: 100% file-based — no database to configure, migrate, or corrupt. One Docker command and it runs [README][2].
- Key weakness: 905 GitHub stars as of this review. Small community, incomplete roadmap, and the official demo instance currently shows “Upload forbidden” — not a confidence signal for a hosting tool [website scrape][README].
What is PictShare
PictShare is a self-hosted media hosting service written in PHP. You upload an image (or MP4, GIF, or text file) and get back a URL. Then you transform that media — resize, filter, convert format — by appending modifiers to the URL itself, without saving intermediate copies. The concept is similar in spirit to Cloudinary or Imgix, but running on your own hardware and free to use.
The project is maintained by HaschekSolutions and is now on v3, which introduced breaking URL structure changes from earlier versions [README]. The GitHub description calls it “an open source image, mp4, pastebin hosting service with a simple resizing and upload API that you can host yourself” — which is the most accurate one-sentence summary you’ll find.
What separates it from a basic file server is the URL modifier system. Upload photo.jpg, get back https://yourhost.com/abc123.jpg. Want it at 800×600? Hit https://yourhost.com/800x600/abc123.jpg. Want it grayscale and cropped? Add more modifiers in the path. The server renders the transformation on the fly and (optionally) caches it. This is the thing that saves you from building a separate image processing pipeline [website scrape][3].
Other things worth knowing: PictShare strips all EXIF data on upload, so GPS coordinates and camera model info don’t travel with your users’ photos [2]. Duplicates are deduplicated — if the same file is uploaded twice, the second upload just links to the first rather than consuming additional storage [README]. And there is no database. All state is on the filesystem, which is either very appealing or slightly alarming depending on your background [README][2].
Why people choose it
The honest answer is that there are two distinct audiences who reach for PictShare, and they have almost nothing in common.
The developer-building-something audience finds PictShare because they need a dead-simple image hosting backend with an API, and they want to avoid the complexity of setting up PostgreSQL alongside their main app just to store file metadata. The Traefik forum thread [4] is a good example: a user integrating PictShare as the image hosting layer inside a Lemmy (Fediverse Reddit alternative) stack. It slots in as a service, handles uploads via POST, returns a URL, done. The passthrough API — where you submit an image and get back the transformed version without storing it — is particularly useful for one-shot normalization of user uploads [website scrape].
The homelab / privacy-focused audience cares about EXIF stripping, data sovereignty, and not feeding their personal photos to someone else’s servers. The medevel.com review [2] is aimed squarely at this group — photographers and media creators who want a private, self-controlled platform. That audience cares that uploads don’t phone home, that delete codes give file-level control, and that nothing is stored in a third-party database.
What both groups share is an appreciation for the no-database architecture. No PostgreSQL to manage. No Redis for sessions. No migrations to run during upgrades. That simplicity is real, and it’s the thing that comes up in every description of the project [2][README].
Features
Core hosting:
- Images (JPEG, PNG, GIF, WebP), MP4 video, and text files [README]
- Upload via multipart POST, URL fetch, or Base64 string [website scrape]
- Automatic duplicate deduplication by content hash — same file uploaded twice does not consume double storage [README]
- Per-file delete codes and a master delete code for admins [README]
- EXIF data stripping on all image uploads [2]
URL-based image transformations:
- Resize by dimensions:
/800x600/filename.jpg[website scrape] - Force exact dimensions with aspect-ratio zoom:
/800x600/forcesize/filename.jpg[website scrape] - Image filters via URL modifiers (grayscale and others documented separately in the repo) [README]
- GIF to MP4 conversion [README][2]
- JPEG and PNG to WebP auto-conversion when the browser supports it [README][2]
- MP4 resizing and automatic re-encoding for mobile compatibility [README]
Generative endpoints (v3):
- Identicon generation from any string in the URL:
/identicon/yourstringhere[README] - Placeholder image generation by size:
/placeholder/555x250/color-white-blue[README]
API:
- REST API returning JSON for all upload operations [website scrape]
- Passthrough endpoint for on-the-fly transformation without storage [website scrape]
- Upload returns hash, file URL, delete code, and delete URL [website scrape]
Infrastructure:
- 100% file-based, no database required [README][2]
- Docker deployment (single
docker runcommand) [README][2] - S3-compatible external storage backend [README]
- Encryption for files stored in external storage [README]
- Text hosting (pastebin-style) [README]
- URL shortening — listed in v3 roadmap but marked incomplete as of this review [README]
- Nginx caching works with the URL path structure, though configuration requires some care [3]
- No built-in authentication or user management [1]
The last point deserves emphasis. PictShare has no login system. If you want to restrict uploads to authorized users, you handle that at the reverse proxy layer — Caddy basicauth, Authelia, or similar [1]. The UPLOAD_CODE config option provides a primitive upload password, but there are no user accounts, sessions, or roles. This is a feature if you want simplicity; it is a problem if you’re building a multi-tenant product on top of it.
Pricing: self-hosted math vs. the SaaS alternatives
PictShare has no cloud offering. You self-host it or you don’t use it. So the comparison here is against the SaaS media hosting services it could replace.
Cloudinary (the most common point of comparison for image hosting with transformations):
- Free: 25GB storage, 25GB bandwidth, 25 monthly credits
- Plus: $89/mo for 225GB storage, 225GB bandwidth
- Pricing scales steeply as you add transformations, bandwidth, and storage
Cloudflare Images + Stream (for images + video):
- Images: $5/mo for up to 100,000 images stored, $1 per 1,000 delivered
- Stream: $5/mo per 1,000 minutes stored, $1 per 1,000 minutes delivered
Self-hosted PictShare:
- Software: $0 (Apache-2.0)
- VPS on Hetzner or Contabo: $4–10/mo for entry-level instances
- Storage: VPS-local disk or S3-compatible (Wasabi at $6.99/mo for 1TB, Backblaze B2 at $6/TB)
- Bandwidth: varies by VPS provider — Hetzner gives 20TB/mo on their CAX11 ARM instance at €3.79/mo
Concrete example: A small SaaS app storing 5,000 user-uploaded images per month with moderate traffic. On Cloudinary Plus, that’s comfortably in the $89/mo range once you factor in transformation credits. On self-hosted PictShare running on a $6 Hetzner VPS with Wasabi for overflow storage, that’s roughly $13/mo total — assuming you’re already paying for the VPS for something else, closer to $7.
Over a year: Cloudinary Plus ≈ $1,068. PictShare self-hosted ≈ $84–156. The delta is real.
The caveat: Cloudinary’s CDN is global and production-hardened. PictShare is your server in one datacenter. If you’re serving media globally with latency requirements, add Cloudflare’s free CDN tier in front of your PictShare instance — it’s the standard setup and documented in the nginx caching thread [3].
Deployment reality check
The quickstart is genuinely one command [README]:
docker run -d -p 8080:80 --name=pictshare ghcr.io/hascheksolutions/pictshare
That works. Open http://localhost:8080, upload an image, get a URL. For a proof of concept or internal tool, you can be running in under five minutes.
For production you need more:
- A Linux VPS with Docker installed
- A domain name and reverse proxy (Caddy or nginx) for HTTPS
- Persistent volume mounts so your uploads survive container restarts — the README covers this in the Docker docs
- If using external storage: S3 credentials and the relevant env vars
- If restricting uploads: an
UPLOAD_CODEin your config, or handle auth at the reverse proxy with Authelia or similar [1]
The nginx caching configuration requires some attention. The URL modifier system means images live at paths like /800x600/abc123.jpg, and you need a regex location block to catch all these patterns for caching — a standard ~* \.(jpg|png|gif)$ rule won’t cover them [3]. The Stack Overflow thread from the project’s creator [3] walks through the correct nginx configuration.
The v3 breaking changes matter if you’re upgrading from an older install. URL structure changed (the filename must now be the last segment), several config options were dropped, and the API was redesigned for more consistent REST behavior [README]. If you’re starting fresh, ignore this. If you’re migrating, read the README’s breaking changes section before you do anything.
One flag: the official PictShare demo at pictshare.net currently shows “Upload forbidden — Due to configured restrictions, you are not allowed to upload files at this time” [website scrape]. For a tool whose main pitch is ease of use and a working demo, having the public instance locked down is a poor first impression. It doesn’t affect what you self-host, but it does raise questions about how actively the project is maintained.
Pros and Cons
Pros
- No database. This is genuinely unusual and genuinely useful. Nothing to configure, nothing to migrate, nothing to restore. Files are files [README][2].
- Apache-2.0 license. More permissive than MIT in some commercial contexts. No “Fair-code” or “source-available” gotchas [README].
- URL transformer API is elegant. Resize, filter, convert — by editing the URL. No SDKs, no extra API calls, no client-side libraries required [website scrape][3].
- EXIF stripping out of the box. GPS data and camera metadata are removed on upload, which matters for any app where users upload phone photos [2].
- Deduplication. Identical files don’t consume additional storage — the second upload links to the first [README].
- Passthrough API. Transform an image on the fly without storing the result — useful for normalizing uploads before saving them elsewhere [website scrape].
- One-command Docker deploy. Genuinely fast to get running [README][2].
Cons
- 905 stars. Small community means fewer eyes on bugs, slower issue resolution, and less confidence in long-term maintenance [GitHub].
- No built-in auth. No user accounts, no login, no RBAC. You handle access control entirely at the reverse proxy. This is workable but means more moving parts [1].
- Incomplete roadmap. URL shortening and upload quotas are listed in the v3 roadmap but not checked as complete. Features that were in the config spec are also unimplemented [README].
- Demo is broken. The public instance rejects uploads, which is a red flag for a project whose appeal is simplicity [website scrape].
- PHP 8.2+ requirement. Not a problem with Docker, but if you’re on shared hosting or a legacy server, check your PHP version [README].
- v3 broke backward compatibility. Anyone upgrading from v2 has URL structure changes to deal with [README].
- No video transcoding pipeline. MP4 resizing and conversion work, but there’s no job queue for heavy processing — large video uploads block synchronously.
- Documentation is split across multiple RTFM files in the repo, with no single comprehensive reference for all config options and their interactions.
Who should use this / who shouldn’t
Use PictShare if:
- You’re building a web app that needs image upload + URL-based resizing and you don’t want to integrate Cloudinary or maintain a separate image processing service.
- You’re running a homelab or self-hosted stack (Lemmy, Nextcloud, etc.) and want a private media host you control [4].
- You’re a photographer or developer who uploads from mobile and specifically wants EXIF data stripped at the server level [2].
- You’re comfortable with Docker and a basic reverse proxy setup.
- You want Apache-2.0 with no strings attached.
Skip it (use Chevereto or Lychee) if:
- You want photo album organization, galleries, or user management rather than a raw upload API.
Skip it (use Cloudinary or Cloudflare Images) if:
- You need a global CDN, 99.9% uptime SLA, or you don’t have the time or interest in maintaining your own server.
- Your team needs an admin UI rather than a command-line config file.
Skip it (use imgproxy) if:
- You already have a storage layer (S3, local disk) and you only need the image transformation piece — imgproxy does that without the hosting layer.
Skip it entirely if:
- You’re a non-technical founder with no one to handle a Linux server. PictShare has no managed offering and no GUI setup wizard.
Alternatives worth considering
- Chevereto — full-featured image hosting platform with user accounts, albums, and an admin panel. The self-hosted Community Edition is free. More opinionated than PictShare, more features, also has a database dependency.
- Lychee — photo management with album support, user accounts, and a polished UI. Better for personal photo libraries than for programmatic API use.
- imgproxy — image transformation only, no storage. Pair it with MinIO or S3 if you want the full stack. More performant for high-traffic transformation workloads, built in Go rather than PHP.
- Cloudinary — the SaaS incumbent. Global CDN, polished SDK, expensive at scale, zero maintenance. If budget isn’t the constraint, the experience is better than anything self-hosted.
- Cloudflare Images — $5/mo base + usage. Good if you’re already in the Cloudflare ecosystem. No self-hosted option.
- MinIO + imgproxy — DIY stack that gives you more control and better performance than PictShare for high-throughput use, but significantly more configuration work.
Bottom line
PictShare solves a specific problem well: you need a lightweight, file-based image host with a URL transformation API, you don’t want a database, and you want to own the infrastructure. The one-command Docker deploy is real, the URL modifier system is genuinely clever, and the Apache-2.0 license has no commercial restrictions. For a developer building a side project or a small team hosting user avatars and attachments, the math against Cloudinary is compelling.
The honest concern is project health. At 905 stars, with a broken public demo and an incomplete roadmap, PictShare is a tool you adopt because it fits your use case right now — not because you’re betting on a thriving community behind it. That’s not disqualifying, but go in with eyes open: you may find yourself reading the source code to answer questions the documentation doesn’t cover.
If the deployment is the blocker, upready.dev handles exactly this kind of one-time self-hosted setup for clients.
Sources
- Mustafa Can Yücel — “Authelia and Caddy in Containers” — mustafacanyucel.com. https://mustafacanyucel.com/blog/blog-18.html
- Medevel — “PictShare: A Powerful Tool for Photographers and Media Creators” — medevel.com. https://medevel.com/pictshare/
- Christian (HaschekSolutions) — “Caching images on all folder levels of nginx reverse proxy” (Stack Overflow question from the project creator) — stackoverflow.com. https://stackoverflow.com/questions/33703230/caching-images-on-all-folder-levels-of-nginx-reverse-proxy
- astuffedtiger — “Issues with Router Priorities” (PictShare integration with Lemmy via Traefik) — community.traefik.io. https://community.traefik.io/t/issues-with-router-priorities/4565
Primary sources:
- GitHub repository and README: https://github.com/hascheksolutions/pictshare (905 stars, Apache-2.0 license)
- Official website and API documentation: https://www.pictshare.net/
Features
Integrations & APIs
- REST API
Search & Discovery
- Tags / Labels
Category
Related File Management & Sharing Tools
View all 133 →Syncthing
81KOpen-source continuous file synchronization — peer-to-peer, encrypted, no central server, no cloud account required.
LocalSend
77KAn open-source, cross-platform alternative to AirDrop — share files between nearby devices over your local network without the cloud.
MinIO
61KHigh-performance, S3-compatible object storage for AI, analytics, and cloud-native workloads. Deploy on-premises or in any cloud with a single binary.
Rclone
56KCommand-line tool that syncs, copies, and manages files across 70+ cloud storage providers. The rsync for cloud storage.
AList
49KFile list program that aggregates multiple storage backends into a single web interface with WebDAV support. Mount cloud drives, local storage, and S3 in one place.
copyparty
44KCopyparty is a portable, single-file Python file server with resumable uploads, deduplication, WebDAV, SFTP, FTP, media indexing, and audio transcoding — no dependencies required.