Self-hosted service
root-gg/plik avatar
root-gg/plik

Plik: a self-hosted temporary upload server in Go

Plik is a temporary file upload system (Wetransfer like) in Go.

1,822 stars197 forksGoNOASSERTION

At a glance

What is it?
Plik is a WeTransfer-style file drop that runs on your own infrastructure, with pluggable storage, metadata backends and an end-to-end encryption mode. The trade-off is that you own the cleanup, the backups and the certificate.
Who is it for?
Adopt Plik if you need an internal drop box where the storage, the metadata database and the authentication provider are all your choice, and where a link expires without anyone remembering to delete a file. Do not adopt it if you want a hosted service with zero operational surface, or if you need a compliance posture the project does not document.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Plik solves, and for whom

Sending a large file to someone outside your organisation usually means either attaching it to an email that will bounce, or pasting it into a public service where the retention policy is someone else's decision. Plik is the third option: a temporary upload server you host, where the file lives for a configured time and then goes away. The README describes it as a temporary file upload system, like WeTransfer but self-hosted, and the feature list backs that up with configurable TTL and auto-cleanup, password-protected uploads, and OneShot downloads that delete the file after the first retrieval.

The audience is narrow but real. It is a team that already runs infrastructure, has a place to put a service, and wants the upload endpoint to sit behind its own authentication rather than a vendor's. The repository topics include docker, self-hosted and e2ee, which matches that framing. If nobody on the team wants to own a server, a database and a TLS certificate, Plik is the wrong shape of tool.

Storage, metadata and auth are three separate choices

The architecture visible in the README splits into three pluggable layers. Files go to a storage backend: local disk, S3, OpenStack Swift or Google Cloud Storage. Upload records and tokens go to a metadata backend: SQLite, PostgreSQL or MySQL. Identity comes from an authentication provider: Local, Google, GitHub, OVH or OIDC. Each layer is independently selectable, which is the main reason to run Plik rather than a single-binary drop box.

That separation has consequences worth thinking through before deployment. SQLite is the low-friction metadata option and is fine for a small instance, but it makes horizontal scaling of the server awkward in a way PostgreSQL or MySQL do not. Choosing S3 for storage while keeping SQLite for metadata is a legitimate combination, but it means the database file still needs a backup path. The README does not spell out which combinations are tested together, so treat the matrix as something to confirm on your own instance rather than assume.

Two modes sit alongside the storage layer. Stream mode pipes the uploader directly to the downloader with nothing stored, which is useful for one-off transfers but removes any retry or resume story. End-to-end encryption is implemented with Age, and the README states that the CLI and web clients are interoperable, meaning a file encrypted from the command line can be decrypted through the browser. That is a specific and checkable claim, and it is the feature most likely to matter to anyone handling material they do not want sitting in plaintext in a bucket.

Getting a server up: four documented paths

The README gives four installation routes, and they are not equivalent in operational cost. The fastest is the container:

docker run -p 8080:8080 rootgg/plik

From there the web interface is at http://127.0.0.1:8080. The release tarball route downloads plik-server-1.4.2-linux-amd64.tar.gz, extracts it and runs ./plikd from inside the server directory. Debian and Ubuntu users can add the project's apt repository with the published gpg key, install plik-server, and start it with systemctl start plikd, which is the path that gives you a service unit rather than a foreground process. Kubernetes users get a Helm chart via helm repo add plik https://root-gg.github.io/plik followed by helm install plik plik/plik. Building from source is git clone, make, then cd server && ./plikd.

The command line client is the part most people will actually touch. Uploading a file is plik myfile.txt, and the README shows the resulting output: a share URL of the form http://127.0.0.1:8080/#/?id=vDPmPEUqc5oCt31T, a progress line, and a ready-made curl command for retrieving the file. The same upload can be done with curl alone:

curl --form 'file=@/path/to/myfile.txt' http://127.0.0.1:8080

which returns a direct file URL. That curl path matters because it means Plik can be wired into scripts and CI jobs without installing the Go client. What the README does not show is the server configuration file or the exact keys for the storage, metadata and auth backends; those live in the documentation site rather than the repository README, so budget time to read it before you pick backends.

Where Plik stops being the right tool

The honest limitation is that Plik is a service, not a library or a managed product. Everything in the feature list (TTL, auto-cleanup, OneShot, stream mode, E2EE, Prometheus metrics) is behaviour you have to keep running. If the plikd process is down, uploads fail; if the metadata database is lost, the links are lost even when the files still sit in the bucket. The README does not describe a replication or failover story for the metadata layer, so a single PostgreSQL instance is a single point of failure for link resolution.

Stream mode is a good example of a feature that is easy to misread. Nothing stored sounds appealing until you need to retry a transfer that dropped halfway, at which point there is nothing to resume from. OneShot has a similar edge: the file is deleted after the first download, so a recipient who opens the link and then loses the download has no second attempt. Neither is a defect, but both are choices that need to be communicated to the people receiving links.

The licence field is another thing to check rather than assume. The repository metadata reports NOASSERTION for the licence, while the README's badge and licence section both point at MIT. Those two signals disagree, and the resolution is in the LICENSE file, not in anything summarised here. If your organisation has a licence review step, read that file directly. Nothing in this article is legal advice.

How Plik differs from a generic object store with signed URLs

The obvious alternative is not another file-sharing product but the storage you already have: an S3 bucket or equivalent, plus presigned URLs and a lifecycle rule. That approach is genuinely simpler. There is no server to run, no metadata database, and the expiry is enforced by the storage provider's lifecycle policy rather than by an application.

The difference in approach is where the upload experience lives. A presigned URL is a credential with a deadline; whoever holds it can PUT to a known key. Plik instead creates an upload object with its own identifier, issues a share URL, and layers behaviour on top: a password on the upload, a download counter that can delete the file, a browser interface with previews, and an encrypted mode where the server never sees plaintext. It also gives you an audit-shaped surface through Prometheus metrics, which a raw bucket does not. In exchange, you take on the metadata database, the upgrade cadence and the certificate. If your requirement is simply let a colleague fetch one object for an hour, the bucket wins. If you need a link a non-technical recipient can open in a browser, with a password and a one-shot download, Plik is doing work the bucket will not.

Upgrades, maintenance and what a version bump costs

The release history shows a steady cadence: 1.4.0 in early March 2026, 1.4.1 a week later, 1.4.2 at the end of March, with repository activity continuing through September 2026. That pattern suggests patch releases follow quickly after minor ones, which is good for fixes but means an operator should expect to move more than once a year. The upgrade path itself depends on the install method you chose. Docker and Helm users pull a new tag and restart; apt users run apt update && apt install plik-server; tarball users unpack a new directory and swap the binary. None of these are documented in the README as a migration procedure, and the metadata backend is where that matters, since a schema change between versions would land there.

The recurring costs are the ones typical of a self-hosted service: patching the host, backing up whichever metadata backend you selected, rotating credentials for the storage backend, and renewing the TLS certificate in front of plikd. Prometheus metrics are available for monitoring, but the README does not enumerate which metrics exist, so instrumenting alerting means reading the documentation first. None of this is unusual, and none of it is free.

Clients, integrations and the MCP server

Plik is not limited to its own web and CLI clients. The README lists third-party integrations: a ShareX uploader that is integrated directly into ShareX, plikSharp as a .NET API client, and a Thunderbird addon called Filelink for Plik that uploads attachments. Those exist because the server exposes an HTTP API that the curl example already demonstrates. For a team that wants screenshot-to-link or mail-attachment-to-link workflows without building anything, the ShareX and Thunderbird integrations are the practical entry points.

There is also an MCP server for AI assistant integration, documented separately. That is an unusual feature for a file-sharing tool and worth treating with appropriate caution: an assistant that can create uploads is an assistant that can move data out of your environment, so the upload policy, the TTL and the authentication provider become the controls that matter. The README does not describe any per-token scoping or quota mechanism, so if you enable MCP access, the constraints you rely on are the ones enforced at the upload level (TTL, password, OneShot) rather than at the assistant level. Verify that reading before you wire an assistant into an instance that holds anything sensitive.

Editorial conclusion

Adopt Plik if you need an internal drop box where the storage, the metadata database and the authentication provider are all your choice, and where a link expires without anyone remembering to delete a file. Do not adopt it if you want a hosted service with zero operational surface, or if you need a compliance posture the project does not document. Before rollout, verify three things on your own instance: that your chosen metadata backend survives a restart with uploads intact, that your storage backend's credentials are scoped to the bucket or container Plik uses, and that the TTL and auto-cleanup settings match the retention your organisation will actually accept.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. root-gg/plik on GitHub
Community notes

Community notes