Deployment guide

Plik

Overview

Plik is a scalable, open-source, self-hosted service for temporary file uploads and sharing. Users upload one or more files through a clean web interface or an HTTP API, choose how long the files should live, and receive short shareable links that expire automatically.

One-shot links that self-destruct after a single download, password-protected uploads, streaming uploads that are never written to disk, and markdown comments make Plik a flexible replacement for emailing large attachments or standing up ad hoc file drops.

The SecureAnyCloud image installs the official prebuilt Plik server at /opt/plik/plikd. It runs as the plik service bound to loopback 127.0.0.1:8080, behind nginx, which terminates TLS on port 443. The metadata database and the uploaded files live on a dedicated data disk, so the appliance is production-ready within minutes of launch, with no package installation and no proxy configuration.

Secure by default, no anonymous uploads. Plik ships wide open by default and accepts anonymous uploads from anyone. This image does not. Authentication is forced, so every upload requires a valid account or API token, and open self-registration is disabled.

A plik-firstboot.service oneshot creates a unique administrator account and API token on each VM's first boot. It writes them to a root-only file, regenerates a per-VM TLS certificate, and then disables itself. The plik service requires the first-boot unit, so it can never serve before the per-VM credentials exist. No two VMs share credentials, and none are baked into the image.

Dedicated data disk. The SQLite metadata database (plik.db) and the file store (files/) live on a dedicated data disk mounted at /var/lib/plik. The disk is captured into the image, so every VM is provisioned with it. The server binary and web frontend stay on the OS disk.

What you get:

  • Plik 1.4.2, the official prebuilt server binary and bundled web frontend
  • The full Plik web UI, served over TLS: upload, set an expiry and get shareable links
  • plik.service bound to loopback 127.0.0.1:8080
  • nginx terminating TLS on 443, with 80 redirecting to HTTPS and an unauthenticated /healthz probe
  • plik-firstboot.service, which creates the first-boot admin account, API token, per-VM TLS certificate and info note
  • Forced authentication, with anonymous uploads disabled and self-registration turned off
  • A dedicated data disk mounted at /var/lib/plik for the metadata database and file store
  • Ubuntu 24.04 LTS base, patched at build time
  • 24/7 SecureAnyCloud support with a 24-hour response SLA

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet.

  • VM size: Standard_B2s (2 vCPU, 4 GB RAM) suits evaluation and light sharing. Use Standard_D2s_v5 or larger for busier workloads.
  • Data disk: the dedicated data disk holds your uploads, so resize it to suit how much you expect to store at once. The default maximum time to live is 30 days.
1

Deploy from the Azure Portal

Search the Marketplace for Plik on Ubuntu 24.04 and choose your VM size. Attach an NSG that allows TCP 22 (SSH) from your management network. Also allow TCP 443 (the web UI and API) from the networks and users that need to share files. Port 80 only issues an HTTPS redirect.

2

Deploy from the Azure CLI

RG="plik-prod"; LOCATION="eastus"; VM_NAME="plik-01" IMAGE_URN="sac1647283583153:plik-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name plik-vnet --address-prefix 10.90.0.0/16 --subnet-name plik-subnet --subnet-prefix 10.90.1.0/24 az network nsg create -g "$RG" --name plik-nsg az network nsg rule create -g "$RG" --nsg-name plik-nsg --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name plik-nsg --name allow-https --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:plik-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username azureuser --ssh-key-values "$SSH_KEY" \
  --vnet-name plik-vnet --subnet plik-subnet --nsg plik-nsg --public-ip-sku Standard
3

Connect via SSH

Connect to the VM over SSH with your admin user and key:

ssh azureuser@<vm-ip>
4

Verify the services are running

Plik listens on loopback 127.0.0.1:8080, and nginx fronts it with TLS on port 443. The /healthz endpoint is public for load balancer probes. The web UI and API require your per-VM credentials.

sudo systemctl is-active plik nginx plik-firstboot ss -tln | grep -E '127.0.0.1:8080|:443 ' curl -ks -o /dev/null -w 'healthz HTTP %{http_code}\n' https://127.0.0.1/healthz cat /opt/plik/VERSION

You should see the services active, plikd listening on loopback with nginx on 443, healthz HTTP 200, and the installed Plik version.

The web UI is served over TLS at https://<your-vm-ip>/. The certificate is self-signed per VM, so your browser warns on first visit. Accept the exception, or trust /etc/nginx/tls/plik.crt, to reach the page. Because authentication is forced, you see a sign-in screen rather than an open upload form.

5

Read your per-VM credentials and confirm auth is enforced

The administrator account and API token were generated on this VM's first boot and stored in a root-only file. Read them and keep them secret. Then confirm that an unauthenticated upload is rejected and that the per-VM token is accepted.

