Plik is a scalable & friendly temporary file upload system ( wetransfer like ) in golang.


Build Status Go Report Docker Pulls GoDoc License

Want to chat with us ? Telegram channel :


Plik is a scalable & friendly temporary file upload system ( wetransfer like ) in golang.

Main features

  • Powerful command line client
  • Easy to use web UI
  • Multiple data backend : File, OpenStack Swift, S3
  • Multiple metadata backend : Sqlite3, postgresql
  • OneShot : Files are destructed after the first download
  • Stream : Files are streamed from the uploader to the downloader (nothing stored server side)
  • Removable : Give the ability to the uploader to remove files at any time
  • TTL : Custom expiration date
  • Password : Protect upload with login/pasgisword (Auth Basic)
  • Comments : Add custom message (in Markdown format)
  • User authentication : Local / Google / OVH
  • Upload restriction : Source IP / Token
  • Administrator dashboard
  • Server side encryption ( with S3 data backend )
  • ShareX Uploader : Directly integrated into ShareX
  • plikSharp : A .NET API client for Plik
  • Filelink for Plik : Thunderbird Addon to upload attachments to Plik




From release

To run plik, it's very simple :

$ wget
$ tar xzvf plik-1.3.1-linux-64bits.tar.gz
$ cd plik-1.3.1/server
$ ./plikd

Et voilà ! You now have a fully functional instance of Plik running on
You can edit server/plikd.cfg to adapt the configuration to your needs (ports, ssl, ttl, backend params,...)

From Debian repository

Configure repository and install server and/or client

wget -O - | apt-key add -
echo "deb $(lsb_release --codename --short) main" > /etc/apt/sources.list.d/
apt-get update
apt-get install plikd plik

Edit server configuration at /etc/plikd.cfg and start the server

service plikd start
From sources

To compile plik from sources, you'll need golang and npm installed on your system.

First, get the project and libs via go get :

$ go get
$ cd $GOPATH/src/

Build everything and run it :

$ make
$ cd server && ./plikd

Cli client

Plik is shipped with a powerful golang multiplatform cli client (downloadable in web interface) :

  plik [options] [FILE] ...

  -h --help                 Show this help
  -d --debug                Enable debug mode
  -q --quiet                Enable quiet mode
  -o, --oneshot             Enable OneShot ( Each file will be deleted on first download )
  -r, --removable           Enable Removable upload ( Each file can be deleted by anyone at anymoment )
  -S, --stream              Enable Streaming ( It will block until remote user starts downloading )
  -t, --ttl TTL             Time before expiration (Upload will be removed in m|h|d)
  -n, --name NAME           Set file name when piping from STDIN
  --server SERVER           Overrides plik url
  --token TOKEN             Specify an upload token
  --comments COMMENT        Set comments of the upload ( MarkDown compatible )
  -p                        Protect the upload with login and password
  --password PASSWD         Protect the upload with login:password ( if omitted default login is "plik" )
  -a                        Archive upload using default archive params ( see ~/.plikrc )
  --archive MODE            Archive upload using specified archive backend : tar|zip
  --compress MODE           [tar] Compression codec : gzip|bzip2|xz|lzip|lzma|lzop|compress|no
  --archive-options OPTIONS [tar|zip] Additional command line options
  -s                        Encrypt upload usnig default encrypt params ( see ~/.plikrc )
  --not-secure              Do not encrypt upload regardless of ~/.plikrc configurations
  --secure MODE             Archive upload using specified archive backend : openssl|pgp
  --cipher CIPHER           [openssl] Openssl cipher to use ( see openssl help )
  --passphrase PASSPHRASE   [openssl] Passphrase or '-' to be prompted for a passphrase
  --recipient RECIPIENT     [pgp] Set recipient for pgp backend ( example : --recipient Bob )
  --secure-options OPTIONS  [openssl|pgp] Additional command line options
  --update                  Update client
  -v --version              Show client version

For example to create directory tar.gz archive and encrypt it with openssl :

$ plik -a -s mydirectory/
Passphrase : 30ICoKdFeoKaKNdnFf36n0kMH
Upload successfully created :

mydirectory.tar.gz : 15.70 MB 5.92 MB/s

Commands :
curl -s '' | openssl aes-256-cbc -d -pass pass:30ICoKdFeoKaKNdnFf36n0kMH | tar xvf - --gzip

Client configuration and preferences are stored at ~/.plikrc or /etc/plik/plikrc ( overridable with PLIKRC environement variable )

Quick upload using curl only

curl --form '[email protected]/path/to/file'

DownloadDomain configuration option must be set for this to properly work.

Available data backends

Plik is shipped with multiple data backend for uploaded files and metadata backend for the upload metadata.

  • File databackend :

Store uploaded files in a local or mounted file system directory.

Openstack Swift is a highly available, distributed, eventually consistent object/blob store which supports Server Side Encryption

Available metadata backends

  • Sqlite3

Suitable for standalone deployment.

  • PostgreSQL

Suitable for distributed / High Availability deployment.


Plik can authenticate users using Local accounts or using Google or OVH APIs.

If source IP address restriction is enabled, user accounts can only be created from trusted IPs and then authenticated users can upload files without source IP restriction.

It possible to deny unauthenticated uploads totally ( NoAnonymousUploads ).

Admin users can access the admin dashboard and manipulate every uploads.

  • Local :

    • You can manipulate local users with the server command line
    $ ./plikd --config ./plikd.cfg user create --login root --name Admin --admin    
    Generated password for user root is 08ybEyh2KkiMho8dzpdQaJZm78HmvWGC
  • Google :

    • You'll need to create a new application in the Google Developper Console
    • You'll be handed a Google API ClientID and a Google API ClientSecret that you'll need to put in the plikd.cfg file.
    • Do not forget to whitelist valid origin and redirect url ( https://yourdomain/auth/google/callback ) for your domain.
    • It is possible to whitelist only one or more email domains.
  • OVH :

    • You'll need to create a new application in the OVH API :
    • You'll be handed an OVH application key and an OVH application secret key that you'll need to put in the plikd.cfg file.

Once authenticated a user can generate upload tokens that can be specified in the ~/.plikrc file to authenticate the command line client.

Token = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"


Plik allow users to upload and serve any content as-is, but hosting untrusted HTML raises some well known security concerns.

Plik will try to avoid HTML rendering by overriding Content-Type to "text-plain" instead of "text/html".

By default Plik sets a couple of security HTTP headers like X-Content-Type-Options, X-XSS-Protection, X-Frame-Options, Content-Security-Policy to disable sensible features of most recent browsers like resource loading, xhr requests, iframes,... This will however break features like audio/video playback, pdf rendering so it's possible to disable this behavior by setting the EnhancedWebSecurity configuration parameter to false

Along with that it is also strongly advised to serve uploaded files on a separate (sub-)domain to fight against phishing links and to protect Plik's session cookie with the DownloadDomain configuration parameter.


Plik server expose a HTTP API to manage uploads and get files :

See the Plik API reference

Admin CLI

Using the ./plikd server binary it's possible to :

  • create/list/delete local accounts
  • create/list/delete user CLI tokens
  • create/list/delete files and uploads
  • import / export metadata

See help for more details


Plik comes with a simple Dockerfile that allows you to run it in a container :

See the Plik Docker reference

Plik also comes with some useful scripts to test backend in standalone docker instances :

See the Plik Docker backend testing

Go client

Plik now comes with a golang library above which the cli client is built

See the Plik library reference


  • Why is stream mode broken in multiple instance deployement ?

Beacause stream mode isn't stateless. As the uploader request will block on one plik instance the downloader request MUST go to the same instance to succeed. The load balancing strategy MUST be aware of this and route stream requests to the same instance by hashing the file id.

Here is an example of how to achieve this using nginx and a little piece of LUA. Make sure your nginx server is built with LUA scripting support. You might want to install the "nginx-extras" Debian package (>1.7.2) with built-in LUA support.

upstream plik {

upstream stream {
    hash $hash_key;

server {
    listen 9000;

    location / {
        set $upstream "";
        set $hash_key "";
        access_by_lua '
            _,_,file_id = string.find(ngx.var.request_uri, "^/stream/[a-zA-Z0-9]+/([a-zA-Z0-9]+)/.*$")
            if file_id == nil then
                ngx.var.upstream = "plik"
                ngx.var.upstream = "stream"
                ngx.var.hash_key = file_id
        proxy_pass http://$upstream;
  • Redirection loops with DownloadDomain enforcement and reverse proxy
Invalid download domain, expected

DownloadDomain check the Host header of the incoming HTTP request, by default reverse proxies like Nginx or Apache mod_proxy does not forward this Header. Check the following configuration directive :

Apache mod_proxy : ProxyPreserveHost On
Nginx : proxy_set_header Host $host;
  • I have an error when uploading from client : "Unable to upload file : HTTP error 411 Length Required"

Under nginx < 1.3.9, you must enable HttpChunkin module to allow transfer-encoding "chunked".
You might want to install the "nginx-extras" Debian package with built-in HttpChunkin module.

And add in your server configuration :

chunkin on;
error_page 411 = @my_411_error;
location @my_411_error {
  • How to disable nginx buffering ?

By default nginx buffers large HTTP requests and reponses to a temporary file. This behaviour leads to unnecessary disk load and slower transfers. This should be turned off (>1.7.12) for /file and /stream paths. You might also want to increase buffers size.

Detailed documentation :

proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_buffer_size 1M;
proxy_buffers 8 1M;
client_body_buffer_size 1M;
  • Why authentication does not work with HTTP connections when EnhancedWebSecurity is set ?

Plik session cookies have the "secure" flag set when EnhancedWebSecurity is set so they can only be transmitted over secure HTTPS connections.

  • Build failure "/usr/bin/env: ‘node’: No such file or directory"

Debian users might need to install the nodejs-legacy package.

This package contains a symlink for legacy Node.js code requiring
binary to be /usr/bin/node (not /usr/bin/nodejs as provided in Debian).
  • How to take and upload screenshots like a boss ?
alias pshot="scrot -s -e 'plik -q \$f | xclip ; xclip -o ; rm \$f'"

Requires you to have plik, scrot and xclip installed in your $PATH.
scrot -s allow you to "Interactively select a window or rectangle with the mouse" then Plik will upload the screenshot and the url will be directly copied to your clipboard and displayed by xclip. The screenshot is then removed of your home directory to avoid garbage.

  • How to contribute to the project ?

Contributions are welcome, feel free to open issues and/or submit pull requests. Please be sure to also run/update the test suite :

    make fmt
    make lint
    make test
    make test-backends
  • Cross compilation

All binary are now statically linked
Clients can be safely cross-compiled for all os/architectures as they do not rely on GCO (sqlite)

    GOOS=windows GOARCH=amd64 make client

Servers rely on CGO/sqlite so we cross-compile it for Linux only using Docker.
The make release target will build a release package and Docker images for amd64,i386,arm,arm64

If you want a more specific ARMv7 for hardware floating point build for example See :

    make release
    docker run -it rootgg/plik-builder:latest /bin/bash

    GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc make server

    file server/plikd
    server/plikd: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, Go ...

    Then either copy the binary from the docker or play with releaser/ to generate a release archive
  • Defining configuration parameters using environment variables

One can specify configuration parameters using env variable with the configuration parameter in screaming snake case

    PLIKD_DEBUG_REQUESTS=true ./plikd

For Arrays and config maps they must be provided in json format. Arrays are overriden but maps are merged

    PLIKD_DATA_BACKEND_CONFIG='{"Directory":"/var/files"}' ./plikd
  • Auto zipping content

    Auto zipping content

    Is it possible to implement an auto-zipping feature? It would be great to zip multiple files server side. (Great for mobile phones uploading pictures)

    opened by peperunas 19
  • Go get complains about missing BuildInfo

    Go get complains about missing BuildInfo

    [email protected]:~/gopath/src/ go get -v
    plik/server/handlers/misc.go:51:28: undefined: common.GetBuildInfo
    opened by camathieu 12
  • Improve Content Security Policy

    Improve Content Security Policy

    When you use to check the Content Security Policy there appear errors in the plugin-types and sandbox section.

    Additional there should be allowed to play a mp4 file in the browser instead of getting the following error: image I can be simply reproduced by uploading a mp4 file. (In my case I used ShareX with the Plik uploader).

    opened by mxschmitt 10
  • Upload options missing after 1.2.2 upgrade

    Upload options missing after 1.2.2 upgrade

    Running on CentOS 6, behind an Apache reverse proxy and using the binaries.

    After upgrading from 1.2.0 to 1.2.2 the main Plik page loads but the file upload options (in the red box below) are missing and files can no longer be uploaded.


    opened by TheFiZi 9
  • Google Auth - Error 500

    Google Auth - Error 500

    Hello! I've setup the Google API in Plik but when I do the login, this message pops up:

    Unable to get user info from google API

    What should I do?


    opened by peperunas 9
  • Unsafe execution of code in the Plik website context

    Unsafe execution of code in the Plik website context

    Plik lets users upload untrusted HTML content. This content is then made available at a static URL.

    In addition to being convenient for hosting phishing pages, the HTML content is rendered as-is. Untrusted Javascript and Flash scripts get executed in the context of the Plik server.

    The plik-session cookie is marked HTTPOnly. However, this doesn't prevent injected scripts from sending authenticated requests to the Plik API. The session cookie will not be directly visible to the scripts, but it will still be transmitted to the API endpoints.

    For example, an attacker can upload a webpage to Plik that includes this code in order to retrieve the list of files uploaded by Plik users viewing that upload:

    fetch('/me/uploads?offset=0&size=50', {credentials: 'same-origin'}).
        then(e => e.json()).then(e => /* send e to a remote server */)


    The actual cookies can also be retrieved by attackers in spite of the HTTPOnly flag, by including Flash objects in the webpage. These can send queries with theTRACE method, whose response include cookies if the server supports that method.

    Possible mitigations:

    • Viewing and uploading files should not share the same origin, so that viewing a document doesn't involve any cookies.
    • Do not render HTML. Offer it as a download (Content-Disposition: Attachment), and pay attention to the fact that this is not enough on some Internet Explorer versions. The X-Download-Options: noopen and X-Content-Type-Options: nosniff headers have to be sent. This also prevents Plik websites from being abused for phishing.
    • If untrusted HTML really has to be rendered, render it in an iframe with the sandbox attribute. All browsers do not support this attribute, though.
    opened by jedisct1 9
  • [Feature Request] add read-only share-url

    [Feature Request] add read-only share-url

    Add a read-only share-url so that each time you generate a share you get a read-only url which only allows listing files and downloading them and a read-write-url which allows changing the share like normal.

    opened by tionis 8
  • log file location on docker container

    log file location on docker container

    I feel silly to open an issue for that but I cannot find plik log file.

    I am using plik docker image and looked at usual /var/log location and ~/server dir but could not find any log file there.

    I would like to see the root of the error 500 I have on save (Oops ! (500) Unable to save file).

    opened by xididri 8
  • Pasting files on firefox is broken

    Pasting files on firefox is broken

    Tried on Firefox 97.0b8, on a new profile. I can only paste an image when clicked in this zone: image Since clicking on the middle zone will open a file explorer, you can only use the little bit of space on the left of the field to make it work. Pasting after clicking anywhere else won't do anything.

    However, if you paste text, it works everywhere in the page. I'm happy to do any testing/edits to try fixes and find a solution.

    opened by Cubox 7
  • docker container exit error

    docker container exit error

    When I try running plik via docker on a raspberrypi 3, I get an error:

    standard_init_linux.go:211: exec user process caused "exec format error"

    opened by luckymedog 7
  • Cannot Get Reverse proxy to work in NGINX

    Cannot Get Reverse proxy to work in NGINX

    Hi, somehow I can't get the reverse proxy function to work in NGINX with plik. Here is my config:

    upstream plik { 
    server {
    #I am omitting here the other parts of the config for http and https (which is working fine for other web apps anyway)
    location /plik {
    proxy_pass http://plik;                                    
    proxy_set_header Host $host;    
    proxy_set_header Connection "upgrade";
    proxy_buffering off;
    proxy_request_buffering off;                                          
    proxy_http_version 1.1; 
    proxy_buffer_size 1M; 
    proxy_buffers 8 1M;
    proxy_redirect off;
    client_body_buffer_size 1M; 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 

    I get a 404 error, and nginx says the following in the log

    SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream

    Any idea what is wrong? Note that while I am using https usually, i have no issue doing reverse proxy with other apps. But somehow I cannot figure what is wrong here. Any hint appreciated!

    opened by ekianjo 7
  • streaming to multiple clients

    streaming to multiple clients

    Is it possible with plik to stream a file to multiple clients? If yes, I did not manage to do this...

    This could be useful when trying to distribute a file to all attendees of a training.

    opened by oupala 4
  • critical error when enabling encryption on s3 storage backend

    critical error when enabling encryption on s3 storage backend

    I have a critical error when uploading a simple image file :

    09/14/2022 10:21:40][CRITICAL][[][uMAlAUTgO2ZPUnhr][IMG_20220907_085611.jpg]] unable to save file : A header you provided implies functionality that is not implemented. -- -- 500

    The only thing that I have added to the configuration of plik is the S3 encryption settings:

    SSE-C: server-side-encryption with customer provided keys ( managed by Plik )

        SSE = "SSE-C"

    I don't think I have a specific header provided...

    What are the "customer provided key" that the documentation is talking about?

    opened by oupala 2
  • pass proxy host and port for S3 storage configuration

    pass proxy host and port for S3 storage configuration

    Is there a way to pass proxy host and port for S3 storage configuration?

    Sometime, the S3 platform is only reachable by passing by a proxy. You then have to specify the proxy host and the proxy port in order to get a connectivity with the S3 platform.

    unable to start Plik server : unable to initialize data backend : unable to check if <bucket-name> exists : Get "http://<bucket-host>/<bucket-name>/?location=": dial tcp i/o timeout

    opened by oupala 0
  • Docker: offer to configure S3 storage by environment variables

    Docker: offer to configure S3 storage by environment variables

    It looks like it is not currentyl possible to configure S3 storage by environment variables. The only way to configure an S3 storage is by configuration the plikd.cfg config file.

    When you are using a k8s that has an S3 operator, the S3 bucket is dynamically set on startup and credentials are made accessible by environment variables (mainly configMaps).

    It would be great if plik can retrieve its S3 credentials from environment variables (aka configMaps) so that is can be dynamically linked to the S3 bucket. This would ignore any settings in plikd.cfg if any setting is also set as an environment variable.

    I think this requires a change in the plikd binary so that variable can be read from env variables in addition to configuration file. Am I right?

    opened by oupala 10
Provide an upload endpoint that stores files on pinata and returns a json response with the uploaded file pinata url

Purpose Build a template repository to get to coding as quickly as possible, by starting from a common template which follows the guidelines here Feat

Dathan Vance Pattishall 0 Dec 30, 2021
Upgit - Upgit helps you simply upload any file to your Github repository and then get a raw URL for it

Upgit - Upgit helps you simply upload any file to your Github repository and then get a raw URL for it

null 299 Sep 22, 2022
A virtual file system for small to medium sized datasets (MB or GB, not TB or PB). Like Docker, but for data.

AetherFS assists in the production, distribution, and replication of embedded databases and in-memory datasets. You can think of it like Docker, but f

mya 8 Feb 9, 2022
Download an upload large files to Google Drive (API v3)

gdriver gdriver is a command-line tool, written in Go, used for uploading and downloading large personal files from Google Drive (API v3). The tool pr

Marcin Tojek 66 Jul 20, 2022
upload to gdrive include shared drive

gdrive_uploader upload to gdrive include shared drive How to get go get About credential You must set your client

ryu 3 Jun 8, 2022
A simply upload fileserver for fun

Filebus A simply upload fileserver for fun Build Binary: go build -o filebus . Docker docker build . -t n0vad3v/filebus:lastest Usage Filebus will b

Nova Kwok 0 Dec 14, 2021
🌳 Go Bonzai™ File Completer, normal completion looking at files and directories with trailing slashes on directories (like bash)

?? Go Bonzai™ File Completer, normal completion looking at files and directories with trailing slashes on directories (like bash)

Rob Muhlestein 2 Apr 12, 2022
Bigfile -- a file transfer system that supports http, rpc and ftp protocol

Bigfile ———— a file transfer system that supports http, rpc and ftp protocol 简体中文 ∙ English Bigfile is a file transfer system, supports http, ftp and

null 230 Sep 26, 2022
File system event notification library on steroids.

notify Filesystem event notification library on steroids. (under active development) Documentation Installation

Rafal Jeczalik 760 Sep 26, 2022
Pluggable, extensible virtual file system for Go

vfs Package vfs provides a pluggable, extensible, and opinionated set of file system functionality for Go across a number of file system types such as

C2FO 196 Sep 19, 2022
Cross-platform file system notifications for Go.

File system notifications for Go fsnotify utilizes rather than syscall from the standard library. Ensure you have the latest version

fsnotify 7.4k Sep 22, 2022
Dragonfly is an intelligent P2P based image and file distribution system.

Dragonfly Note: The master branch may be in an unstable or even broken state during development. Please use releases instead of the master branch in o

dragonflyoss 5.9k Sep 25, 2022
File system for GitHub

HUBFS · File System for GitHub HUBFS is a read-only file system for GitHub and Git. Git repositories and their contents are represented as regular dir

Bill Zissimopoulos 1.5k Sep 23, 2022
GeeseFS is a high-performance, POSIX-ish S3 (Yandex, Amazon) file system written in Go

GeeseFS is a high-performance, POSIX-ish S3 (Yandex, Amazon) file system written in Go Overview GeeseFS allows you to mount an S3 bucket as a file sys

Yandex.Cloud 287 Sep 7, 2022
Encrypted File System in Go

Getting Started: Setup the environment: Install GoLang: $ sudo apt update $ sudo apt upgrade $ sudo apt install libssl-dev gcc pkg-config $ sudo apt

Lucky Verma 0 Apr 30, 2022
A rudimentary go program that allows you to mount a mongo database as a FUSE file system

This is a rudimentary go program that allows you to mount a mongo database as a

Jay Goel 1 Dec 29, 2021
Gokrazy mkfs: a program to create an ext4 file system on the gokrazy perm partition

gokrazy mkfs This program is intended to be run on gokrazy only, where it will c

null 4 Jun 13, 2022
Package cae implements PHP-like Compression and Archive Extensions.

Compression and Archive Extensions 中文文档 Package cae implements PHP-like Compression and Archive Extensions. But this package has some modifications de

ᴜɴᴋɴᴡᴏɴ 36 Jun 16, 2022
The best HTTP Static File Server, write with golang+vue

gohttpserver Goal: Make the best HTTP File Server. Features: Human-friendly UI, file uploading support, direct QR-code generation for Apple & Android

Sound Sun 1.8k Sep 21, 2022