sudo cat /root/plik-info.txt echo "anonymous -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1/upload -d '{}')" echo "wrong token -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST -H 'X-PlikToken: wrong' https://127.0.0.1/upload -d '{}')"
PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-)
echo "per-VM tok -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{}')"

The info note holds PLIK_ADMIN_LOGIN, PLIK_ADMIN_PASSWORD and PLIK_API_TOKEN. It is owned by root:root with mode 0600. An anonymous upload returns 400 anonymous uploads are disabled, a wrong token returns 403 invalid token, and only your per-VM token returns 200.

6

Upload and share a file from the API

Load your token into a shell variable, create an upload and add a file. Plik returns a shareable link and gives you the file back on download. Authenticate every request with the X-PlikToken header.

PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-) printf 'Q3 revenue report - sac demo\n' > /tmp/report.txt
UPID=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{}' | jq -r '.id')
FILE=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -F "file=@/tmp/report.txt" https://127.0.0.1/file/$UPID)
FID=$(echo "$FILE" | jq -r '.id');
FNAME=$(echo "$FILE" | jq -r '.fileName')
echo "share link: https://<your-vm-ip>/#/?id=$UPID" curl -ks -H "X-PlikToken: $PLIK_TOKEN" https://127.0.0.1/file/$UPID/$FID/$FNAME

The upload is created, and the file uploads over TLS with status uploaded. You get a share link that expires with the upload, and downloading it returns the original content byte for byte.

7

Upload and share from the web UI

Sign in at https://<your-vm-ip>/ with the PLIK_ADMIN_LOGIN and PLIK_ADMIN_PASSWORD from your info note. Drag a file onto the upload area, or click to select one. Choose an expiry and any options, such as one-shot or password protection, then select Upload.

Plik returns a shareable link and an admin link for the upload, along with a QR code, a zip archive of all files, and a preview of each file. Share the link with anyone who needs the file. It stops working when the upload expires.

8

One-shot and expiring links

Set "oneShot": true when you create an upload, and the file self-destructs after a single download. This suits sending a secret or a one-time file. Combine it with a short time to live for links that expire quickly.

PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-) printf 'one time secret - sac demo\n' > /tmp/secret.txt
UPID=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{"oneShot":true,"ttl":3600}' | jq -r '.id')
FILE=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -F "file=@/tmp/secret.txt" https://127.0.0.1/file/$UPID)
echo "one shot upload $UPID created, expires in 1 hour, file self destructs after the first download"
echo "$FILE" | jq -r '"file: \(.fileName) status: \(.status)"'

The default and maximum time to live are 30 days. The appliance also supports password-protected and removable uploads through the same API and the web UI.

9

Manage the server from the admin panel

Your account is an administrator, so the Admin menu opens a dashboard. It shows the server configuration and live statistics, and it lets you manage users and uploads. The statistics show anonymous uploads at zero, because authentication is forced.

10

Persistence and the data disk

The metadata database and the uploaded files live on the dedicated data disk mounted at /var/lib/plik, so uploads survive reboots and the disk is captured into the image. Confirm the mount, and confirm that authentication is forced:

findmnt -no SOURCE,TARGET,FSTYPE /var/lib/plik df -h /var/lib/plik | tail -1 sudo ls /var/lib/plik curl -ks https://127.0.0.1/config | jq '{feature_authentication, maxFileSize, defaultTTL}'

The data disk is ext4, mounted at /var/lib/plik, and holds plik.db (the SQLite metadata database) and the files store. The /config endpoint reports feature_authentication: forced.

11

Enable a real TLS certificate

The appliance ships with a self-signed certificate generated per VM. For production, point a DNS record at the VM and replace it with a CA-signed certificate. Use Certbot to obtain one, then copy it into the nginx TLS paths:

sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --standalone -d your-domain.example.com
sudo cp /etc/letsencrypt/live/your-domain.example.com/fullchain.pem /etc/nginx/tls/plik.crt
sudo cp /etc/letsencrypt/live/your-domain.example.com/privkey.pem /etc/nginx/tls/plik.key
sudo systemctl reload nginx

Clients can then verify the certificate normally instead of using -k.

First boot, credentials and updates

The first-boot service creates the per-VM administrator account and API token, regenerates the per-VM TLS certificate, and resolves the instance URL. It writes the root-only info note at /root/plik-info.txt, then disables itself so later reboots are unaffected.

To rotate the API token, run sudo /opt/plik/plikd --config /etc/plik/plikd.cfg token create --login admin and store the new token. The OS is patched at build time and ships with unattended security upgrades enabled.

Support

Every SecureAnyCloud deployment includes 24/7 support with a 24-hour response SLA. Contact sales@secureanycloud.com for help with deployment, configuration or scaling.

This is a repackaged open-source software product, with additional charges for SecureAnyCloud support services. Plik is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Their use does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Plik on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure